|
Никак не пойму как работае IAP, Никак не пойму как работае IAP |
|
|
|
Jun 14 2011, 10:13
|
Частый гость
 
Группа: Участник
Сообщений: 103
Регистрация: 29-01-08
Пользователь №: 34 558

|
Цитата Вызываются функции загрузчика через указатели на них. У NXP все расписано в аппнотах. Вот вот здесь собственно и начинаются непонятки: 1. После перехода к загрузчику(и его выполнения?), насколько я понимаю, должен следовать мой код? 2. Насколько я понял максимальный разъмер кода - 8кб ? Т.к. он будет расположен в области загрузчика? 3. Слышал, что нужно переписывать таблицу векторов прерывай, так ли это? PS Апноут прочел. Но к сожалению не понимаю последовательности процесса.
|
|
|
|
|
Jun 14 2011, 10:26
|
Гуру
     
Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295

|
Цитата(Metallist64 @ Jun 14 2011, 13:13)  Вот вот здесь собственно и начинаются непонятки: 1. После перехода к загрузчику(и его выполнения?), насколько я понимаю, должен следовать мой код? 2. Насколько я понял максимальный разъмер кода - 8кб ? Т.к. он будет расположен в области загрузчика? 3. Слышал, что нужно переписывать таблицу векторов прерывай, так ли это? 1. И до, и после. Вызовы функций загрузчика вставляются в требуемые места вашей программы. 2. См. описание функций загрузчика. В функцию записи передаются адреса источника и приемника, а никак не сами записываемые данные. 3. Не совсем. Вы просто можете запретить прерывания на время модификации Flash. Альтернатива - скопировать таблицу векторов в ОЗУ, указать на эту копию процессору и разместить обработчики прерываний и все требуемое для их работы в ОЗУ. тогда прерывания смогут обрабатываться даже во время записи во Flash ...
Сообщение отредактировал kovigor - Jun 14 2011, 10:27
|
|
|
|
|
Jun 14 2011, 11:29
|
Частый гость
 
Группа: Участник
Сообщений: 103
Регистрация: 29-01-08
Пользователь №: 34 558

|
Цитата(kovigor @ Jun 14 2011, 14:26)  1. И до, и после. Вызовы функций загрузчика вставляются в требуемые места вашей программы. 2. См. описание функций загрузчика. В функцию записи передаются адреса источника и приемника, а никак не сами записываемые данные. 3. Не совсем. Вы просто можете запретить прерывания на время модификации Flash. Альтернатива - скопировать таблицу векторов в ОЗУ, указать на эту копию процессору и разместить обработчики прерываний и все требуемое для их работы в ОЗУ. тогда прерывания смогут обрабатываться даже во время записи во Flash ... Т.е. насколько я понял, я должен записываться код со следующего свободного сектора и затем как-то переходить именно в эту область ?
|
|
|
|
|
Jun 16 2011, 10:32
|
Частый гость
 
Группа: Участник
Сообщений: 103
Регистрация: 29-01-08
Пользователь №: 34 558

