Оглавление.

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 в правильной последовательности иначе картинка не будет соответствовать исходной.