jenya7 0 26 ноября, 2018 Опубликовано 26 ноября, 2018 · Жалоба Я сохраняю системные параметры во внутреннюю память микроконтролера. (STM32F303CB) Собственно функции для записи. FLASH_Status WriteFlash(void* src, void* dst, int len) { uint32_t timeout = 0; uint16_t* srcw = (uint16_t*)src; volatile uint16_t* dstw = (uint16_t*)dst; FLASH_Status status = FLASH_COMPLETE; FLASH->CR |= FLASH_CR_PG; /* Programm the flash */ while (len) { *dstw = *srcw; while ((FLASH->SR & FLASH_SR_BSY) != 0 ) { timeout++; if (timeout > 100000) { status = FLASH_ERROR_PROGRAM; break; } } if (*dstw != *srcw ) { status = FLASH_ERROR_PROGRAM; break; } dstw++; srcw++; len = len - sizeof(uint16_t); } FLASH->CR &= ~FLASH_CR_PG; /* Reset the flag back !!!! */ return status; } FLASH_Status WriteToFlash(uint32_t flash_page) { uint32_t *addr; uint32_t size; uint32_t offset; //uint32_t space_left; FLASH_Status status = FLASH_COMPLETE; //flash unlock if((FLASH->CR & FLASH_CR_LOCK) != RESET) { /* Authorize the FLASH Registers access */ FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY2; } status = FLASH_ErasePage(flash_page); if (status == FLASH_COMPLETE) { size = sizeof(MOTOR_SYS_PARAMS); offset = 0; addr = (uint32_t *)(flash_page + offset); flash_status = WriteFlash(&motor_sys_params, addr, size); size = sizeof(GLOB_MOTOR_DATA); offset += (size + SEPARATOR); addr = (uint32_t *)(flash_page + offset); flash_status = WriteFlash(&glob_mot_data, addr, size); size = sizeof(IR_DATA); offset += (size + SEPARATOR); addr = (uint32_t *)(flash_page + offset); flash_status = WriteFlash(&ir_data, addr, size); size = sizeof(MOTOR_TASK) * MAX_TASKS; offset += (size + SEPARATOR); addr = (uint32_t *)(flash_page + offset); flash_status = WriteFlash(&mot_task, addr, size); } //flash lock FLASH->CR |= FLASH_CR_LOCK; return status; } И потом вызываю команду uint32_t COM_Save(uint32_t argc, char** args) { FLASH_Status status; __disable_interrupt(); status = WriteToFlash(FLASH_PAGE_62); __enable_interrupt(); if (status == FLASH_COMPLETE) Parser_SendString(COM_USART, "Save OK\r", 0); else Parser_SendString(COM_USART, "Save failed\r", 0); return MSG_OK; } Первая проблема – вызвал команду save – получил свой Save OK – рисет – вижу все прописалось. Но если я хочу прописать повторно я падаю на status = FLASH_ErasePage(flash_page); Не удается стереть страницу. Если сделать рисет – все нормально – страница перезаписалась. Первая проблема геморойна, неудобна, но можно жить. Вторая проблема – когда я сказал все прописалось я покривил душой – все кроме WriteFlash(&ir_data, addr, size); Падает на валидации данных if (*dstw != *srcw ) { status = FLASH_ERROR_PROGRAM; break; } ir_data ничем не страшнее других прописываемых структур typedef struct { uint8_t show; uint8_t bits; uint8_t protocol; uint8_t res; uint8_t action[4]; uint32_t code [4]; uint32_t debounce_time; }IR_DATA; IR_DATA ir_data; Думал битая страница (62). Поменял (63) – то же самое, обе проблемы присутствуют. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 26 ноября, 2018 Опубликовано 26 ноября, 2018 · Жалоба Вы пилите сук на котором сидите: функции для изменения содержимого Flash должны размещаться в другой памяти (ОЗУ, внешней памяти, другом банке Flash, если банков хотя бы два). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 26 ноября, 2018 Опубликовано 26 ноября, 2018 (изменено) · Жалоба 33 minutes ago, Forger said: Вы пилите сук на котором сидите: функции для изменения содержимого Flash должны размещаться в другой памяти (ОЗУ, внешней памяти, другом банке Flash, если банков хотя бы два). достаточно поставить перед функцией __ramfunc ? И все же я не думаю что это причина проблемы. Я помню проекты где функции лежали во флеш и тем не менее все работало. или возьмем бутлоадер к примеру - он сидит в одной области флеша и пишет в другую. Изменено 26 ноября, 2018 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 26 ноября, 2018 Опубликовано 26 ноября, 2018 · Жалоба 44 minutes ago, jenya7 said: достаточно поставить перед функцией __ramfunc ? Не достаточно, подробности читайте в мануале на ваш компилятор/линкер. Quote И все же я не думаю что это причина проблемы. Профи опирается только факты, а всякие "думаю", "раньше работало" и т. п. - это все домыслы ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 57 26 ноября, 2018 Опубликовано 26 ноября, 2018 · Жалоба 2 часа назад, jenya7 сказал: достаточно поставить перед функцией __ramfunc ? Есть такой Application note AN4296 Overview and tips for using STM32F303/328/334/358xx CCM RAM with IAR EWARM, Keil MDK-ARM and GNU-based toolchains Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 26 ноября, 2018 Опубликовано 26 ноября, 2018 · Жалоба 23 minutes ago, HardEgor said: Есть такой Application note AN4296 Overview and tips for using STM32F303/328/334/358xx CCM RAM with IAR EWARM, Keil MDK-ARM and GNU-based toolchains спасибо. документ объясняет как положить функции в РАМ. но не решает мою проблему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 26 ноября, 2018 Опубликовано 26 ноября, 2018 · Жалоба 2 hours ago, jenya7 said: достаточно поставить перед функцией __ramfunc ? И все же я не думаю что это причина проблемы. Я помню проекты где функции лежали во флеш и тем не менее все работало. или возьмем бутлоадер к примеру - он сидит в одной области флеша и пишет в другую. Я бы посмотрел для начала на карту памяти. Коллега Forger прав. Заморочки с размещением функций работы с флэш именно в ОЗУ для STM32 не обязательны (EFM32 - другое дело). До сих пор мои проекты работали с функциями во флэше, сами находясь, конечно же, не в странице, которая перезаписывается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 26 ноября, 2018 Опубликовано 26 ноября, 2018 (изменено) · Жалоба 24 minutes ago, KnightIgor said: Я бы посмотрел для начала на карту памяти. Коллега Forger прав. Заморочки с размещением функций работы с флэш именно в ОЗУ для STM32 не обязательны (EFM32 - другое дело). До сих пор мои проекты работали с функциями во флэше, сами находясь, конечно же, не в странице, которая перезаписывается. так Quote Коллега Forger прав. или Quote Заморочки с размещением функций работы с флэш именно в ОЗУ для STM32 не обязательны До сих пор мои проекты работали с функциями во флэше давайте уже определимся. Конструктивный разбор полетов будет? Память смотрю. Все структуры прописаны кроме той которая не прописана. И почему нужно делать рисет чтоб прописать страницу заново? Изменено 26 ноября, 2018 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 26 ноября, 2018 Опубликовано 26 ноября, 2018 · Жалоба Функции записи во flash можно размещать в самой flash и даже на той же странице, куда пишем (только смысл?). Однако, стирание и, например, перевод flash в спячку требуют запуска этих функций уже из другой памяти. Для примера откройте исходники на готовые библиотеки для работы с flash. Это нужно делать в первую очередь, когда пытаетесь самостоятельно работать с железом через регистры, но при этом же избегаете читать даташиты. Короче, хоть это и банально прозвучит, но все же RTFM ;) 8 minutes ago, jenya7 said: И почему нужно делать рисет чтоб прописать страницу заново? Походу, вы - первый кто так делает :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 26 ноября, 2018 Опубликовано 26 ноября, 2018 · Жалоба 10 minutes ago, Forger said: Однако, стирание и, например, перевод flash в спячку требуют запуска этих функций уже из другой памяти. У меня бутлодер сидит в той же памяти которую стирает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 26 ноября, 2018 Опубликовано 26 ноября, 2018 (изменено) · Жалоба 26 minutes ago, jenya7 said: давайте уже определимся. Я имел ввиду, что коллега прав по поводу сука. Далее он предложил НЕСКОЛЬКО вариантов, два из них: размещение функций в ОЗУ или в другом банке флэш. Я уточнил, что размещение в ОЗУ для STM32 (в отличие от EFM32) не является обязательным, можно оставить во флэш, просто в другой странице (даже не банке, если стирать постранично, что Вы и делаете, вроде). В желании Вам помочь и разобраться, я просматриваю мой нынешний рабочий код, которому уже много лет, и слабо вспоминаю, что вначале я тоже сталкивался с похожей проблемой. P.S. Вот у меня нашел такое: FLASH_Unlock(); FLASH_ClearFlag (FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR); // Clear All pending flags Возможно, нужно сбросить флаги с предыдущей операции. Может это объясняет, почему первая запись после сброса у Вас работает, а последующие нет, хотя сам факт записи имел место. Изменено 26 ноября, 2018 пользователем KnightIgor Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 26 ноября, 2018 Опубликовано 26 ноября, 2018 · Жалоба 12 minutes ago, KnightIgor said: Я имел ввиду, что коллега прав по поводу сука. Далее он предложил НЕСКОЛЬКО вариантов, два из них: размещение функций в ОЗУ или в другом банке флэш. Я уточнил, что размещение в ОЗУ для STM32 (в отличие от EFM32) не является обязательным, можно оставить во флэш, просто в другой странице (даже не банке, если стирать постранично, что Вы и делаете, вроде). В желании Вам помочь и разобраться, я просматриваю мой нынешний рабочий код, которому уже много лет, и слабо вспоминаю, что вначале я тоже сталкивался с похожей проблемой. P.S. Вот у меня нашел такое: FLASH_Unlock(); FLASH_ClearFlag (FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR); // Clear All pending flags Возможно, нужно сбросить флаги с предыдущей операции. Может это объясняет, почему первая запись после сброса у Вас работает, а последующие нет, хотя сам факт записи имел место. О! Вот это слова не мальчика но мужа! Я почти уверен что в этом проблема. У меня забрали все переходники не могу проверить сейчас. Я конечно учту замечания Forger и перенесу ф-ции в РАМ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 26 ноября, 2018 Опубликовано 26 ноября, 2018 · Жалоба 30 minutes ago, jenya7 said: У меня бутлодер сидит в той же памяти которую стирает. Надо же и у меня тоже! Но в моем случае все сразу заработало с полпинка и сразу так, как надо. Наверно, просто повезло, а чтение даташитов и разбор чужих рабочих исходников (в частности на SPL от ST) тут вообще ни причем :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 26 ноября, 2018 Опубликовано 26 ноября, 2018 · Жалоба Вспомнил один важный момент - писать во флэш нужно целыми 32-битными словами, причем источник данных должен быть выровнен по границе этого слова! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 26 ноября, 2018 Опубликовано 26 ноября, 2018 (изменено) · Жалоба 12 minutes ago, Forger said: Надо же и у меня тоже! Но в моем случае все сразу заработало с полпинка и сразу так, как надо. Наверно, просто повезло, а чтение даташитов и разбор чужих рабочих исходников (в частности на SPL от ST) тут вообще ни причем :) Так я пользуюсь SPL-вскими ф-циями. Но они не прописаны в рам. Скажем, как правильно заметил KnightIgor, у EFM32 все библиотечные ф-ции использующие флеш имеют #pragma arm section code="ram_code". 7 minutes ago, Forger said: Вспомнил один важный момент - писать во флэш нужно целыми 32-битными словами, причем источник данных должен быть выровнен по границе этого слова! 32? а в примерах half-word - 16 бит. WriteFlash я взял из их примера - там приводиться к (uint16_t*). Изменено 26 ноября, 2018 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться