pokk 0 3 апреля, 2019 Опубликовано 3 апреля, 2019 · Жалоба Сделал так: Положил CRC в начало прошивки а структуру сдвинул на 4 байта, а в загрузчике накладываю структуру (с присутствие поля CRC_Appl ) по началу адреса. extern uint32_t __checksum; typedef struct{ //uint32_t CRC_Appl; uint16_t ID; uint32_t endAddr; uint32_t size_page; }s_botloader_header; //-------------------------------------------------------------------------------------------------- const s_botloader_header botloader_header@0x8005004={ .ID=0xAACC, // идетификатор что бы муссор не пихали .endAddr=0x803F7FF, }; Но не нравится мне такой вариант все же, хочеться более надежно, что бы CRC в структуре была сразу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 3 апреля, 2019 Опубликовано 3 апреля, 2019 · Жалоба 2 часа назад, pokk сказал: Сделал так: Положил CRC в начало прошивки а структуру сдвинул на 4 байта, а в загрузчике накладываю структуру (с присутствие поля CRC_Appl ) по началу адреса. Делаю иначе: в начале прошивки сразу после таблицы векторов храню размер прошивки (автоматически проставляет редактор связей (линкер)). Сразу за прошивкой храню CRC. Таким образом, всегда считается CRC только реально занятой под прошивку области. Реализуется легко, не требуется ничего смещать. Использую ARM Cortex и GCC, просто как идея. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 3 апреля, 2019 Опубликовано 3 апреля, 2019 · Жалоба У меня CRC32 хранится внутри таблицы векторов прерываний, в неиспользуемом векторе по смещению 0x20: PUBLIC __codetail EXTERN __checksum_begin, __checksum_end SECTION .codetail:CONST:ROOT(2) __codetail DC32 __checksum_begin DC32 __checksum_end DC32 FIRMWARE_TARGET PUBLIC __codehead SECTION .codehead:CONST:ROOT(2) __codehead DC32 __codetail DC32 0 SECTION .intvec:CONST:ROOT(8) DATA ;Таблица векторов прерываний __vector_table DCD sfe(.bssStkMain) ;Top of Stack DCD AppStart ;Reset Handler DCD NmiISR ;NMI Handler DCD HardFaultISR ;Hard Fault Handler DCD MpuFaultISR ;MPU Fault Handler DCD BusFaultISR ;Bus Fault Handler DCD UsageFaultISR ;Usage Fault Handler __vector_table_0x1c DCD 0 ;не используется SECTION .intvecTail:CONST:ROOT(2) DATA ;Продолжение таблицы векторов прерываний __vector_table_tail DCD isrSVC ;SVCall Handler DCD DefaultISR ;Debug Monitor Handler DCD 0 ;Reserved DCD isrPendSV ;PendSV Handler DCD isrSysTick ;SysTick Handler В .icf-файле: define block IMAGE_HEAD with fixed order {section .intvec, section .checksum, section .codehead, section .intvecTail, section .codeSignature}; place in FLASH_regionA {ro, first block IMAGE_HEAD, last section .codetail, section .httpContent}; sizeof(.intvec) == 32; sizeof(.checksum) == 4; sizeof(.codehead) == 8 Удобно что CRC всегда имеет фиксированное смещение относительно начала программы. И что она сразу считается IAR-м при линковке и вставляется в это место: прошивка без CRC не может появиться. В .codehead находится просто указатель на .codetail. Таким образом можно определить реальный размер образа прошивки и прочитать её сигнатуру. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 3 апреля, 2019 Опубликовано 3 апреля, 2019 · Жалоба 1 час назад, jcxz сказал: У меня CRC32 хранится внутри таблицы векторов прерываний, в неиспользуемом векторе по смещению 0x20: То есть вам надо посчитать CRC с адреса 0 до адреса 0x20, потом с адреса 0x24 до адреса в __codetail, потом считать CRC из адреса 0x20 и сравнить с результатом. Мне надо запустить расчет CRC от начала образа на считанный из фиксированного места размер образа +4 байта, проверить результат на ноль. Да, у меня размер образа больше на 8 байт (размер образа и CRC). Я могу себе позволить роскошь сэкономить их в другом месте при необходимости. Размер образа могу поместить в свободное место таблицы векторов, тогда разница в размере образа будет в 4 байта. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 3 апреля, 2019 Опубликовано 3 апреля, 2019 · Жалоба 1 час назад, Сергей Борщ сказал: То есть вам надо посчитать CRC с адреса 0 до адреса 0x20, потом с адреса 0x24 до адреса в __codetail, потом считать CRC из адреса 0x20 и сравнить с результатом. Мне надо запустить расчет CRC от начала образа на считанный из фиксированного места размер образа +4 байта, проверить результат на ноль. Не мне, а процессору. Так, одной строкой: if ((u32)HCRC32p32(&__checksum + 1, __checksum_end + 1 - (u8 *)(&__checksum + 1) >> 2, HCRC32p32(__checksum_begin, (u8 *)&__checksum - __checksum_begin >> 2, ~0) >> 32) != __checksum) trap(TRAP_PRG_IMAGE); А ещё ему (процессору) нужно ещё несколько сотен тысяч других команд выполнить. Десятком команд больше, десятком меньше - какая разница? 1 час назад, Сергей Борщ сказал: Мне надо запустить расчет CRC от начала образа на считанный из фиксированного места размер образа +4 байта, проверить результат на ноль. Да, у меня размер образа больше на 8 байт (размер образа и CRC). А как Вы сказали IAR-у (или другом компилятору) таким образом посчитать CRC и занести её? Ну и к тому же у Вас положение CRC не фиксированное, а зависит от размера таблицы векторов. А у меня - стандарт для всех моих проектов на разных МК Cortex-M. Но и у моего метода тоже есть минусы. PS: Да ещё - ваш метод не будет работать на МК линейки LPC. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 3 апреля, 2019 Опубликовано 3 апреля, 2019 · Жалоба 2 часа назад, jcxz сказал: А как Вы сказали IAR-у (или другом компилятору) таким образом посчитать CRC и занести её? Использую gcc, Его редактор связей считать CRC не умеет. У меня ее считает и добавляет отдельная утилита перед шифрованием образа обновления. 2 часа назад, jcxz сказал: PS: Да ещё - ваш метод не будет работать на МК линейки LPC. У них какие-то особенные Кортексы? Я его и в 8051 использовал... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 3 апреля, 2019 Опубликовано 3 апреля, 2019 · Жалоба 2 часа назад, Сергей Борщ сказал: У них какие-то особенные Кортексы? Я его и в 8051 использовал... Раз Вы считаете не IAR-ом, то тогда думаю неактуально. В LPC (начиная ещё с ARM7) в каком-то из начальных векторов прерываний (возможно по смещению 0x1C - точно не помню) должна находиться контрольная сумма содержимого первых векторов. Её проверяет ROM-boot, и если она не валидна - он считает, что прошивки во FLASH нет и не стартует с FLASH. И компилятор (или компоновщик) должен эту КС сформировать там. Но в IAR-е это как-то странно сделано: если указать начало области подсчёта CRC начиная с этих первых векторов, то CRC считается неправильно. Какой-то там конфликт расчёта КС и CRC по перекрывающимся адресам. Так что всегда для LPC приходится ставить начало региона контролируемого CRC где-то со смещения == 0x24. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 4 апреля, 2019 Опубликовано 4 апреля, 2019 · Жалоба 40 minutes ago, jcxz said: В LPC (начиная ещё с ARM7) в каком-то из начальных векторов прерываний (возможно по смещению 0x1C - точно не помню) должна находиться контрольная сумма содержимого первых векторов. Да, на редкость идиотская была фича. Атмел в те же времена просто проверяли наличие команд b/ldr в векторах. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 4 апреля, 2019 Опубликовано 4 апреля, 2019 · Жалоба 11 часов назад, jcxz сказал: В LPC (начиная ещё с ARM7) в каком-то из начальных векторов прерываний (возможно по смещению 0x1C - точно не помню) должна находиться контрольная сумма содержимого первых векторов. Дарю: /****************************************************************************/ /* Vector table and reset entry */ /****************************************************************************/ .section .vectors,"ax" .global _start .arm _start: LDR PC, reset_addr // Reset LDR PC, undef_addr // Undefined instruction LDR PC, swi_addr // Software interrupt LDR PC, pabort_addr // Prefetch abort LDR PC, dabort_addr // Data abort .word (0 - (5 * 0xE59FF018 + 0xE51FFF00 + 0xE59FF010)) & 0xFFFFFFFF LDR PC, [PC, #-0xFF0] // Read vector address from VIC LDR PC, fiq_addr // FIQ interrupt reset_addr: .word startup undef_addr: .word undef_handler swi_addr: .word swi_handler pabort_addr: .word prefetch_abort_handler dabort_addr: .word data_abort_handler fiq_addr: .word fiq_handler .ltorg Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 4 апреля, 2019 Опубликовано 4 апреля, 2019 · Жалоба 13 минут назад, Сергей Борщ сказал: Дарю: Зачем оно во времена Cortex-M? А на нём так, константно, не посчитаешь. Ну разве что сделать аналогичную таблицу из команд перехода в .section .vectors (неэффективно). Да и даже на ARM7/9 я не прыгал со всех векторов через LDR PC,..., а часть ISR-в располагал в этой же .section .vectors и прыгал на них командой B. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 4 апреля, 2019 Опубликовано 4 апреля, 2019 · Жалоба 4 часа назад, jcxz сказал: Зачем оно во времена Cortex-M? Ну вот. "дай г-на, дай ложку!" Дарю еще: SECTIONS { .text : { . = ALIGN(4); KEEP(*(.isr_vector1)) LONG(0 - (6 + _estack + Reset_Handler + NMI_Handler + HardFault_Handler + MemManage_Handler + BusFault_Handler + UsageFault_Handler)); KEEP(*(.isr_vector2)) /* code read protection */ . = 0x2FC; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 6 апреля, 2019 Опубликовано 6 апреля, 2019 · Жалоба В 04.04.2019 в 18:16, Сергей Борщ сказал: Ну вот. "дай г-на, дай ложку!" Дарю еще: Спасибо конечно, но с LPC давно уже не работаю. Но если придётся снова - проверю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 15 мая, 2019 Опубликовано 15 мая, 2019 · Жалоба Появилось время продолжил разбираться, реализовал размещение CRC в таблице прерывания, только вот возник вопрос, как IAR указать чтобы он считал CRC до адреса где он его расположил CRC (секции checksum) и после секции? Как IAR считает CRC ? т.е до расчета CRC что находиться в секции .checksum ? Либо он в процессе расчета перезаполняет секцию? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 15 мая, 2019 Опубликовано 15 мая, 2019 · Жалоба 1 час назад, pokk сказал: Появилось время продолжил разбираться, реализовал размещение CRC в таблице прерывания, только вот возник вопрос, как IAR указать чтобы он считал CRC до адреса где он его расположил CRC (секции checksum) и после секции? Да никак не надо. Включайте это место в область расчёта. IAR при расчёте CRC пропускает место расположения __checksum. По-крайней мере IAR for ARM. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться