Оглавление.
1. STM32F303 Перестало работать ПО (загрузчик+прикладное) или побочный эффект оптимизации компилятора.
2. STM32H743 - SDRAM не хочет работать.
3. STM32H743 - DCMI + JPEG сжатие картинки.
STM32F303 Перестало работать ПО (загрузчик+прикладное) или побочный эффект оптимизации компилятора.
Переносил проект с STM32F091 на STM32F303.
Софт позволяет проводить обновление ПО и состоит из двух независимых программ.
1 - загрузчик запускается первым и проверяет все что необходимо (наличие новой прошивки, саму прикладную прошивку на корректность и т.п.).
2 - прикладное ПО.
Выяснилось что после передачи управления загрузчиком прикладному ПО ядро попадает в исключение так и не дойдя до main().
Исключение происходило в функции init() начальной настройки ПО (обнуление памяти, копирование из FLASH в RAM и т.п.).
Переход на прикладное ПО стандартный, и выглядит так:
SCB->VTOR = FW_APP_ADDR; // Указываем местоположение таблицы векторов основной прошивки
// Устанавливаем новый указатель стека для основной программы, значение берем из
// таблицы векторов основной программы
__set_MSP( *(__IO uint32_t*) FW_APP_ADDR );
// Получаем адрес перехода из таблицы векторов со смещением 4
JumpAddress = *(__IO uint32_t*) (FW_APP_ADDR + 4);
Jump_To_Application = (pFunction) JumpAddress;
Jump_To_Application(); // JMP to APP
}
Пришлось разбираться и лезть в ассемблер.
Теория:
1. При входе в подпрограмму в стек сохраняются используемые регистры процессора в данной подпрограмме.
2. При выходе из подпрограммы регистрам возвращается их значение до входа в подпрограмму, т.е. извлекаются из стека.
Компилятор (IAR ARM) при оптимизации (None или Low) располагает код в следующей последовательности:
1. Jump_To_Application(); // JMP to APP - переход на прикладное ПО.
2. Затем извлечение регистров.
Собственно регистры и не извлекаются т.к. вершина стека уже настроена на новое значение из прикладного ПО,
и после перехода на прикладное ПО сюда уже программа больше не попадает.
Если включить оптимизацию (Medium или High) то оптимизатор переставляет местами:
1. Сначала восстанавливаются регистры,
2. Затем происходит переход на прикладное ПО, Jump_To_Application(); // JMP to APP
В результате происходит изменение указателя стека прикладного ПО !!! и позже в функции init() происходит исключение т.к.
происходит обращение за пределы памяти....
STM32H743 - SDRAM не хочет работать.
Купил плату SK-STM32H743 (starterkit.ru) на основе STM32H743.
Подымаю периферию контроллера.
STM32CUBE использую только как подсказку чтоб посмотреть настройки тактовых сигналов и сгенерить проект.
Дальше заголовочный файл (stm32h743.h) документацию и на регистрах...
Компилятор IAR. Все идет по плану, дошел до настройки SDRAM.
Не работает SDRAM как не крути... Все что можно перепробовал.
Тест что загружен в кит работает, мой нет...
До этого подымал SDRAM на stm32f746 и все работало, тут нет... хотя изменения минимальные...
Сравнивал значения в регистрах настроек, даже в регистры теже значения загрузил, SDRAM читает с ошибками и все тут...
Заметил особенность, что если загрузить прошивку от производителя, а потом мою без выключения питания, то все работает.
Пришел к выводу что мой софт не прогружает в микросхему SDRAM Load Mode Register...
Оказалось ошибка в битовых полях в файле stm32h743.h и во всех заголовочных файлах линейке тоже....
FirmwarePackage=STM32Cube FW_H7 V1.7.0
/****************** Bit definition for FMC_SDCMR register ******************/
#define FMC_SDCMR_MODE_Pos (0U)
#define FMC_SDCMR_MODE_Msk (0x7UL << FMC_SDCMR_MODE_Pos) /*!< 0x00000007 */
#define FMC_SDCMR_MODE FMC_SDCMR_MODE_Msk /*!<MODE[2:0] bits (Command mode) */
#define FMC_SDCMR_MODE_0 (0x1UL << FMC_SDCMR_MODE_Pos) /*!< 0x00000001 */
#define FMC_SDCMR_MODE_1 (0x2UL << FMC_SDCMR_MODE_Pos) /*!< 0x00000002 */
#define FMC_SDCMR_MODE_2 (0x3UL << FMC_SDCMR_MODE_Pos) /*!< 0x00000003 */
Обратите внимание на FMC_SDCMR_MODE_2, должно быть:
#define FMC_SDCMR_MODE_2 (0x4UL << FMC_SDCMR_MODE_Pos) /*!< 0x00000004 */
Исправил и все заработало !
Часть исходников на github.com
STM32H743 - DCMI + JPEG сжатие картинки.
Самый простой блок в STM32 это DCMI, DCMI + DMA настаивается и работает.
Захватывает изображение построчно и сохраняет в памяти.
А вот JPEG модуль имеет следующие особенности:
Модуль принимает на вход НЕ СТРОКИ изображения, а блоки 8х8 пикселей.
Т.е. весь кадр разбивается на блоки(квадраты) 8х8 и производится последовательная загрузка блоков в JPEG:
1 строка - 8 пикселей,
2 строка - 8 пикселей,
3 строка - 8 пикселей,
4 строка - 8 пикселей,
5 строка - 8 пикселей,
6 строка - 8 пикселей,
7 строка - 8 пикселей,
8 строка - 8 пикселей,
Затем следующий блок и т.д. .....
Сжатие можно производиться только после того как будут получены первые 8 строк !
Но это еще не все ! Данные должны быть поданы в модуль JPEG в правильной последовательности иначе картинка не будет соответствовать исходной.