|
Цитата Функции, модифицирующие Flash, следует расположить в ОЗУ, чтобы не было конфликтов и зависаний при одновременной модификации Flash и выборки из нее кодов команд или данных .. На сколько я понимаю физически флэш память одна. Она просто логически разделена(судя по карте памяти) на разелы BOOT и скажем так пользовательский код? Сам код, который будет обновлять флэш будет находиться в области зарузчика ? И писать пользовательский код туда нельзя. Судя по карте памяти в нем есть как ROM так FLASH области? Таким образом общий объем памяти складывается из = BOOT ROM + BOOT FLASH + USER CODE FLASH ? Опять таки, насколько я понял, что для LPC2367 объем BOOT области = 8кб. И писать тудо ничего ненадо? Там лежат именно те самые функции IAP, я должен только использовать их, вызывая и передавая аргументы?
|
|
|
|
|
Jun 19 2011, 12:21
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата(Metallist64 @ Jun 16 2011, 13:32)  На сколько я понимаю физически флэш память одна. Она просто логически разделена(судя по карте памяти) на разелы BOOT и скажем так пользовательский код?
Сам код, который будет обновлять флэш будет находиться в области зарузчика ? И писать пользовательский код туда нельзя. Судя по карте памяти в нем есть как ROM так FLASH области?
Таким образом общий объем памяти складывается из = BOOT ROM + BOOT FLASH + USER CODE FLASH ?
Опять таки, насколько я понял, что для LPC2367 объем BOOT области = 8кб. И писать тудо ничего ненадо? Там лежат именно те самые функции IAP, я должен только использовать их, вызывая и передавая аргументы? FLASH одна и имеет линейное адресное пространство от и до. Вы можете выделить под Ваш загрузчик скажем первые 8к (2 первых сектора по 4к, если их будет мало добавите сколько нужно - для lpc23хх нет разграничений flash на boot не boot области как у атмег). В этой области разместите код загрузчика который будет каким-либо образом принимать прошивку (по uart или как сделано у меня 122к зашифрованной прошивки хранятся во внешней flash-памяти). Код загрузчика анализирует наличие прошивки, закидывает в буффер скажем 4к блок прошивки приложения, из IAP вызывает процедуру подготовки соотв. сектора, процедуру стирания и потом процедуру записи. Там по сути всё настолько просто что работает с первого раза (скажем у меня за полдня получилось полностью освоить код работы с IAP и написать загрузчик для lpc2368). CODE //----------------------------------------- //стирание выбранного сектора unsigned int eraseSector(unsigned int SECTOR) { unsigned int status=0; //--------------------------------------- //подготовка сектора status = iapSelectSector(SECTOR, SECTOR); if(status != IAP_CMD_SUCCESS) { return 0; //сбой подготовки } //--------------------------------------- //--------------------------------------- //стирание сектора __disable_interrupt(); status = iapEraseSector(SECTOR, SECTOR); __enable_interrupt(); if(status != IAP_CMD_SUCCESS) { return 0; //сбой стирания } else { return 1; //стирание OK } //--------------------------------------- } //-----------------------------------------
//----------------------------------------- //запись вектора unsigned int writeSector(unsigned int* pData, unsigned int SECTOR, unsigned int addr, unsigned int size) { unsigned int status=0; //--------------------------------------- //подготовка сектора status = iapSelectSector(SECTOR, SECTOR); if(status != IAP_CMD_SUCCESS) { return 0; //сбой подготовки } //--------------------------------------- //--------------------------------------- //запись сектора __disable_interrupt(); status = iapRamToFlash( addr, (unsigned int) pData, size); __enable_interrupt(); if(status != IAP_CMD_SUCCESS) { return 0; //сбой записи } else { return 1; //запись OK } //--------------------------------------- } //-----------------------
Сообщение отредактировал mempfis_ - Jun 19 2011, 12:23
|
|
|
|
|
Jun 20 2011, 16:34
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата(Metallist64 @ Jun 20 2011, 09:29)  Большое спасибо за пример и пояснение. С функциями более или менее разобрался. Но есть еще пара вопросиков: А на уровне проекта это как осуществляется? Создаются 2 проекта с разными рабочими областями? или в одном проекте указывается где какой код должен лежать?
Заранее спасибо. У меня это 2 отдельных проекта. Связаны они между собой только начальным адресом приложения во flash. В бутлоадере в файле линкера flash ограничена 8к. Выделен сегмент под CRP. В коде бутлоадера гдето прописывается уровень защиты Код //------------------------------------------- //устанавливаем защиту #define CRP1 0x12345678ul #define CRP2 0x87654321ul #define CRP3 0x43218765ul //этот уровень защиты убъёт процессор!!!
#pragma location = "CRP_section" __root const unsigned long crp = 0x87654321ul; //------------------------------------------- вызов приложения из бутлоадера осуществляется так: Код void (*app) (); //указатель на приложение
#define APPL_START_ADDR 0x00002000 //стартовый адрес расположения приложения во flash app = (void(*)()) APPL_START_ADDR; app(); В icf-файле приложения необходимо указать линкеру что вектора прерываний находятся не по нулевому адресу. Ну и ограничить flash. Пишу в IAR. Прмер icf-файла для бутлоадера. CODE /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x00000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x00000200; define symbol __ICFEDIT_region_ROM_end__ = 0x00002000; define symbol __ICFEDIT_region_RAM_start__ = 0x40000040; define symbol __ICFEDIT_region_RAM_end__ = 0x40007FDF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x400; define symbol __ICFEDIT_size_svcstack__ = 0x100; define symbol __ICFEDIT_size_irqstack__ = 0x100; define symbol __ICFEDIT_size_fiqstack__ = 0x40; define symbol __ICFEDIT_size_undstack__ = 0x10; define symbol __ICFEDIT_size_abtstack__ = 0x10; define symbol __ICFEDIT_size_heap__ = 0x2000; /**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define symbol __region_USB_DMA_RAM_start__ = 0x7FD00000; define symbol __region_USB_DMA_RAM_end__ = 0x7FD01FFF; define region USB_DMA_RAM_region= mem:[from __region_USB_DMA_RAM_start__ to __region_USB_DMA_RAM_end__];
define symbol __region_EMAC_DMA_RAM_start__ = 0x7FE00000; define symbol __region_EMAC_DMA_RAM_end__ = 0x7FE03FFF; define region EMAC_DMA_RAM_region= mem:[from __region_EMAC_DMA_RAM_start__ to __region_EMAC_DMA_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block SVC_STACK with alignment = 8, size = __ICFEDIT_size_svcstack__ { }; define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { }; define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { }; define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { }; define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite }; do not initialize { section .noinit }; do not initialize { section USB_DMA_RAM }; do not initialize { section EMAC_DMA_RAM };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK, block UND_STACK, block ABT_STACK, block HEAP }; place in USB_DMA_RAM_region { section USB_DMA_RAM }; place in EMAC_DMA_RAM_region { section EMAC_DMA_RAM };
place at address mem: 0x000001FC { readonly section CRP_section }; Пример icf-файла приложения: CODE /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x00002000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x00002044; define symbol __ICFEDIT_region_ROM_end__ = 0x0001FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x40000040; define symbol __ICFEDIT_region_RAM_end__ = 0x40007FFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x400; define symbol __ICFEDIT_size_svcstack__ = 0x100; define symbol __ICFEDIT_size_irqstack__ = 0x100; define symbol __ICFEDIT_size_fiqstack__ = 0x40; define symbol __ICFEDIT_size_undstack__ = 0x10; define symbol __ICFEDIT_size_abtstack__ = 0x10; define symbol __ICFEDIT_size_heap__ = 0x2000; /**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define symbol __region_USB_DMA_RAM_start__ = 0x7FD00000; define symbol __region_USB_DMA_RAM_end__ = 0x7FD01FFF; define region USB_DMA_RAM_region= mem:[from __region_USB_DMA_RAM_start__ to __region_USB_DMA_RAM_end__];
define symbol __region_EMAC_DMA_RAM_start__ = 0x7FE00000; define symbol __region_EMAC_DMA_RAM_end__ = 0x7FE03FFF; define region EMAC_DMA_RAM_region= mem:[from __region_EMAC_DMA_RAM_start__ to __region_EMAC_DMA_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block SVC_STACK with alignment = 8, size = __ICFEDIT_size_svcstack__ { }; define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { }; define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { }; define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { }; define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite }; do not initialize { section .noinit }; do not initialize { section USB_DMA_RAM }; do not initialize { section EMAC_DMA_RAM };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK, block UND_STACK, block ABT_STACK, block HEAP }; place in USB_DMA_RAM_region { section USB_DMA_RAM }; place in EMAC_DMA_RAM_region { section EMAC_DMA_RAM };
|
|
|
|
|
Jul 12 2011, 08:43
|
■ ■ ■ ■
    
Группа: Свой
Сообщений: 1 100
Регистрация: 9-08-06
Пользователь №: 19 443

|
Цитата Или можно коду загрузчика работать из флеш? Нужно.
--------------------
Делай что должен и будь что будет.
|
|
|
|
|
Jul 12 2011, 10:40
|

Частый гость
 
Группа: Участник
Сообщений: 90
Регистрация: 28-07-09
Из: Чернигов
Пользователь №: 51 621

|
И еще пара вопросиков  1) допустим у меня приложение начинается с адреса 0х020000. достаточно ли просто для старта приложения перейти по указанному адресу? или нет? 2) в НЕХ файле приложения есть запись с типом 05 (линейный адрес старта) что с ней делать? можно ли ее проигнорировать или нет? в описании стандарта Intel-HEX указанно что эта запись указывает на адрес с которого начинается исполнение объектного файла - значит ее надо кудато запихнуть, а куда...? Подскажите кто знает!
Сообщение отредактировал Lexy_one - Jul 13 2011, 05:45
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|