Jump to content

    

Запись во FLASH.

11 minutes ago, jenya7 said:

Но они не прописаны в рам.

Все верно, это нужно делать руками при сборке проекта, о чем указано в самой библиотеке, в частности непосредственно в названии самого файла: "stm32l1xx_flash_ramfunc.c".

 

Далее осталось лишь открыть файл любым текстовым редактором и прочитать его шапку:

/**
  ******************************************************************************
  * @file    stm32l1xx_flash_ramfunc.c
  * @author  MCD Application Team
  * @version V1.3.1
  * @date    20-April-2015
  * @brief   This file provides all the Flash firmware functions which should be
  *          executed from the internal SRAM. This file should be placed in 
  *          internal SRAM. 
  *          Other FLASH memory functions that can be used from the FLASH are 
  *          defined in the "stm32l1xx_flash.c" file. 
@verbatim

    *** ARM Compiler ***
    --------------------
    [..] RAM functions are defined using the toolchain options. 
         Functions that are be executed in RAM should reside in a separate
         source module. Using the 'Options for File' dialog you can simply change
         the 'Code / Const' area of a module to a memory space in physical RAM.
         Available memory areas are declared in the 'Target' tab of the 
         Options for Target' dialog.

    *** ICCARM Compiler ***
    -----------------------
    [..] RAM functions are defined using a specific toolchain keyword "__ramfunc".

    *** GNU Compiler ***
    --------------------
    [..] RAM functions are defined using a specific toolchain attribute
         "__attribute__((section(".data")))".

    *** TASKING Compiler ***
    ------------------------
    [..] RAM functions are defined using a specific toolchain pragma. This 
         pragma is defined inside this file.

 

Специально для вас цитирую нужное:

 

This file provides all the Flash firmware functions which should be executed from the internal SRAM. This file should be placed in internal SRAM.

 

 

Share this post


Link to post
Share on other sites
17 minutes ago, Forger said:

Все верно, это нужно делать руками при сборке проекта, о чем указано в самой библиотеке, в частности непосредственно в названии самого файла: "stm32l1xx_flash_ramfunc.c".

Далее осталось лишь открыть файл любым текстовым редактором и прочитать его шапку:

Специально для вас цитирую нужное:


This file provides all the Flash firmware functions which should be executed from the internal SRAM. This file should be placed in internal SRAM.

 

 

Спасибо. У меня в STM32F30x_StdPeriph_Driver нет файла _ramfunc. Соэдать самому секцию и пометить все ф-ции прагмой? А какой размер секции выбрать? Не хотелось отжирать лишний РАМ его и так не много.

Share this post


Link to post
Share on other sites
32 minutes ago, jenya7 said:

Так я пользуюсь SPL-вскими ф-циями. Но они не прописаны в рам. Скажем, как правильно заметил KnightIgor, у EFM32 все библиотечные ф-ции использующие флеш имеют #pragma arm section code="ram_code".

 

 

32? а в примерах half-word - 16 бит.

WriteFlash я взял из их примера - там приводиться к (uint16_t*).

 

В мануале (правды ради - для моих F051 и F103, влом скачивать для F3xx, но вроде у всех одинаково :blush:) действительно сказано:

"The Flash memory can be programmed 16 bits (half words) at a time.". Не помню, откуда ходит "байка" о 32-битах. Возможно, для других типов процессоров (NXP?). Ага, для EFM32 писать именно по 32 бита выровненно.

Share this post


Link to post
Share on other sites
26 minutes ago, jenya7 said:

Спасибо. У меня в STM32F30x_StdPeriph_Driver нет файла _ramfunc. Соэдать самому секцию и пометить все ф-ции прагмой? А какой размер секции выбрать? Не хотелось отжирать лишний РАМ его и так не много.

Совет: не заморачивайтесь с размещением в ОЗУ. В этом нет жесткой необходимости, ОЗУ и вправду мало, требует массу телодвижений, и т.д. Я уверен, что получится из флэша, иначе у меня бы не работало бы эти последние годы. Просто нужно подсуетиться разместить перезаписываемые данные в отдельной странице флэш, которая ни для чего более не используется.

Edited by KnightIgor

Share this post


Link to post
Share on other sites
33 minutes ago, jenya7 said:

STM32F30

Не обратил внимания, что у вас семейство F3 :( , а для них действительно не требуется размещение в ОЗУ. Все сделано проще, на время обращения останавливается доступ к флэш всего, что может к ней обращаться. 

Перед очередной операцией нужно проверять флаги состояний от предыдущей операции и сбрасывать возможные несброшенные ошибки. Возможно, дело в этом.


 

Share this post


Link to post
Share on other sites
6 minutes ago, KnightIgor said:

Совет: не заморачивайтесь с размещением в ОЗУ. В этом нет жесткой необходимости, ОЗУ и вправду мало, требует массу телодвижений, и т.д. Я уверен, что получится из флэша, иначе у меня бы не работало бы эти последние годы. Просто нужно подсуетиться разместить перезаписываемые данные в отдельной странице флэш, которая ни для чего более не используется.

 

 а у вас запись одного блока во флэш или кусками? в EFM32  у меня была одна большая структура и я ее одним куском писал. а тут я несколько прописываю по кускам.

Share this post


Link to post
Share on other sites
11 minutes ago, Forger said:

Не обратил внимания, что у вас семейство F3 :( , а для них действительно не требуется размещение в ОЗУ. Все сделано проще, на время обращения останавливается доступ к флэш всего, что может к ней обращаться. 

Перед очередной операцией нужно проверять флаги состояний от предыдущей операции и сбрасывать возможные несброшенные ошибки. Возможно, дело в этом.

Для F3 как раз нужно записывать кратно 16-битным словам: 

The main Flash memory can be programmed 16 bits at a time. The program operation is
started when the CPU writes a half-word into a main Flash memory address with the PG bit
of the FLASH_CR register set. Any attempt to write data that are not half-word long will
result in a bus error generating a Hard Fault interrupt

 

это скорее всего первая проблема. может упаковать структуру в 16 бит ( #pragma pack(2) ) ?  тогда и вторая отпадет?

Edited by jenya7

Share this post


Link to post
Share on other sites
25 minutes ago, jenya7 said:

 а у вас запись одного блока во флэш или кусками? в EFM32  у меня была одна большая структура и я ее одним куском писал. а тут я несколько прописываю по кускам.

Вообще, у меня исторически "навороченный" собственный HAL, который сводит все к функции вроде flash(source*, const *destination, size), которая мне пишет данные любого (разумного) размера, вплоть до побайтно, во флэш, причем я могу писать через границы страниц. Безусловно, я копирую всю страницу флэш в ОЗУ, модифицирую данные в ОЗУ и переписываю страницу флэш целиком назад. Такой подход позволяет мне объявлять в коде константы (настроек) в виде скалярных переменных или массивов и структур, которые используются в коде ну как обычно. Например,
 

const float ADC_Coeff ATS(_SECTION_PARAMS_) = 1.0;

...

{

    return 2.0 * ADC_Coeff * ADC_ValueToVoltageRef(ADC_Values[ADC_ACCU_INDEX], ADC_VDDA());

}

Во всем этом присутствуют неизбежные трюки:

1. мое макро ATS() собирает все такие константы в одну секцию (_SECTION_PARAMS_ это строка вроде "MySetting")

2. скаттерный файл компоновщика в проекте размещает такую секцию в требуемую мне страницу флэш, исключая пересечение данных с кодом.

 

Вы можете сказать, я тут рекомендую не заморачиваться с размещением функций в ОЗУ, а сам замутил хардкор? Ну, сначала единовременная инвестиция, а потом удобство использования в любом проекте как copy&paste. Мне нужна структура сложных настроек, которая иногда должна модифицироваться извне? Я объявляю константную структуру как обычно, юзаю ее в коде как обычно. И иногда пишу в нее с помощью flash(source*, const *destination, size). В этом мое удобство и общность решения.

Edited by KnightIgor

Share this post


Link to post
Share on other sites

Первая проблема таки решилась обнулением флагов. Над второй бьюсь как рыба об стол. Пробовал менять структуры местами. Та же проблема - все прописываются кроме ir_data.

Edited by jenya7

Share this post


Link to post
Share on other sites
1 hour ago, jenya7 said:

Первая проблема таки решилась обнулением флагов. Над второй бьюсь как рыба об стол. Пробовал менять структуры местами. Та же проблема - все прописываются кроме ir_data.

 

Грубое обнуление флагов - не есть надежное решение.

Перед каждой операцией стирания/записи во флэш проверяйте ее флаги, после  - тоже желательно проверять не было ли ошибок записи.

 

Share this post


Link to post
Share on other sites
2 hours ago, Forger said:

Грубое обнуление флагов - не есть надежное решение.

Перед каждой операцией стирания/записи во флэш проверяйте ее флаги, после  - тоже желательно проверять не было ли ошибок записи.

 

Мне всегда интересно, как в небольшой системе с, как правило, отсутствием интерфейса к пользователю типа "keyboard not found, press any key to continue", можно разумно восстановться после такой ошибки как ошибка записи во флэш? Вот обнаружил человек не тот бит, что ожидался. Делать что? Ставить ноги в какое-то безопасное состояние и уходить в бесконечный цикл в надежде, что дядя придёт и увидит, что всё умерло?

Я не о том, что нужно "забить" на всё, но реально возможности сделать "recovery" после ошибки записи во флэш, да и любых других подобных, в таких системах очень ограничены. Напишите, кто как выкручивается?

Edited by KnightIgor

Share this post


Link to post
Share on other sites
1 hour ago, KnightIgor said:

Мне всегда интересно, как в небольшой системе с, как правило, отсутствием интерфейса к пользователю типа "keyboard not found, press any key to continue", можно разумно восстановться после такой ошибки как ошибка записи во флэш? Вот обнаружил человек не тот бит, что ожидался. Делать что? Ставить ноги в какое-то безопасное состояние и уходить в бесконечный цикл в надежде, что дядя придёт и увидит, что всё умерло?

Я не о том, что нужно "забить" на всё, но реально возможности сделать "recovery" после ошибки записи во флэш, да и любых других подобных, в таких системах очень ограничены. Напишите, кто как выкручивается?

 

Две страницы. С одной читаем, другой дублируем. :)

Share this post


Link to post
Share on other sites
1 hour ago, KnightIgor said:

Мне всегда интересно, как в небольшой системе с, как правило, отсутствием интерфейса к пользователю типа "keyboard not found, press any key to continue", можно разумно восстановться после такой ошибки как ошибка записи во флэш? Вот обнаружил человек не тот бит, что ожидался. Делать что? Ставить ноги в какое-то безопасное состояние и уходить в бесконечный цикл в надежде, что дядя придёт и увидит, что всё умерло?

Я не о том, что нужно "забить" на всё, но реально возможности сделать "recovery" после ошибки записи во флэш, да и любых других подобных, в таких системах очень ограничены. Напишите, кто как выкручивается?

 

Я храню пользовательские настройки в EEPROM (встроенная или на край внешняя копеечная), всегда настройки сопровождаются контрольной суммой.

Flash для этого, ихмо, плохо подходит.

При каждом сбросе пользовательские настройки вычитываются и ВСЕГДА проверяется их контрольная сумма. В случае несовпадения восстанавливаются настройки по-умолчанию (хранятся во flash как const) и пытаемся обновить поврежденные настройки в EEPROM.

Сама прошивка перед передачей ей управления проверяется на целостность контрольной суммой самим бутлоадером при КАЖДОМ включении.

Если прошивка битая, то всегда сидим в бутлоадере, ждем новую прошивку. Битую прошивку не запускаем, рисковать не хотим ))

Разумеется, что пппаратно само изделие должно притягивать все используемые внешние пины к нужным уровням, т.е. если зависли в бутлоадере в ожидании новой прошивки, то никакие моторы/агрегаты и т.п. не должны самопроизвольно включаться!

 

 

Share this post


Link to post
Share on other sites
37 minutes ago, Forger said:

Я храню пользовательские настройки в EEPROM (встроенная или на край внешняя копеечная), всегда настройки сопровождаются контрольной суммой. Flash для этого, ихмо, плохо подходит.

Я придерживаюсь противоположного мнения: именно флэш ультимативно удобна и надежна для хранения настроек.

Аргументы:

- внешние устройства хранения есть дополнительные компоненты, для них нужно место, к ним требуются шины коммуникации, которые занимают пины и могут сбоить; подвешивание автоматов I2C EEPROM общеизвестно.

- требуется ощутимое время на считывание из внешних хранителей.

- настройки извне надо копировать в ОЗУ, а в микроконтроллерах его,  как правило, ощутимо меньше, чем флэш;

- размещение параметров во флэш позволяет использовать их непосредственно как константы в выражениях кода.

- флэш надежнее; если это опровергать, нужно смириться и с тем, что и сама прошитая программа ненадежна, к чему ей тогда настройки вообще, когда она рухнет?

 

P.S. У нас есть объекты, на которых работают контроллеры 8051, первые с флэш (до этого были с EPROM, стираемые UV), c... 1997! Там все на свете гарантии прошли, мы несколько раз сменяли PC (речь о распределенном управлении отоплением в коммунальных зданиях с центральным PC), а модулики работают! Мы сами в позитивном шоке. Так вот, там настройки хранятся в I2C EEPROM, т.к. тогда самопрограммирования флэша еще не было. И вот было несколько сбоев недавно. Мы проверили, и оказалось, что именно содержимое EEPROM потерялось. Мы перезалили EEPROM, и модули поскакали дальше. Заменить/обновить их не можем, т.к. их нет у нас больше на складе, да и сами процессоры такие не купишь. А старые процессоры еще могут! Спасибо, TEMIC и ATMEL!

 

P.P.S. Ностальгия пробила, порылся в коробках, нашел такой модуль (см. фото). Вверху на плате дата разработки стоит: 18.09.96. Под кварцем видна EEPROM в SO8.

20181127_130128.jpg

Edited by KnightIgor

Share this post


Link to post
Share on other sites
29 minutes ago, Forger said:

Я храню пользовательские настройки в EEPROM (встроенная или на край внешняя копеечная), всегда настройки сопровождаются контрольной суммой.

Flash для этого, ихмо, плохо подходит.

В той же EEPROM настройки должны быть в двух экземплярах, чтобы быть готовым к отключению питания во время записи. Если делать по уму, получится не сильно проще, чем во флеше.

Во флеше можно устроить "эмуляцию EEPROM". Там легко накосячить, конечно, но не сильно сложнее, чем правильная работа с EEPROM.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now