Jump to content

    

_Desh_

Участник
  • Content Count

    57
  • Joined

  • Last visited

Community Reputation

0 Обычный

About _Desh_

  • Rank
    Участник
  • Birthday 07/19/1988

Контакты

  • Сайт
    Array
  • ICQ
    Array

Recent Profile Visitors

898 profile views
  1. Методом проб и ошибок выяснил, что перезаписать данные по некоторому адресу можно, сначала исключив этот адрес: srec_cat.exe test_file_source.bin -binary -exclude 0x1C 0x20 -length-l-e 0x1C -o test_file.bin -binary Теперь по адресу 0x1C корректно записывается длина файла. Но теперь проблема записать по адресу 0x20 значение CRC. Если исключить диапазон 0x20-0x24, то в расчете CRC он не участвует, выдается предупреждение о том, что в данных есть прореха. В принципе, при сверке CRC программно внутри контроллера можно это учесть, но получается как-то некрасиво. Есть ли более элегантный способ прописать CRC в нужный адрес?
  2. Вопрос немного не об этом, но допустим. При попытке писать длину прошивки и CRC вместо неиспользуемых (несуществующих) векторов по заранее известному фиксированному адресу: srec_cat.exe test_file_source.bin -binary -length-l-e 0x1C -crc32-b-e 0x20 -o test_file.bin -binary srec_cat.exe выводит следующее сообщение об ошибке: srec_cat: test_file_source.bin: 0x0400: multiple 0x0000001C values (previous = 0x0C, this one = 0x00) Что это означает и как это исправить? Из документации ни черта не понятно, там есть почти такой же пример, и видимо он должен работать. P.S. Что означает ошибка примерно понял. Он мне хочет сказать, что я хочу какое-то ненулевое значение перезаписать новым значением (нулевым). Ну и что? Мне это и надо.
  3. Прошерстил форум и Интернет на предмет использования утилиты srec_cat.exe, но остались вопросы и непонятки. Мне надо добавить в конец прошивки ее CRC, с этим я справился: srec_cat.exe test_file_source.bin -binary -crc32-l-e -maximum-address test_file_source.bin -binary -o test_file.bin -binary Также хотелось бы перед формированием конечного файла прошивки увидеть в выводе IDE полученную CRC (или даже записать ее в отдельный файл). Это тоже можно сделать, например, так: srec_cat.exe test_file_source.bin -binary -fill 0xFF 0 0x400 -crop 0 0x400 -crc32-b-e 0x400 -crop 0x400 0x404 -o - -hex-dump Но как быть, если размер прошивки заранее неизвестен? Чтобы встроить вызов утилиты в IDE и полностью автоматизировать процесс, не вводя ручками каждый раз разные адреса. Во втором случае, если использовать, например, -crop -maximum-address test_file_source.bin -binary -maximum-address test_file_source.bin -binary -offset 4 вместо -crop 0x400 0x404 В консоль выводится полный дамп прошивки, а не 4 последние байта, как мне надо. Есть ли способ для утилиты srec_cat.exe указывать в качестве параметров, например, реальную длину файла, а не забивать магические константы?
  4. Если она обратится к библиотечным функциям, у которых исходные коды недоступны, у меня будут проблемы. Но наверняка они тоже решаемы, просто я пока не знаю как (оно мне сейчас не надо). Последний раз я пользовался Keil 4 с ARMCC и там можно было прямо в свойствах исходника мышкой указать размещение в конкретной области памяти. Либо так же с помощью атрибута, аналогичного GCC, если для отдельной функции или переменной. Но там еще можно было явно адрес указывать, например, __attribute__((at(0x20002000))). А в GCC так нельзя, только через линкер и секции.
  5. Знает. Я даже могу обратиться к переменным, указанным в скрипте линкера, в исходном коде, собственно, я это и делаю, когда копирую код функции - именно из скрипта я беру начальный и конечный адреса нужного участка кода. Нет, не допустимо. Я даже цитату из документации по компилятору для этого привел - он разместит мой код там, где ему указывает атрибут. Не останется, если я точно так же скопирую весь код и переменные, к которым идет обращение, туда же, при необходимости. Это неудобно, не спорю. В документации на линкер написано, что можно даже целиком объектный файл указывать для размещения в данной секции, но с этим я пока не разобрался. Копирование специально сделано перед вызовом функций, которые работают с периферией, как мне и посоветовали здесь. Я включил оптимизацию Os, затем O2, обычная функция и функция-обработчик прерывания работают из ОЗУ, поведение программы соответствует ожидаемому. Я не использую IAR, используемую среду разработки я указал в первом же посте первой же строкой.
  6. https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes __attribute__((section(".RAMFUNC"))) void systick_config(void) { ... } Размещение секции указано здесь: RAMFUNC (rx) : ORIGIN = 0x20000000, LENGTH = 8K и здесь: .ramfunc : { ... *(.RAMFUNC.ISR) *(.RAMFUNC) *(.RAMFUNC*) ... } >RAMFUNC AT> FLASH
  7. Из атрибута, в котором указано, в какой области памяти находится код функции.
  8. Я обязательно разберусь. Просто я на STM32F4 с Миландровского 1986ВЕ1Т пересел. Там обязательно было код записи/стирания флэш-памяти в ОЗУ размещать. Перемещаемой таблицы там не было, потому что Cortex-M0/M1, это я уже сам затеял. Опыта у меня с STM32 мало.
  9. Нет, только страницу с основной программой. Я так и понял, что именно программист должен это гарантировать, вручную разместив все данные и функции, к которым будут обращения, в нужной области памяти.
  10. Я указал секцию, где будет размещена функция, при помощи линкера. В исходнике функции указал, что она размещается именно в этой секции. Затем самостоятельно скопировал код этой функции по соответствующему адресу RAM в стартапе. Что еще я должен сделать, чтобы эта функция разместилась там, где мне нужно?
  11. Верно, сейчас попробовал сделать как посоветовал АНТОХА, и все получилось. Просто вчера я свой вариант успел сделать и протестировать раньше, чем увидел его пост. Спасибо, что обратили мое внимание на это.
  12. Предполагаю стирать/писать флэш-память без запрета прерываний. Раньше я загрузку прошивки на лету ни разу не делал, опыта у меня мало. Сейчас я увидел неудобства, связанные с этим (начинал с Кейла, там гораздо проще делается размещение функций в ОЗУ), возможно в конце концов обойдусь простым запретом прерываний на время стирания/записи. Ну и сами-то функции стирания/записи по-любому придется в ОЗУ размещать. Так что осваивать все равно пришлось бы, пусть и не на примере обработчика.
  13. Нагуглил и сделал следующее (пусть это наверное всем кроме меня известный баян, напишу хотя бы для упорядочивания в своей голове). Объявил новую секцию RAMFUNC для размещения кода нужных мне функций в скрипте линкера. Пока выбрал 8 Кб, отрезав столько же от остальной RAM. MEMORY { CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K RAMFUNC (rx) : ORIGIN = 0x20000000, LENGTH = 8K RAM (xrw) : ORIGIN = 0x20002000, LENGTH = 120K FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 128K } Описание секции между секциями .data и .bss: _siramfunc = LOADADDR(.ramfunc); .ramfunc : { . = ALIGN(4); _sramfunc = .; /* для копирования кода в startup-файле */ *(.RAMFUNC.ISR) *(.RAMFUNC) *(.RAMFUNC*) . = ALIGN(4); _eramfunc = .; /* для копирования кода в startup-файле */ } >RAMFUNC AT> FLASH В startup-файле вписал объявленные ранее переменные и добавил копирование кода по аналогии с уже имеющимся копированием данных .data и .bss. Как уже указывал уважаемый Forger, копировать код функций надо до вызова основной программы: .word _siramfunc .word _sramfunc .word _eramfunc ... CopyCodeRamFunc: ldr r3, =_siramfunc ldr r3, [r3, r1] str r3, [r0, r1] adds r1, r1, #4 LoopCopyCodeRamFunc: ldr r0, =_sramfunc ldr r3, =_eramfunc adds r2, r0, r1 cmp r2, r3 bcc CopyCodeRamFunc bl SystemInit bl main ... После этого осталось только объявить соответствующий атрибут для нужных мне функций. Для целей тестирования я сделал для одной обычной функции (инициализация Systick) и одного обработчика прерывания (того же Systick): __attribute__((section(".RAMFUNC"))) void systick_config(void) { ... } __attribute__((interrupt)) __attribute__((section(".RAMFUNC.ISR"))) void systick_handler_ram(void) { ... } Теперь обработчик работает корректно. Обычная функция тоже. Извините за простыню. Всем спасибо за подсказки.
  14. Подскажите пожалуйста хотя бы название. Что за мануал - на МК, на среду разработки, на сам GCC?