|
|
  |
Программирование MC через Ethernet |
|
|
|
Apr 20 2007, 12:22
|

Их либе дих ...
     
Группа: СуперМодераторы
Сообщений: 2 010
Регистрация: 6-09-04
Из: Russia, Izhevsk
Пользователь №: 609

|
Терзаю LPC2378 под управлением NicheLite ... Есть желание прикрутить механизм смены прошивки "на лету" через эзернет, а конкрктнее используя стек NicheLite, через TCP соединение. Думаю, вариантов тут не много ... одна версия NicheLite (минимальная) выступает в роли загрузчика (или базовой аварийной версии), другая размещается выше (которая и будет перезаливаться). Примерный механизм сены прошивки: 1) говорм устройству что нужно обновить фирмварь, та во флешке сохраняет флажек PROGRAM, перезапускает контроллер 2) "базовая" версия при запуске смотрит состояние PROGRAM флага, если не активен, то тупо предает управление "рабочей" версии, если PROGRAM активен то ждет обновления прошивки потом сбрасывает PROGRAM и рестарт
Рассматривал еще вариант с двумя полноценными прошивками, если нужно то одна заменяет другую, но при этом прийдется еще загрузчик клеить чтоб анализировал целостность и передавал управление нужной прошивке.
...
--------------------
Усы, борода и кеды - вот мои документы :)
|
|
|
|
|
Apr 20 2007, 12:48
|

Их либе дих ...
     
Группа: СуперМодераторы
Сообщений: 2 010
Регистрация: 6-09-04
Из: Russia, Izhevsk
Пользователь №: 609

|
1)сама себя рабочая прошивка перезалить не сможет, а загрузчик должен знать требуется обновление или нет, тайм-ауты тоже не желательны т.к. затягивают старт системы. 2) TFTP или нет, это пока не принципиально (к тому же NicheLite имеет клиента, ломает рабираться как к этому свои нужны прикручивать).
Вопрос, как в Кейле разместить код по нужному адресу? Взял адрес 0x20000, указал в свойствах линковщика --entry 0x20000, а мне в ответ: Entry point (0x00020000) lies outside the image.
--------------------
Усы, борода и кеды - вот мои документы :)
|
|
|
|
|
Apr 20 2007, 13:02
|

Частый гость
 
Группа: Свой
Сообщений: 173
Регистрация: 30-11-05
Из: San Francisco
Пользователь №: 11 593

|
Не совсем в темы, но тоже про бутлоадер. А каким методом Вы пользуетесь для рестарта процессора после перепрошивки? Я использую аналог вызова IAP из примера от KEIL. Код typedef void (*P_RESET)(void); P_RESET prog_reset;
В процедуре инициализации: prog_reset = (P_RESET) 0x00000000;
Ну и где необходим рестарт: prog_reset(); В общем-то работает. Хотел узнать может есть какой другой, может более правильный вариант?
|
|
|
|
|
Apr 20 2007, 13:22
|

Их либе дих ...
     
Группа: СуперМодераторы
Сообщений: 2 010
Регистрация: 6-09-04
Из: Russia, Izhevsk
Пользователь №: 609

|
2 zuy До рестартарт-ов мне пока далеко  , только я не понял, где в вашем примере IAP (обычная загрузка указателя)? К тому же через IAP вроде можно только принудительно бутлоадер вызвать. Далее по моему вопросу о размещении, с помощью вот такого файла линковщика получается разместить выше: Цитата ROM_LOAD 0x00020000 0x00080000 { ROM_EXEC 0x00020000 { Startup.o (vectors,+First) * (+RO) } IRAM 0x40000000 { * (+RW,+ZI) } HEAP +0 UNINIT { Startup.o (Heap) } STACKS 0x40008000-0x1800 UNINIT { Startup.o (Stacks) } } НО, при этом и таблица векторов тоже в верх уползает, как поправить?
--------------------
Усы, борода и кеды - вот мои документы :)
|
|
|
|
|
Apr 20 2007, 13:34
|

Частый гость
 
Группа: Свой
Сообщений: 173
Регистрация: 30-11-05
Из: San Francisco
Пользователь №: 11 593

|
Цитата(3.14 @ Apr 20 2007, 13:22)  2 zuy До рестартарт-ов мне пока далеко  , только я не понял, где в вашем примере IAP (обычная загрузка указателя)? К тому же через IAP вроде можно только принудительно бутлоадер вызвать. Я имел ввиду, что посмотрел, как в примере вызывают IAP и сделал так же, только адрес заменил на 0, и параметры убрал. В оригинале обьявление выглядело так: Код typedef void (*IAP)(struct iap_in *in, unsigned int *result); #define iap_entry ((IAP) 0x7FFFFFF1) // IAP Entry Point
И вызов: iap_entry (&iap, result);
|
|
|
|
|
Apr 24 2007, 14:55
|

Их либе дих ...
     
Группа: СуперМодераторы
Сообщений: 2 010
Регистрация: 6-09-04
Из: Russia, Izhevsk
Пользователь №: 609

