Jump to content

    
haker_fox

ISP загрузчик LPC1768

Recommended Posts

Добрый день, коллеги! Пишу "клиента" для заводского загрузчика LPC1768. Одна плата в приборе должна обновлять ПО другой платы, на которой смонтирован LPC1768. Было принято решение не изобретать колесо, а воспользоваться встроенным загрузчиком. И вот нюанс. Вход в загрузчик происходит без проблем, синхронизация, выставление частоты кварца - тоже. Далее, выполняю такую последовательность команд:

1. Unlock.

2. Prepare SectorForWrite from 0 to 0.

3. Erase Sector from 0 to 0.

4. Unlock.

5. Prepare Sector For Write from 0 to 0.

6.Copy Ram To Flash, ram address 0x10001000, flash address 0x00000000, count 256.

И, судя по ответам от МК, все эти команды проходят. Ответ "0 CR LF" на каждую из них. Сейчас данные в ОЗУ не загружаю, т.к. неважно же, что записывать.

И вот даю седьмую команду:

7. Compare, addr1 0x00000000, addr1 0x10001000, count 4 (да, даже намеренно четыре). И ответ приходит "10 CR LF". Т.е. данные просто не равны. Как так? Судя по некоторым поискам на форумах, в загрузчиках различных микроконтроллеров встречаются редкие баги (у кого-то, по-моему LPC800, не было ответа "OK" после отправки данных в ОЗУ). Но про сравнение ничего не нашёл. Может быть всё-таки есть бак? Или я что-то кардинально не так делаю?

 

Коллеги, спасибо за ответы заранее!

Share this post


Link to post
Share on other sites
12 минут назад, haker_fox сказал:

Или я что-то кардинально не так делаю?

Может не читали это?:

ISP commands use on-chip local RAM. from 0x1000 0118 to 0x1000 01FF. The user 
could use this area, but the contents may be lost upon reset. Flash programming 
commands use the top 32 bytes of on-chip local RAM. The stack is located at RAM top - 
32. The maximum stack usage is 256 bytes and it grows downwards.

И где-то нарушаете эти требования?

 

12 минут назад, haker_fox сказал:

Одна плата в приборе должна обновлять ПО другой платы, на которой смонтирован LPC1768. Было принято решение не изобретать колесо, а воспользоваться встроенным загрузчиком.

А защита прошивки этой "другой платы" Вас не беспокоит?

Share this post


Link to post
Share on other sites

Для упрощения диагностики предлагаю проверять содержимое памяти после каждого шага отладчиком. Ну и лог. анализатор на линиях rx-tx тоже может помочь.

 

На первый взгляд, должно работать. Но я занимался чем-то похожим (свой загрузчик, совместимый по командам с FlashMagic) очень давно...

55 minutes ago, haker_fox said:

ответ приходит "10 CR LF". Т.е. данные просто не равны

Что странно. Документ обещает "COMPARE_ERROR | (Followed by the offset of first mismatch)", т.е. нолик куда-то потерялся...

 

Ну и про то, что адреса должны быть в десятичной системе, вы же в курсе?

Share this post


Link to post
Share on other sites
2 hours ago, jcxz said:

Может не читали это?:

Читал. Как раз использую 4 кб с адреса 0x10001000. Это не нарушает требования.

2 hours ago, jcxz said:

А защита прошивки этой "другой платы" Вас не беспокоит?

Нет, начальство выдало задание только обновлять)

1 hour ago, esaulenka said:

Для упрощения диагностики предлагаю проверять содержимое памяти после каждого шага отладчиком. Ну и лог. анализатор на линиях rx-tx тоже может помочь.

Верно! Завтра утром подключу второй отладчик к прошиваемому МК и подвешу анализатор. Сегодня был смущён тем, что выводил в консоль тектовые буферы сообщения. И ответные сообщения в норме. Что странно. Была бы ошибка приёма, МК бы ругнулся.

1 hour ago, esaulenka said:

Что странно. Документ обещает "COMPARE_ERROR | (Followed by the offset of first mismatch)", т.е. нолик куда-то потерялся...

Виноват, ответ приъходит такой "10 CR LF 0 CR LF", всего семь байт.

1 hour ago, esaulenka said:

Ну и про то, что адреса должны быть в десятичной системе, вы же в курсе?

Да, конечно! Вот одна из функций клиента загрузчика, там всё через sprintf сделано

TRetVal NxpLpcBootClient::Cmd::eraseSector( const size_t startSector, const size_t endSector ) {
#if(DEBUG_ISP_CLIENT==1)
    kprintf("Cmd::%s, startSector %d, endSector %d\r\n", __FUNCTION__, startSector, endSector);
#endif
    RET_VAL(Cmd::prepareSectorsForWrite(startSector, endSector));
    sprintf(m_msgBuff, "E %d %d\r\n", startSector, endSector);
    TRetVal result = m_serial->write(m_msgBuff, strlen(m_msgBuff));
    RET_VAL(result);
    RET_VAL(checkResponse());
    return rvOK;
}

 

З.Ы. Блин, думал, что это наипростейший вариант не парится с загрузчиком и обновлением, т.к. я не люблю загрузчики. Сам же и намекнул начальству на такой путь решения. И вот... перекусил)))

Share this post


Link to post
Share on other sites
5 минут назад, haker_fox сказал:

Виноват, ответ приъходит такой "10 CR LF 0 CR LF", всего семь байт.

А самостоятельно проверить/сравнить - равны или нет - слабо?

Команда чтения ведь имеется....

Share this post


Link to post
Share on other sites
3 hours ago, haker_fox said:

6.Copy Ram To Flash, ram address 0x10001000, flash address 0x00000000, count 256.

Кстати, у этой команды синтаксис memcpy. Т.е. cmd dst, src, size, а не cmd ram, flash, size.
Возможно, она даже корректно скопирует флеш в рам :-)

Share this post


Link to post
Share on other sites
38 minutes ago, esaulenka said:

Возможно, она даже корректно скопирует флеш в рам :-)

Проверил код, всё в порядке)

        sprintf(m_msgBuff, "C %d %d %d\r\n", flashAddress, ramAddress, count);
        kprintf("copy m_msgBuff [%s]\r\n", m_msgBuff);
        TRetVal result = m_serial->write(m_msgBuff, strlen(m_msgBuff));
        RET_VAL(result);
        RET_VAL(checkResponse());

 

Share this post


Link to post
Share on other sites

Проблема, похоже в этом

image.thumb.png.579b0f6214b64581fc1fa8e2bf15e168.png

Я взял программу SEGGER J-Mem и вычитал всю память LPC1768.

image.thumb.png.367d87c9aeea69d67425c17b89cc07b3.png

Так вот, область флеши с 0x00000000 по 0x000003FF после стирания содержит нули и какие-то адреса, раскиданные по различным векторам. Область с 0x00000400 содержит 0xFF как и положено. Начал своим клиентом писать данные с этого адреса (просто то, что лежит в ОЗУ перешиваемого микроконтроллера), сравнение стало проходить без ошибок. Т.е. делаю вывод: пишется реальная флешка, а читается - отражённая. Но всё это ещё надо проверить, т.е. залить теперь уже реальную программу. Но предварительные выводы именно такие. Хотя странно. Уж их compare-то могла как-то читать реальную область.

 

Share this post


Link to post
Share on other sites
3 hours ago, jcxz said:

Может у вас там просто стоит защита от чтения или стирания?

Вы имеете в виду биты CPR? Нет, нарочно никакую защиту не ставили.

Share this post


Link to post
Share on other sites

Гм... после всяких экспериментов и чтения различных бумаг, удалось залить прошивку в LPC1768. Программа запускается. Далее, J-Mem'ом вытащил содержимое памяти в бинарь, и сравнил с целевым "бином". Всё совпадает. При этом compare на первых адресах так и не проходит..

 

З.Ы. Имел опыт написания подобного клиента, но для заводских загрузчиков STM32xx1. Там всё значительно проще. Такое ощущение, что на LPC'шках что всё замудрено нарочно. И многое - ради обмена в ASCII-формате. Вопрос, а кому оно надо? Может быть это что-то историческое?

Share this post


Link to post
Share on other sites
1 час назад, haker_fox сказал:

Всё совпадает. При этом compare на первых адресах так и не проходит..

Можно взять FlashMagic и с помощью него прошить LPC. Перехватывая и анализируя обмен по UART. Чтобы подглядеть как делает FlashMagic и какие ответы получает от LPC. Ведь у него получается нормально прошивать.

1 час назад, haker_fox сказал:

Вопрос, а кому оно надо? Может быть это что-то историческое?

Обычно шьют изнутри, через IAP, из своего bootloader-а. А у вас - редкий случай.

22 часа назад, haker_fox сказал:

Вы имеете в виду биты CPR? Нет, нарочно никакую защиту не ставили.

Насколько помню - там не "биты", а 32-битный ключ. И не CPR, а CRP (Code Read Protection). Про "биты CPR" я ничего не слышал.

Share this post


Link to post
Share on other sites
17 minutes ago, jcxz said:

Ведь у него получается нормально прошивать.

Прошивать и у меня получается 100%) Другое дело, что FlashMagic может не вызывать compare, а вычитывать всю флешку, и сравнивать с файлом. Но возможно, что протокол и подгляжу.

18 minutes ago, jcxz said:

Обычно шьют изнутри, через IAP, из своего bootloader-а. А у вас - редкий случай.

Да так и делаем в основном. Свой загрузчик, своё шифрование, контрольные суммы. Но честно, я просто не хотел возиться. Меня подбешивают загрузчики... да, возможно, что звучит непрофессионально, но, тем не менее, этол так)

19 minutes ago, jcxz said:

не CPR, а CRP (Code Read Protection). Про "биты CPR" я ничего не слышал.

Ок, я это и имел в виду)

Share this post


Link to post
Share on other sites
11 minutes ago, haker_fox said:

Другое дело, что FlashMagic может не вызывать compare, а вычитывать всю флешку, и сравнивать с файлом.

FlashMagic действительно вычитывает прошивку при верификации.

Это видно по статусу выполнения.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.