Перейти к содержанию
    

Как занести в структуру CRC приложения ?

Сделал  так:

Положил 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 в структуре была сразу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, pokk сказал:

Сделал  так:

Положил CRC в начало прошивки а структуру сдвинул на 4 байта, а в загрузчике накладываю структуру (с присутствие поля CRC_Appl ) по началу адреса.

Делаю иначе: в начале прошивки сразу после таблицы векторов храню размер прошивки (автоматически проставляет редактор связей (линкер)). Сразу за прошивкой храню CRC. Таким образом, всегда считается  CRC только реально занятой под прошивку области. Реализуется легко, не требуется ничего смещать. Использую ARM Cortex и GCC, просто как идея.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня 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. Таким образом можно определить реальный размер образа прошивки и прочитать её сигнатуру.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

У меня CRC32 хранится внутри таблицы векторов прерываний, в неиспользуемом векторе по смещению 0x20:

То есть вам надо посчитать CRC с адреса 0 до адреса 0x20, потом с адреса 0x24 до адреса в __codetail, потом считать CRC из адреса 0x20 и сравнить с результатом. Мне надо запустить расчет CRC от начала образа на считанный из фиксированного места размер образа +4 байта, проверить результат на ноль. Да, у меня размер образа больше на 8 байт (размер образа и CRC). Я могу себе позволить роскошь сэкономить их в другом месте при необходимости. Размер образа могу поместить в свободное место таблицы векторов, тогда разница в размере образа будет в 4 байта.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Сергей Борщ сказал:

То есть вам надо посчитать CRC с адреса 0 до адреса 0x20, потом с адреса 0x24 до адреса в __codetail, потом считать CRC из адреса 0x20 и сравнить с результатом. Мне надо запустить расчет CRC от начала образа на считанный из фиксированного места размер образа +4 байта, проверить результат на ноль.

Не мне, а процессору. :wink:  Так, одной строкой:

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);

А ещё ему (процессору) нужно ещё несколько сотен тысяч других команд выполнить. Десятком команд больше, десятком меньше - какая разница?  :smile:

1 час назад, Сергей Борщ сказал:

Мне надо запустить расчет CRC от начала образа на считанный из фиксированного места размер образа +4 байта, проверить результат на ноль. Да, у меня размер образа больше на 8 байт (размер образа и CRC).

А как Вы сказали IAR-у (или другом компилятору) таким образом посчитать CRC и занести её?

Ну и к тому же у Вас положение CRC не фиксированное, а зависит от размера таблицы векторов. А у меня - стандарт для всех моих проектов на разных МК Cortex-M.  :smile:  Но и у моего метода тоже есть минусы.

 

PS: Да ещё - ваш метод не будет работать на МК линейки LPC.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, jcxz сказал:

А как Вы сказали IAR-у (или другом компилятору) таким образом посчитать CRC и занести её?

Использую gcc, Его редактор связей считать CRC не умеет. У меня ее считает и добавляет отдельная утилита перед шифрованием образа обновления.

2 часа назад, jcxz сказал:

PS: Да ещё - ваш метод не будет работать на МК линейки LPC.

У них какие-то особенные Кортексы? Я его и в 8051 использовал...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Сергей Борщ сказал:

У них какие-то особенные Кортексы? Я его и в 8051 использовал...

Раз Вы считаете не IAR-ом, то тогда думаю неактуально.

В LPC (начиная ещё с ARM7) в каком-то из начальных векторов прерываний (возможно по смещению 0x1C - точно не помню) должна находиться контрольная сумма содержимого первых векторов. Её проверяет ROM-boot, и если она не валидна - он считает, что прошивки во FLASH нет и не стартует с FLASH. И компилятор (или компоновщик) должен эту КС сформировать там. Но в IAR-е это как-то странно сделано: если указать начало области подсчёта CRC начиная с этих первых векторов, то CRC считается неправильно. Какой-то там конфликт расчёта КС и CRC по перекрывающимся адресам. Так что всегда для LPC приходится ставить начало региона контролируемого CRC где-то со смещения == 0x24.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

40 minutes ago, jcxz said:

В LPC (начиная ещё с ARM7) в каком-то из начальных векторов прерываний (возможно по смещению 0x1C - точно не помню) должна находиться контрольная сумма содержимого первых векторов.

Да, на редкость идиотская была фича. Атмел в те же времена просто проверяли наличие команд b/ldr в векторах.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 минут назад, Сергей Борщ сказал:

Дарю:

Зачем оно во времена Cortex-M? А на нём так, константно, не посчитаешь. Ну разве что сделать аналогичную таблицу из команд перехода в .section .vectors (неэффективно).

Да и даже на ARM7/9 я не прыгал со всех векторов через LDR PC,..., а часть ISR-в располагал в этой же .section .vectors и прыгал на них командой B.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 часа назад, jcxz сказал:

Зачем оно во времена Cortex-M?

Ну вот. "дай г-на, дай ложку!" :crazy:

Дарю еще:

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;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 04.04.2019 в 18:16, Сергей Борщ сказал:

Ну вот. "дай г-на, дай ложку!" :crazy:

Дарю еще:

Спасибо конечно, но с LPC давно уже не работаю. Но если придётся снова - проверю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Появилось время продолжил разбираться, реализовал размещение  CRC в таблице прерывания, только вот возник вопрос, как IAR указать чтобы он считал  CRC до адреса где он его расположил CRC (секции checksum) и после секции?

Как IAR считает CRC ? т.е до расчета CRC что находиться в секции .checksum ? Либо он в процессе расчета перезаполняет секцию?

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Появилось время продолжил разбираться, реализовал размещение  CRC в таблице прерывания, только вот возник вопрос, как IAR указать чтобы он считал  CRC до адреса где он его расположил CRC (секции checksum) и после секции?

Да никак не надо. Включайте это место в область расчёта. IAR при расчёте CRC пропускает место расположения __checksum. По-крайней мере IAR for ARM.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...