|
Чего то я слегка заблудился в IAP. Перед началом программирования флешки, провожу препарирование нужных секторов потом стираю потом проверяю, все ОК. Далее начинаю засылать в контроллер странички по 256 байт и заливаю их (cм. листинг). Процесс заканчивается без ошибок, но вот реальное содержимое флешки после программирования не совпадает. Несколько первых страниц (~10) пишутся без проблем затем начинаются "пробелы" чистой флеши. Еще очень не понятно, если в препаре LAST_SECTOR указать текущий, то когда странички доберутся до следующего сектора все встанет. Код int ProgramFirmware(unsigned char first_sect, int page, char * buf) { int i,j; char start_sect,last_sect; unsigned long Pointer; start_sect = floor(page/128) + first_sect; last_sect = start_sect; switch(first_sect) { case 10: Pointer = 0x18000; break; case 11: Pointer = 0x20000; break; case 12: Pointer = 0x28000; break; case 13: Pointer = 0x30000; break; case 14: Pointer = 0x38000; break; case 15: Pointer = 0x40000; break; case 16: Pointer = 0x48000; break; case 17: Pointer = 0x50000; break; case 18: Pointer = 0x58000; break; case 19: Pointer = 0x60000; break; default : return FALSE; } Pointer = Pointer + ((unsigned long)page * 256);
Iap.status=CMD_SUCCESS+1; while(Iap.status!=CMD_SUCCESS) { IDISABLE; Iap.cmd=IAP_CMD_PREPARE; Iap.par[0]=start_sect; Iap.par[1]=last_sect+6; //!!! странность iap_exec(&Iap); IENABLE; } IDISABLE; Iap.cmd=IAP_CMD_WRITE; Iap.par[0]=Pointer; Iap.par[1]=(unsigned long) buf; Iap.par[2]=256; Iap.par[3]=Fcclk/1000; iap_exec(&Iap); IENABLE; while(Iap.status!=CMD_SUCCESS); return TRUE; }
--------------------
Усы, борода и кеды - вот мои документы :)
|
|
|
|
|
Apr 24 2007, 15:15
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(3.14 @ Apr 20 2007, 11:22)  1) говорм устройству что нужно обновить фирмварь, та во флешке сохраняет флажек PROGRAM, перезапускает контроллер 2) "базовая" версия при запуске смотрит состояние PROGRAM флага, если не активен, то тупо предает управление "рабочей" версии, если PROGRAM активен то ждет обновления прошивки потом сбрасывает PROGRAM и рестарт Какую-либо неиспользуемую ногу (например приснопамятный SSEL с внешней подтяжкой) приложение настраивает на вывод и передает управление загрузчику. Загрузчик проверяет ногу - если настроена на ввод - значит это старт по включению питания, если на вывод - значит это вызов из приложения. Запись флажка во флеш при этом не требуется. Цитата(zuy @ Apr 20 2007, 12:02)  В общем-то работает. Хотел узнать может есть какой другой, может более правильный вариант? Запустить вочдог и дать ему сбросить процессор. Гарантированноо сбросится вся периферия и вы не будете иметь сюрпризов типа какую-то периферию уже настроил загрузчик а приложение об этом не знает и полагается на настройки по умолчанию. Код start_sect = floor(page/128) + first_sect; Зачем тут плавающая точка? start_sect = page / 128 + first_sect; Код IENABLE; while(Iap.status!=CMD_SUCCESS); return TRUE; Если предыдущий вызов IAP не удался, этот цикл будет крутиться вечно.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 24 2007, 17:43
|

Их либе дих ...
     
Группа: СуперМодераторы
Сообщений: 2 010
Регистрация: 6-09-04
Из: Russia, Izhevsk
Пользователь №: 609

|
Вобщем, это не принципиально как общаться загрузчику и фирмвари между собой. >>Зачем тут плавающая точка? start_sect = page / 128 + first_sect; да это я для пущей уверенности, что после деления возмется наименьшее (а не округлится), целые то из флоата без проблем должны получится. >>Если предыдущий вызов IAP не удался, этот цикл будет крутиться вечно. Это я специально, чтоб видеть, что в этом месте встало.
Перед уходом с работы нарыл что мои макросы IENABLE/IDISABLE вовсе не разрешают/запрещают прерывания а разрешают/запрещают вложенные прерывания. Заменил их на обнуление/востановление маски векторов VIC-а, чего то вообще поломалось.
--------------------
Усы, борода и кеды - вот мои документы :)
|
|
|
|
|
Apr 25 2007, 00:06
|

Местный
  
Группа: Свой
Сообщений: 481
Регистрация: 1-08-05
Пользователь №: 7 267

|
Пардон, не в тему ARM, но в тему обновления фирмвари по ethernet. В меге162 сделал так: При сбросе бутлодырь считает контрольную сумму основной области, если все ОК, смотрит еще флажок в eeprom - требование обновления. После чего передает управление основной программе. Соответственно если контрольная сумма не совпадает или взведен флаг, отрабатывается процедура обновления. После обновления опять проверяется контрольная сумма, и только потом передается управление. В основной программе есть отработка команды обновления - приняли команду, взвели флажок, сбросили по WD, обновляемся... Все прекрасно работает уже года 3. Даже через интернет... Протокол UDP, ибо в 2 кб загрузочной области меги162 не шибко развернешься.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|