|
Размер таблицы прерываний STM32 |
|
|
|
May 26 2015, 08:42
|
Профессионал
    
Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528

|
В IAR ещё проще Код #pragma section=".intvec" printf( "intvec segment size = %d\r\n", (uint32_t)__segment_end(".intvec") - (uint32_t)__segment_begin(".intvec") );
--------------------
Russia est omnis divisa in partes octo.
|
|
|
|
|
May 27 2015, 03:49
|
Местный
  
Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188

|
В CrossWorks (GNU) работает это: CODE extern void* __vectors_load_start__; extern void* __vectors_load_end__; ................................ uint32_t vt_length = (uint32_t)&__vectors_load_end__ - (uint32_t)&__vectors_load_start__;
Имена взяты из map-файла. Может быть и в IAR возможно что-то подобное?
|
|
|
|
|
May 27 2015, 07:29
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(ViKo @ May 26 2015, 09:43)  Порылся в своем, нашел, вспомнил - в c-файл из ассемблерного можно передать переменную. Вот обратного действия у меня не получилось. Я не думаю, что IAR в этом смысле сильно отличается от KEIL, а в KEIL для использования в С из S: s: EXPORT mysimbol c: extern <typedef> mysimbol; В обратную сторону: c: <typedef> mycsimbol; s: IMPORT mycsimbol Мне "удалось" также импортировать в ассемблер символы, генерируемые компоновщиком (касается адресов и размеров секций). Например, IMPORT |Load$$LR$$LR_IROM2$$Length|, то есть, длину региона загрузки LR_IROM2 (должно быть обрамлено именно вертикальными линиями). Это все не я раскопал, конечно. Описано на сайте onarm.com, но ссылки я уже не приведу.
Сообщение отредактировал KnightIgor - May 27 2015, 07:30
|
|
|
|
|
May 27 2015, 07:37
|
Профессионал
    
Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528

|
Цитата(Axel @ May 27 2015, 10:49)  Может быть и в IAR возможно что-то подобное? Что-то подобное я уже писал в предыдущем сообщении. Но у IAR есть ещё одна чрезвычайно полезная штука: папка doc. Оказывается, кроме __segment_begin и __segment_end есть не менее полезная псевдофункция __segment_size.
--------------------
Russia est omnis divisa in partes octo.
|
|
|
|
|
May 28 2015, 06:04
|
Знающий
   
Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231

|
Спасибо всем. результат таков: 1. через __segment_size получаем размер таблицы векоров, но это значение нельзя использовать препроцессором, т.е. Код #pragma section=".intvec" #define FLASH_VECTOR_TABLE_SIZE ((uint32_t)__segment_size(".intvec"))
#define FLASH_WRITE_BLOCK_SIZE (512)
// !!! --- Это работать не будет --- #if (FLASH_WRITE_BLOCK_SIZE < FLASH_VECTOR_TABLE_SIZE) #error "Error FLASH_WRITE_BLOCK_SIZE" #endif 2. через EXPORT __vector_table в ассемблере (startup_stm32f40_41xxx.s ), затем extern uin32_t __vector_table или extern uin32_t* __vector_table в си, можно определить адрес расположения __vector_table или значение записанное по этому адресу __vector_table[0], но размер таблицы не определить, т.к. опереция sizeof(__vector_table)/sizeof(__vector_table[0]) выдаст 1.
|
|
|
|
|
May 28 2015, 10:27
|
Профессионал
    
Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528

|
Цитата(Rash @ May 28 2015, 13:04)  Спасибо всем. результат таков: 1. через __segment_size получаем размер таблицы векоров, но это значение нельзя использовать препроцессором, т.е. Так не удивительно, что первый, что второй методы работают одинаково: через определение символов (меток) для линкера, и только линкер знает их реальные значения, получившиеся в процессе сборки. Впрочем, если Вы не сами пишете .s, а используете готовый, то размер таблицы можно вычислить зная максимальный номер вектора. Надо только учесть ещё 16 слов для векторов с отрицательными номерами. Ищем определение typedef enum{ ... } IRQn_Type;, дописываем две строчки: Код typedef enum{ ..... HASH_RNG_IRQn = 80, /*!< Hash and RNG global interrupt */ FPU_IRQn = 81 /*!< FPU global interrupt */ ,__MAX_VECTOR_NUM__ /* получит значение на 1 больше максимального номера вектора */ } IRQn_Type; #define VECTOR_TABLE_SIZE (4*(__MAX_VECTOR_NUM__-1+16)) ЗЫ. Сравнивая размер таблицы векторов с FLASH_WRITE_BLOCK_SIZE Вы проявляете завидную дальновидность Пока что даже у самого толстого F756 этот размер составляет (97+16)*4 = 452 байта.
--------------------
Russia est omnis divisa in partes octo.
|
|
|
|
|
May 28 2015, 10:57
|
Знающий
   
Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231

|
.s беру стандартные из CMSIS, FLASH_WRITE_BLOCK_SIZE задаётся, может быть изменён в настройках перед компиляцией. Приложение это бутлоадер. И т.к. контроллеры могут быть разные, а ядро одинаковое, решил сделать доп. проверку. В Код typedef enum{ ..... } IRQn_Type; можно вставить, но это редактирование stm32f4xx.h, хоть и один раз (но при смене версии нужно учитывать), а так подменил .s файл и всё посчитало при компиляции. Вначале просто вычислил все вектора для мк 4-ой серии и записал дефайнами, но стало интересней сделать поумнее.
|
|
|
|
|
May 28 2015, 11:35
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата Бутлоадер в основной прошивке запишет CRC основной прошивки после векторов прерываний. Естественно основная прошивка для этого зарезервирует место для CRC. а зачем он это сделает? да правда нет но можно использовать Reset_Handler он вроде как идет сразу после таблицы с началом __Vectors А можно в конце таблице добавить __Vectors_end , так будет совсем красиво.... Не наврал по карте памяти там __main.o вроде как сразу легло... интересно это зафиксировано?
|
|
|
|
|
May 28 2015, 13:05
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
CRC я дописываю в конец файла прошивки. Естественно, CRC всего файла вместе с CRC должна быть равна 0, если принял правильно. При приеме файла вычисляю его размер, и по этому размеру прогоняю вычисление CRC. Этот же размер я храню в области векторов, конкретно, в дыре по адресу 0x0020. При включении прибора даю время запустить загрузчик с панели управления. Если загрузчик не запускается, читаю по адресу 0x0020 размер прошивки, вычисляю CRC и запускаю рабочую программу, если CRC равна 0. Если CRC не верна, значит, рабочей программы нет.
|
|
|
|
|
May 28 2015, 19:27
|
Знающий
   
Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231

|
Цитата(Golikov A. @ May 28 2015, 21:57)  а мы добили прошивку мусором до полного числа секторов, и конец определяем по первому пустому сектору, при заливке стираем на 1 сектор больше, так у нас конец определен и хранить не надо ничего... Это всё хорошо когда сектора маленькие. А допустим в 401 (256k Flash), 4 сектора 16k - 2 для бута и 2 эмуляция EEPROM, 1 сектор 64 kB - основная программа и 1 сектор 128 - возможно в будущем ещё одна основная программа. Это всё соединено последовательно друг за другом до 100 устройств по RS-485, скорость ~ 115200. И передавать лишнее килобайты как то не особо хочется, при этом не разрушая работу всей системы. ViKo, за метки спасибо, завтра попробую.
|
|
|
|
|
Jun 5 2015, 10:23
|
Знающий
   
Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231

|
Появилось время попробовать вариант 2 код в .s файле Код EXPORT VECTOR_TABLE_SIZE
DATA __vector_table ... ... __vector_table_end VECTOR_TABLE_SIZE EQU __vector_table_end - __vector_tabl код в .с файле Код extern uint32_t VECTOR_TABLE_SIZE; #define FLASH_VECTOR_TABLE_SIZE VECTOR_TABLE_SIZE
[b]// !!! --- По прежнему не работает ---[/b] #if (FLASH_WRITE_BLOCK_SIZE < FLASH_VECTOR_TABLE_SIZE) #error "Error FLASH_WRITE_BLOCK_SIZE" #endif Цитата Remark[Pe193]: zero used for undefined preprocessing identifier "FLASH_WRITE_BLOCK_SIZE" В коде всё как и в 1-ом варианте работает нормально. Думаю заставить препроцессор увидеть переменную раньше дефайна нет. Т.к. в .s файле это дефайн, а при экспорте в .c файл это уже объявление переменной.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|