LAS9891 0 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба Есть у меня проект на GD32F103RBT6. При работе со стиранием/записью во FLASH по началу проблем не было, но потом после стирания/записи FLASH контроллер стал вести себя неадекватно. Перестал отвечать на запросы по CAN, но не после каждого цикла стирания/записи, а как то раз через раз, непостоянно короче. При работе в Debuggere эту ситуацию вообще не удаётся отловить. И тут я вспомнил слово LATENCY, и что её надо настраивать в соответствии с CK_SYS. Так было для STM, а в UserManual на GD, в разделе Flash Memory Controller (FMC) вообще нет слова LATENCY, но есть описание похожего регистра Wait state register (FMC_WS). Далее я нашёл статью. В ней описана моя ситуация, как настраивать эту самую LATENCY для GD. У меня CK_SYS = 108 MHz и я написал так: //---Variables---// uint32_t temp = 0; uint32_t *FMC_WSEN_ADDR = (uint32_t*)0x400220FC; //---------------// //fmc_unlock(); FMC_KEY0 = UNLOCK_KEY0; FMC_KEY0 = UNLOCK_KEY1; FMC_KEY1 = UNLOCK_KEY0; FMC_KEY1 = UNLOCK_KEY1; *FMC_WSEN_ADDR = (uint32_t)1; // ПИШЕМ 1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! temp = RCU_ClockFreq_Get(CK_SYS); if(temp <= 24000000) FMC_WS = WS_WSCNT_0; // Wait state counter: 0 wait state added. else if ( (temp > 24000000) && (temp <= 48000000)) FMC_WS = WS_WSCNT_1; // Wait state counter: 1 wait state added. else // if temp > 48000000 FMC_WS = WS_WSCNT_2; // Wait state counter: 2 wait state added. fmc_lock(); temp = FMC_WSEN; // ТУТ ВСЕГДА 0, ХОТЯ ДОЛЖНО БЫТЬ 1!!!!!!!!!!!!!!!!!!!!!!!!! Значение LATENCY устанавливается в регистре FMC_WS. Я это вижу, но вот логическая единица в регистре FMC_WSEN не устанавливается, ни в отладчике, ни без него, ни с задержками во всех местах, ни без них. А она нужна, потому что только когда она есть wait state added when fetch flash. Что я делаю не так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 163 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба Как минимум это uint32_t *FMC_WSEN_ADDR = (uint32_t*)0x400220FC; переписать в это uint32_t volatile *FMC_WSEN_ADDR = (uint32_t *)0x400220FC; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба 35 minutes ago, Arlleex said: uint32_t volatile *FMC_WSEN_ADDR = (uint32_t *)0x400220FC; не помогло Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 133 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба Для GD32 latency не существует, потому что у него флешь выполнена отдельным кристаллом, в момент включения копируется в теневое ОЗУ и далее вся работа идет с ОЗУ. Это из описания F407: И этот long delay никак не регулируется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 163 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба Возможно еще, что бит этот хоть и 'rw', но на чтение всегда 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба 15 minutes ago, Сергей Борщ said: И этот long delay никак не регулируется. Тогда и настраивать не нужно или как? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 133 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба 37 минут назад, LAS9891 сказал: Тогда и настраивать не нужно или как? Не нужно. В документации больше нигде эти биты не встречаются, каковы критерии выбора того или иного значения - не описано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба 12 minutes ago, Сергей Борщ said: Не нужно. В документации больше нигде эти биты не встречаются, каковы критерии выбора того или иного значения - не описано. Жаль, я думал в этом был баг. Сейчас осталось предположение, что проблемы с FLASH были из-за другого. В проекте использую ОС Keil_RTX5 c вытесняющей многозадачностью. Все потоки имеют равный приоритет. Есть предположение, что во время стирания/записи FLASH, возникает прерывание планировщика, и из-за него с записью возникают глюки. Пока вычитал такой способ обезопасить работу с FLASH: uint32_t lock_state = 0; /* ... */ lock_state = osKernelLock(); // Lock the RTOS Kernel scheduler. WriteFlashStatus = Write_Words_to_flash(GetConfigAddress(), sizeof(Config_struct)/4, (uint32_t*)(pConfig)); // Запись во FLASH. osKernelRestoreLock(lock_state); // Restore the RTOS Kernel scheduler lock state. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 25 ноября, 2023 Опубликовано 25 ноября, 2023 · Жалоба 3 hours ago, Сергей Борщ said: Не нужно. и зачем тогда эти регистры нужны вообще? надо че с ними делать или нет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться