Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: IAR: Расчет CRC только для секции CODE, запись размера прошивки во FLASH
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
093
Приветствую! Подскажите пожалуйста:

1) Есть ли возможность в IAR настроить расчет CRC не для всей области памяти, как это делается по умолчанию путем предварительного заполнения неиспользуемой памяти значениями 0xFF, а только для той, где лежит программа?
Ведь в процессе работы содержимое flash может изменяться (например, записали туда какие-то настройки) и CRC уже не совпадет.
2) Допустим генерацию CRC настроили как надо, но как определить по какому объему данных рассчитывать CRC?
Может быть можно настроить линкер так, чтобы перед кодом программы он вставил размер прошивки (4 байта) или в конец программы специальный маркер из 4...8 байт, который нигде больше не встречается? Какие для этого используются директивы?
jcxz
Цитата(93 @ Sep 8 2017, 14:01) *
Ведь в процессе работы содержимое flash может изменяться (например, записали туда какие-то настройки) и CRC уже не совпадет.

Кто-ж пишет в тот-же сектор, в котором лежит прошивка??? И как собственно Вы это умудряетесь делать, ведь для этого его надо предварительно стереть?
Для прошивки определить отдельный регион памяти и задать расчёт CRC для этого региона.
093
Цитата
Кто-ж пишет в тот-же сектор, в котором лежит прошивка??? И как собственно Вы это умудряетесь делать, ведь для этого его надо предварительно стереть?

Легко - прошивка занимает лишь 10% свободной памяти. Остальной flash - под запись архивов.

Почитал доку на линкер и так и не понял как задать расчет CRC только по блоку CODE.
С параметрами:
-HFF
-J2,crc16={CODE}


Получаю:
Error[e171]: The segment "CODE" that is used in a checksum command is a packed segment.

Хотя не ясно - что ему мешает так рассчитать CRC. "Промежутки" в секции где вектора прерываний заполнили, бери да считай, тем более размер блока известен.

Возникают даже мысли написать свой велосипед на сях, который будет рассчитывать и вставлять CRC, а также размер блока по которому его считают.
x893
Тем более, что пишется за 10-15 минут.
jcxz
Цитата(93 @ Sep 11 2017, 23:07) *
Легко - прошивка занимает лишь 10% свободной памяти. Остальной flash - под запись архивов.

Прошивка занимает не 10% или сколько там %. Она занимает целое число секторов флешь. Сектор флешь - это минимальный элемент стирания flash.
Теперь включите голову и ещё раз подумайте, что будет если попытаться записать (с предварительным стиранием) что-либо сразу после последнего байта программы без учёта границ секторов.

Цитата(93 @ Sep 11 2017, 23:07) *
Хотя не ясно - что ему мешает так рассчитать CRC.

Неясно что мешает сделать как все разумные люди: для прошивки зарезервировать целое число секторов флешь, на вкладке опций проекта посвящённой расчёту CRC указать границы этой области и в области прошивки определить место хранения посчитанной CRC. А для хранения архивов (или там чего ещё) определить отдельный регион целых секторов флешь.
093
Цитата
что будет если попытаться записать (с предварительным стиранием) что-либо сразу после последнего байта программы без учёта границ секторов

Кто вам это сказал? Не надо додумывать.
Цитата
на вкладке опций проекта посвящённой расчёту CRC указать границы этой области

Нет на той вкладке такой опции. Можно только через командную строку задать.
Вообще такой способ довольно плох тем, что будем ограничены парой секторов, а если прошивка больше занимает?

Как задать специальный маркер из нескольких байт сразу после CODE и CONST memory? Это бы решило сразу пару проблем.

k155la3
Цитата(93 @ Sep 12 2017, 16:07) *
. . .
Как задать специальный маркер из нескольких байт сразу после CODE и CONST memory? Это бы решило сразу пару проблем.

В файле линкера определите свой сегмент, расположенный за сегментом CODE (CONST идет в начале флеш)
и пользуйте его через

Код
/*const*/   int MyVar[] @ "MY_CODE_SEG" = {0x55AA, 0xAA55};

ps - правильно-ли, и будет ли работать - не знаю, возможно линкер будет ругаться что посягнули на "CODE".
Скорее всего это реализуемо, но надо хорошо знать что и где прописывать в файле линкера.
Если разберетесь - поделитесь sm.gif
jcxz
Цитата(93 @ Sep 12 2017, 20:07) *
Кто вам это сказал? Не надо додумывать.

Вы сами и сказали. Когда написали, что прошивка пострадает при записи каких-то настроек.
Цитата(93 @ Sep 8 2017, 14:01) *
Ведь в процессе работы содержимое flash может изменяться (например, записали туда какие-то настройки) и CRC уже не совпадет.

Она никак не пострадает если границы расчёта CRC задать фиксированными и выровненными по границе секторов.
И она в любом случае может пострадать если писать что-то в сектора, занятые прошивкой. Не важно как вы будете считать CRC - IAR-ом или своим велосипедом.

Цитата(93 @ Sep 12 2017, 20:07) *
Нет на той вкладке такой опции. Можно только через командную строку задать.
Вообще такой способ довольно плох тем, что будем ограничены парой секторов, а если прошивка больше занимает?

Значит - выделить больше секторов под неё.
Нет опции - значит задать через командный файл.
x893
А чем не устраивает запись CRC например после таблицы векторов - она известно где лежит.
Можно сделать сигнатуру свою и после нее записывайте свою сумму (хоть в бин хоть в elf/afx/out).
Когда то страдал такой проблеммой - сделал после векторов
сигнатура
последний адрес секции .text
0
Потом своей приблудой считал CRC и заменял 0.
При старте точно также считал на MCU.
Вообще не понятно из-за чего сыр-бор. Пара часов.
Obam
Цитата(x893 @ Sep 16 2017, 17:56) *
А чем не устраивает запись CRC например после таблицы векторов - она известно где лежит.

В MSP430 (если не ядро 430X (там вообще этот топик не актуален), а конкренный проц TS не указал) после таблицы векторов ничего нет (; адресного пространства - нет.
093
Obam, проц MSP430F5418A и MSP430F5438A

Цитата(k155la3 @ Sep 15 2017, 02:00) *
В файле линкера определите свой сегмент, расположенный за сегментом CODE (CONST идет в начале флеш)
и пользуйте его через
Если разберетесь - поделитесь sm.gif


Вот с определение сегмента как раз и проблема: линкер игнорирует этот сегмент.

Код
//В main.c
const int MyVar[] @ "MYSEGMENTA" = {0x55AA, 0xAA55};


Код
// ---------------------------
// Constant data
//
-Z(CONST)DATA20_C,DATA20_ID,CODE_ID=5C08-FF7F,10040-25BEF
//Объявляю сегмент:
-Z(CONST)MYSEGMENTA=25BF0-25BFF


В map файле нет этого сегмента и никаких ошибок тоже нет:

Код
SEGMENT              SPACE    START ADDRESS   END ADDRESS     SIZE  TYPE  ALIGN
=======              =====    =============   ===========     ====  ====  =====
DATA16_AN                              0102 - 0103               2   rel    0
....
....
CODE_I                                    1C00                       rel    1
DATA20_I                               1C00 - 1C40              41   rel    1
DATA20_Z                               1C42 - 22B5             674   rel    1
DATA20_N                                  22B6                       rel    1
DATA20_HEAP                            22B6 - 2305              50   rel    1
CSTACK                                 5B60 - 5BFF              A0   rel    1
CSTART                                 5C08 - 5C37              30   rel    1
ISR_CODE                               5C38 - 5E0B             1D4   rel    1
<CODE> 1                               5E0C - EFF9            91EE   rel    1
INTVEC                                 FF80 - FFF3              74   com    1
RESET                                  FFFE - FFFF               2   rel    1
DATA20_C                           00010040 - 00012337        22F8   rel    1
DATA20_ID                          00012338 - 00012378          41   rel    1
CODE_ID                                 0001237A                     rel    1
jcxz
Цитата(93 @ Sep 20 2017, 15:06) *
Вот с определение сегмента как раз и проблема: линкер игнорирует этот сегмент.

Откройте мануал на компилятор и прочитайте назначение префикса __root.
То же самое для атрибута ROOT секции.
То же самое можно сделать через свойства проекта. И думаю, что и через командный файл линкёра тоже.
093
jcxz,
Ларчик просто открывался! biggrin.gif
Компилятор игнорил и переменную и сегмент - т.к. переменная нигде в коде не использовалась.
Спасибо! Я так и не вспомнил про это.
093
Ну что же, с маркерами разобрались, осталось разобраться с расчетом CRC:
Возможно ли как-то не вручную узнать адреса сегментов, чтобы указать в параметре range откуда начать расчет CRC и где закончить? Что-то вроде: считаем от START_MARKER до END_MARKER.
Можно конечно объявлять адреса явно, но это не удобно.

Добавил:

Впрочем, вот с такими настройками CRC считается там где надо sm.gif
Код
-J2,crc16={CODE}
jcxz
Цитата(93 @ Sep 20 2017, 19:34) *
Компилятор игнорил и переменную и сегмент - т.к. переменная нигде в коде не использовалась.

Значит всё-таки прочитали про __root rolleyes.gif
k155la3
Цитата(93 @ Sep 20 2017, 16:57) *
. . . .
Возможно ли как-то не вручную узнать адреса сегментов, . . . .

Если из кода - то в переменных препроцессора надо смотреть.
SSerge
Цитата(k155la3 @ Sep 25 2017, 02:10) *
Если из кода - то в переменных препроцессора надо смотреть.

У препроцессора вообще никаких переменных нет, он просто делает замены одного текста на другой, ну и есть ещё выражения в директивах типа #if.

В программе можно ссылаться на адреса и размеры сегментов, но их реальные значения станут известны только в результате работы линкера.
Можно также сделать доступными программе константы, объявленные в .icf файле.

Так что, если это действительно нужно, придётся получать реальные адреса из выхлопа линкера.
k155la3
Цитата(SSerge @ Sep 25 2017, 10:02) *
У препроцессора вообще никаких переменных нет, . . .

Да, Вы правы.
Вот нашел, где я на эту тему натыкался в Help/IAR/MSP430

Код
#pragma segment="MYSEGMENT" __data16
__root void * seg_addr;

int main(void)
{
   seg_addr = __segment_begin("MYSEGMENT");  
   . . .


MYSEGMENT должен быть определен в файле линкера.
jcxz
Цитата(k155la3 @ Sep 29 2017, 03:12) *
MYSEGMENT должен быть определен в файле линкера.

А что толку? Как эти адреса (начала/конца сегмента) передать процессу подсчёта CRC?
093
Интересно, как правильно выбрать значения маркеров конца/начала прошивки так, чтобы эти маркеры с наименьшей вероятностью встретились в самой прошивке?
k155la3
Цитата(93 @ Sep 29 2017, 22:39) *
Интересно, как правильно выбрать значения маркеров конца/начала прошивки так, чтобы эти маркеры с наименьшей вероятностью встретились в самой прошивке?

В таблице команд найти "недействительный" опкод, и оттиражировать ЕГО на максимальную длину команд + 1, чтобы "заэкранировать"
данные, которые могут быть какимиугодно. Это "сработает" только для кодового сегмента, где нет массивов данных.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.