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

Область видимость констант линкера

IAR 9.50.1.69506

Приветствую. Помогите разобраться.

1. Вопрос первый

а) Считаю КС способом как на скрине.

б) В линкере есть такие строки для размещения КС по определенному адресу:

define symbol __addr_calc_cs_end__ = 0x0800FFFB;
place at address mem:__addr_calc_cs_end__ +1 { readonly section .checksum };

в) В исходнике используя константы линкера __checksum_begin, __checksum_end, __checksum счтитаю и сверяю КС (в файле .icf они не видны).

Могу ли я "расширить область видимости" __checksum_end для файла линкера .icf, что бы адресс 0x0800FFFB не прописывать два раза (во вкладке Checksum и файле .icf)?

2. Вопрос второй

Можно ли передать глобальную константу в inline asm, что бы вместо MOV R0, #0x20000000 было MOV R0, RAM_START?

asm (
    "MOV R0, #0x20000000   \n"
    "ADD R4, R0, #0x4000   \n"
    "ADD R0, R0, #0x000C   \n"
    ...

сейчас делаю это так: void r0_r1_r2(int r0, int r1, int r2) { asm ("nop"); }, после вызова ф-ции значения ее входных параметров оказываются в соответствующих регистрах, а потом уже мой inline asm

учитывает это. Только не уверен, что это надежно. Понимаю, что "костыль".

 

1.png

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


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

5 часов назад, const сказал:

Могу ли я "расширить область видимости" __checksum_end для файла линкера .icf, что бы адресс 0x0800FFFB не прописывать два раза (во вкладке Checksum и файле .icf)?

А зачем его (константный адрес) вообще прописывать?

Использую CRC в IAR и никакой константный адрес для CRC не прописываю ни разу. Располагаю CRC в таблице векторов прерываний.

5 часов назад, const сказал:

Можно ли передать глобальную константу в inline asm, что бы вместо MOV R0, #0x20000000 было MOV R0, RAM_START?

Можно сколько угодно. В документации IAR есть описание формата asm(). Прочитайте его.

Вот пример из моего кода:

inline void AdcUiDataRst(AdcPCell *pcell, u32 *acc, uint n, s32 filter)
{
  u32 i;
  asm(
    "     SUBS     %[pcell], %[pcell], #10 \n"
    "p01: LDRH     %0, [%[pcell], #10]!    \n"
    "     STRH     %0, [%[pcell], #2]      \n"
    "     STRH     %0, [%[pcell], #4]      \n"
    "     LDR      %0, [%[acc]], #4        \n"
    "     SMMULR   %0, %0, %[filter]       \n"
    "     RSBS     %0, %0, #0              \n"
    "     SUBS     %[n], %[n], #1          \n"
    "     STRH     %0, [%[pcell], #6]      \n"
    "     STRH     %0, [%[pcell], #8]      \n"
    "     BNE      p01                     \n"
    : "=&r"(i)
    : [pcell]"r"(pcell), [acc]"r"(acc), [n]"r"(n), [filter]"r"(filter)
    : "cc", "memory");
  i = i;
}
5 часов назад, const сказал:

Сейчас делаю это так: void r0_r1_r2(int r0, int r1, int r2) { asm ("nop"); }, после вызова ф-ции значения ее входных параметров оказываются в соответствующих регистрах, а потом уже мой inline asm учитывает это. Только не уверен, что это надежно. Понимаю, что "костыль".

Это выстрел себе в ногу. Так как компилятор в полном праве заинлайнить вашу функцию и никаких гарантий по регистрам не получите.

И к тому же вы писали про "константу", а передаёте её как переменную - в регистре. В то время как синтаксис аргументов встроенного asm() позволяет передавать именно как константу (для чего есть соответствующие типы аргументов; например = "i").

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


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

7 hours ago, jcxz said:

А зачем его (константный адрес) вообще прописывать?

Использую CRC в IAR и никакой константный адрес для CRC не прописываю ни разу. Располагаю CRC в таблице векторов прерываний.

1) Как я уже писал, считаю КС от 0х0 до 0хFFFB (КС по 0хFFFС). Если не указывать где располагать КС у меня ее кидает куда попало (в диапазоне от 0х0 до 0хFFFB). Как при этом быть с программным подсчетом, пропускать тот адрес где лежит КС в алгоритме? Или считать с ним и должен в итоге получиться "ноль". Если я считаю программно КС от 0х0 до 0хFFFF (КС по 0хFFFС) "нуля" не получаю.

2) В самой таблице векторов или сразу после? Если в самой таблице, то место какого то прерывания неиспользуемого? У вас считается вся доступная флешь с таблицей прерываний (какой диапазон адресов, для примера)? При программном подсчете КС вы результат сверяете с подсчетом линкера или у вас на выходе "ноль" когда все ОК?

7 hours ago, jcxz said:

Можно сколько угодно. В документации IAR есть описание формата asm(). Прочитайте его.

Вот пример из моего кода:

Читал. С лету не вышло разобраться. Ваш пример почти весь понятен (мне подходит), разбираюсь пока.

7 hours ago, jcxz said:

Это выстрел себе в ногу.

Понимаю, поэтому тут с вопросами.

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


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

Почему бы не написать простейший .exe-патч, который готовый скомпиленный бинарник дополнит посчитанной КС? Мы один раз написали себе утилиту и теперь совершенно не зависим от какой-либо среды разработки. Рекомендую... мало ли завтра представится вынужденный переход на GCC/Clang или любой другой - и снова вернетесь к задаче. Стоит оно того?

КС и размер образа (по которому считается КС) можно хранить в неиспользуемых векторах исключений ядра Cortex-M, а не обычных прерываний, т.к. обычные прерывания сегодня не используешь, а завтра - да. Правда я, например, в свое время немножко недодумал этот момент, и располагаю КС + размер образа прямо за таблицей векторов, о чем сейчас жалею, т.к. приходится поддерживать много разработанных девайсов.

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


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

11 minutes ago, Arlleex said:

Почему бы не написать простейший .exe-патч, который готовый скомпиленный бинарник дополнит посчитанной КС? Мы один раз написали себе утилиту и теперь совершенно не зависим от какой-либо среды разработки. Рекомендую... мало ли завтра представится вынужденный переход на GCC/Clang или любой другой - и снова вернетесь к задаче. Стоит оно того?

КС и размер образа (по которому считается КС) можно хранить в неиспользуемых векторах исключений ядра Cortex-M, а не обычных прерываний, т.к. обычные прерывания сегодня не используешь, а завтра - да. Правда я, например, в свое время немножко недодумал этот момент, и располагаю КС + размер образа прямо за таблицей векторов, о чем сейчас жалею, т.к. приходится поддерживать много разработанных девайсов.

патч у вас автоматом запускается после компиляции?

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


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

34 минуты назад, const сказал:

патч у вас автоматом запускается после компиляции?

Я работаю в Кейле - он штатно дает возможность запустить любую программу как до, так и после сборки проекта. Правда я этим не пользуюсь за ненадобностью.

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


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

On 8/27/2024 at 10:21 PM, Arlleex said:

КС и размер образа (по которому считается КС) можно хранить в неиспользуемых векторах исключений ядра Cortex-M, 

Почему именно так ?
Я, например, размещаю CRC в конце прошивки, а размер прошивки сразу за таблицей векторов.

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


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

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

Я, например, размещаю CRC в конце прошивки, а размер прошивки сразу за таблицей векторов.

А как вы КС считаете в рантайме с этим? в два захода - по таблице векторов + после CRC?

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


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

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

Почему именно так ?
Я, например, размещаю CRC в конце прошивки, а размер прошивки сразу за таблицей векторов.

Плохо. Повторюсь, я тоже делаю за таблицей, но этот вараэиант плох тем, что положение КС и размера в файле будут разными для разных МК даже одной серии. И от размера прошивки зависимо. Это плохо - программа патча должна будет знать о размере таблицы векторов как минимум. Довольно костыльно и не универсально.

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


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

16 часов назад, const сказал:

1) Как я уже писал, считаю КС от 0х0 до 0хFFFB (КС по 0хFFFС). Если не указывать где располагать КС у меня ее кидает куда попало (в диапазоне от 0х0 до 0хFFFB). Как при этом быть с программным подсчетом, пропускать тот адрес где лежит КС в алгоритме? Или считать с ним и должен в итоге получиться "ноль". Если я считаю программно КС от 0х0 до 0хFFFF (КС по 0хFFFС) "нуля" не получаю.

Я считаю и проверяю CRC так:

extern "C" u8 const __checksum_begin[];
extern "C" u8 const __checksum_end[];
extern "C" u32 const __checksum;
...
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);
...
//Расчёт CRC32 (полином == 0xEDB88320) аппаратным CRC-вычислителем
//словами u32. Реентерабельна.
//len - длина [слов u32] (должно быть !=0).
//return: мл.u32 - результат; ст.u32 - seed для след.вызова HCrc32.. при цепочечном расчёте
//HCrc32p32(&x, sizeof(x) / 4, ~0) == Crc32(&x, sizeof(x) & -4, ~0)
u64 HCrc32p32(void const *data, uint len, u32 seed);

Где __checksum_begin и __checksum_end - начало и конец области, для которой считается CRC. __checksum - место лежания CRC.

Т.е. как видно - считается с пропуском области __checksum.

16 часов назад, const сказал:

2) В самой таблице векторов или сразу после? Если в самой таблице, то место какого то прерывания неиспользуемого?

Использую естественно один из свободных векторов ядра Cortex-M. Там есть неиспользуемые. См.даташит на ядро. Я использую 8-й вектор. Во всех проектах на Cortex-M, на разных МК уже много лет как.

16 часов назад, const сказал:

У вас считается вся доступная флешь с таблицей прерываний (какой диапазон адресов, для примера)?

0x08000000...0x08019EFF

16 часов назад, const сказал:

При программном подсчете КС вы результат сверяете с подсчетом линкера или у вас на выходе "ноль" когда все ОК?

Сверяю. См. код выше.

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


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

On 8/28/2024 at 12:33 PM, AlexRayne said:

А как вы КС считаете в рантайме с этим? в два захода - по таблице векторов + после CRC?

В один проход. Просто с нуля и до конца прошивки в вычислитель CRC кидаются байт за байтом.

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


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

3 часа назад, dimka76 сказал:

Почему именно так ?
Я, например, размещаю CRC в конце прошивки, а размер прошивки сразу за таблицей векторов.

Таблица векторов в разных МК имеет разный размер. Что неудобно. Зачем так, если можно сохранить по фиксированному адресу в одном из неиспользуемых векторов ядра?

А в некоторых проектах ещё бывает нужны программно возбуждаемые прерывания. Которые используют вектора после последних аппаратных. Это опять приводит к разному размеру таблицы векторов даже на одном и том же МК.

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


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

On 8/28/2024 at 12:57 PM, Arlleex said:

 Это плохо - программа патча должна будет знать о размере таблицы векторов как минимум. 

Да, есть такой недостаток.
Но у меня зоопарк микроконтроллеров очень маленький. Всего только две марки.

On 8/28/2024 at 2:28 PM, jcxz said:

Зачем так, если можно сохранить по фиксированному адресу в одном из неиспользуемых векторов ядра?

Так получилось. А всех нюансов изначально не получилось продумать.

Может даже изначально тупо где-то подсмотрел. Не помню уже как там изначально было.

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


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

On 8/27/2024 at 2:43 PM, jcxz said:

Можно сколько угодно. В документации IAR есть описание формата asm(). Прочитайте его.

Потратил время, разобрался. Вопрос отпал.

9 hours ago, jcxz said:

Где __checksum_begin и __checksum_end - начало и конец области, для которой считается CRC. __checksum - место лежания CRC.

Т.е. как видно - считается с пропуском области __checksum.

Как понимаю, считая КС вашим способом нет разницы по какому адресу лежит подсчитанная линкером КС. Какой смысл ее помещать в таблицу векторов?

 

12 hours ago, dimka76 said:

Я, например, размещаю CRC в конце прошивки, а размер прошивки сразу за таблицей векторов.

Покажите как это выглядит в линкере и как передать адрес расположения размера прошивки (в прошивке) в программу, пожалуйста. И как положить КС в конец прошивки.

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


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

5 часов назад, const сказал:

Какой смысл ее помещать в таблицу векторов?

Я же уже говорил зачем:

В 27.08.2024 в 14:43, jcxz сказал:

А зачем его (константный адрес) вообще прописывать?

Использую CRC в IAR и никакой константный адрес для CRC не прописываю ни разу.

Чтобы не прибивать гвоздями к какому-то дополнительному фиксированному адресу.

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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