ARM. Учебный курс

До того, как ARM купила компанию Keil , лучшими практически по всем показателям были компиляторы от IAR Systems . Сейчас ситуация выровнялась и по некоторым тестам компилятор от Keil даже превосходит компилятор от IAR. Но тем, кто привык работать в IAR нет большого смысла осваивать новую среду.

Миландр предоставляет файлы поддержки своих микроконтроллеров для среды IAR, но подключение этих библиотек не так очевидно, как в случае PACK для Keil. Эта статья будет посвящена тому, как начать работать с микроконтроллерами Миландр в среде IAR. Напишем обычный "HelloWorld", то есть помигаем светодиодами.

Создастся проект с пустой реализацией функции main. Откроем опции проекта и настроим его под конкретный микроконтроллер, выбираем пункт меню или жмем Alt+F7. Далее приведу только те опции, которые необходимо поменять, все остальное остается по умолчанию. По вкладкам:

General Options

Выбираем наш микроконтроллер, 1986ВЕ92У относится к группе 1986ВЕ9х.

Output Converter

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

Linker

Здесь необходимо выбрать файл задающий раскладку памяти для МК. Этот файл MDR32F1.icf мы копировали ранее при установке SPL. Определение $TOOLKIT_DIR$ как раз содержит путь к директории установки, в которую мы копировали папки Milandr.

C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0\arm\config\flashloader\Milandr\MDR1986VE9х\MDR32F1.icf

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

Debugger

В закладке Setup необходимо выбрать наш отладчик, J-link уже присутствует в списке, выбираем его. Отладчика Ulink2 нет в списке, видимо необходимо ставить дополнительно. Кроме этого необходимо выбрать приведенные на картинке ниже файлы FlashMDR32F1x.mac и jbr_1986BE9x.ddf , которые мы так же копировали при установке SPL.

C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0\arm\config\flashloader\Milandr\MDR1986VE9х\FlashMDR32F1x.mac
C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0\arm\config\debugger\Milandr\MDR1986VE9х\jbr_1986BE9x.ddf

В следующей закладке Download выставляем опции "Verify download" и выбираем файл загрузчика FlashMDR32F1x.board , который загружает нашу программу в микроконтроллер. Это аналог flm файла в среде Keil.

C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0\arm\config\flashloader\Milandr\MDR1986VE9x\FlashMDR32F1x.board

J-Link/J-Trace

В данном окне выставим опции аналогичные тем, что мы выставляем для данного отладчика в среде Keil. Укажем стартовую частоту микроконтроллера 8МГц и выставим Reset Pin. Далее можно выбрать использование Jtag или SWD, а так же увеличить скорость подключения, но мне сейчас это не критично, поэтому оставил по умолчанию.

После внесения изменений, да и вообще периодически, полезно нажимать кнопку Save All. При первом сохранении IAR предложит сохранить Workspace текущего проекта, сохраняем под таким же "HelloWord"-ом. При следующих запусках среды выбираем File - Recent Workspaces и IDE открывается в состоянии в котором мы ее оставили.

Организация папок проекта и SPL

При организации проекта я руководствовался данной статьей IAR EWARM. Создание проекта часть 2. CMSIS и Standard Peripherals Library.

Полагаясь на рекомендации статьи раскладывать исходники по папочкам, я завел группы аналогично тем, что создает Keil по умолчанию - Startup и Driver. Приведу сразу конечный вид дерева проекта и выпадающее меню, показывающее как создавать группу.

Согласно статье, я так же создал отдельную папку src и положил туда файл main.c. Для такого маленького и простого примера это не столь важно, но будем вырабатывать правильный стиль.

Теперь необходимо подключить сами библиотеки SPL позволяющие работать с периферией микроконтроллера. Во многих статьях в интернет необходимые файлы библиотек копируются в папку проекта на диске и затем подключаются в IAR. Мне такое решение не показалось удобным, поэтому я решил разместить библиотеку по стационарному адресу и подключать во всех проектах файлы из единого источника. Плюс данного решения в том, что при исправлении ошибки в общих исходниках, изменение проявится во всех связанных с библиотекой проектах. Потребуется только перекомпиляция. Если же в каждый проект копировать подборку необходимых исходников, то придется в каждый проект вносить исправления. Но тут каждый решает для себя как ему удобнее организовывать код. Зачастую изменение в общем коде, может затронуть уже старый, готовый и работающий проект. В таком случае, проект "ушедший в продакшн" лучше "заморозить" в текущем состоянии, собрав для него все исходники отдельно.

В итоге директории на диске я организовал следующим образом, есть одна общая папка IAR_CODE в которой лежит папка SPL и по папке для каждого микроконтроллера, внутри которых создаются отдельные проекты. Проекты используют исходники SPL, которые подключаются относительными путями от папки проекта. Использование абсолютных путей сделает проект непереносимым в другое место, поэтому пути лучше использовать относительные. При переносе или копировании проекта куда-то, необходимо будет скопировать проект и папку SPL, сохраняя их относительное расположение. Тогда проект будет успешно собираться из другого места.

Здесь приведены директории и файлы которые будут использоваться в нашем проекте.

IAR_CODE\ - Общая папка с проектами в IAR 1986VE9x\ - папка проектов под 1986VE9x MDR32F9Qx_board.h - файл выбора МК и ревизии HelloWorld - папка проекта SPL\ - папка SPL MDR32F9Qx_config.h - файл прочих настроек CMSIS\ CM3\ CoreSupport - поддержка ядра DeviceSupport\MDR32F9Qx\ - startup файлы inc startup\iar MDR32F9Qx_StdPeriph_Driver\ - driver файлы inc src

Чтобы получилась такая раскладка, вот что нужно скопировать из архива SPL:

В папку IAR_CODE\SPL: Исходные файлы SPL lib\MDR32F9_1986ВЕ4_2015\Libraries\все содержимое Файлы с настройкой SPL под конкретный микроконтроллер lib\MDR32F9_1986ВЕ4_2015\Config\MDR32F9Qx_config.h в папку IAR_CODE\1986BE9x: lib\MDR32F9_1986ВЕ4_2015\Examples\MDR1986VE9x\MDR32F9Q3_EVAL\MDR32F9Qx_board.h

В файле MDR32F9Qx_board.h осуществляется выбор микроконтроллера с помощью макроопределений, поэтому он лежит в папке с проектами под конкретный МК.

Файл MDR32F9Qx_config.h в архиве настроен для микроконтроллера 1986ВЕ4, необходимо открыть этот файл в Notepad и внести небольшую правку. Должно получиться так:

// !!! Раскомментировать блок: /* Seleсt the header file for target microcontroller */ #if defined (USE_MDR1986VE9x) #include "MDR32Fx.h" #elif defined (USE_MDR1986VE1T) #include "MDR1986VE1T.h" #elif defined (USE_MDR1986VE3) #include "MDR1986VE3.h" #elif defined (USE_MDR1986BE4) #include "MDR1986BE4.h" #endif //#include "MDR1986BE4.h" - ! Закомментировать строку, либо удалить.

Теперь чтобы среда IAR могла находить файлы SPL в нашей раскладке необходимо указать ей пути для поиска при сборке. В дереве проекта выбираем самый верхний пункт "HelloWorld - Debug" - просто кликаем на нем левой мышкой, чтобы он был активен и открываем опции проекта (Alt+F7). Если не выбрать верхний пункт проекта, а будет активен какой-то файл из групп в дереве проекта, то при нажатии Alt+F7 откроются опции для этой группы. Нам же необходимо указать пути для всех групп в проекте, поэтому выбираем самый верхний узел в дереве.

Заходим в категорию "С/С++ Compiler ", выбираем закладку Preprocessor . Здесь в поле "Additional include directories" необходимо добавить пути которые мы сформировали. Вот эти пути, добавляем их по одному c помощью диалога, вызываемого кнопкой с многоточием, либо можно скопировать пути прямо отсюда:

$PROJ_DIR$\..\..\SPL\CMSIS\CM3\CoreSupport $PROJ_DIR$\..\..\SPL\CMSIS\CM3\DeviceSupport\MDR32F9Qx\inc $PROJ_DIR$\..\..\SPL\CMSIS\CM3\DeviceSupport\MDR32F9Qx\startup\iar $PROJ_DIR$\..\..\SPL\MDR32F9Qx_StdPeriph_Driver\inc $PROJ_DIR$\..\..\SPL\MDR32F9Qx_StdPeriph_Driver\src $PROJ_DIR$\.. $PROJ_DIR$\..\..\SPL

Это и есть наши пути относительно папки проекта. При расположении прочих проектов по данной раскладке, эти пути останутся валидны.

При добавлении путей через диалоговое окно необходимо следующее, по картинке:

    Пути хорошо бы добавить с относительным путем

    При добавлении пути через диалоговое окно,

    Видно, что пути получаются абсолютными.

    Кликаем на кнопку с треугольником.

    Выбираем вариант с путем относительно проекта.

Собираем пустой проект

Для компиляции минимального проекта к уже существующему файлу main.c необходимо подключить startup-файлы с таблицей векторов прерываний и т.д.

Перед подключением файлов в проект давайте заведем переменную в среде IAR, которая будет задавать путь к нашей папке с кодом IAR_CODE. В главном меню выбираем Tools - Configure Custom Argument Variables .

В открывшемся окне создаем группу MDR_Lib и переменную MDR_CODE, которая будет задавать путь к нашей головной папке.

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

Теперь подключая файлы из нашей директории IAR_CODE, пути в проекте будут указываться относительно переменной $MDR_CODE$, следовательно при переносе проекта в другое место достаточно будет переназначить новый путь в переменной MDR_CODE.

Давайте теперь подключим файлы необходимые для компиляции пустого проекта. Для подключения файлов кликаем правой клавишей мыши на созданной нами группе Startup, выбираем Add - Add Files, и подключаем следующие файлы:

Добавляем файлы: IAR_CODE\SPL\CMSIS\CM3\DeviceSupport\MDR32F9Qx\startup\iar\ startup_MDR32F9Qx.s system_MDR32F9Qx.c system_MDR32F9Qx.h

Удобно выделить все файлы и добавить за один раз.

После этого проект должен собираться - меню Project - Rebuild All . Наблюдаем ошибок 0, на ворнинги не обращаем внимания. Библиотека не сильно подчищена для среды IAR.

Для проверки того, что файлы подключились через переменную $MDR_CODE$ кликнем правой клавишей мыши на заголовок в дереве проекта "HelloWorld - Debug" и выберем в выпадающем меню Open Containing Folder . Откроется окно проводника в Windows с выделенным файлом HelloWorld.ewp. Открываем его notepad-ом и листаем в самый низ, где находим как подключены наши, только что добавленные файлы:

.... Startup $MDR_CODE$\SPL\CMSIS\CM3\DeviceSupport\MDR32F9Qx\startup\iar\startup_MDR32F9Qx.s $MDR_CODE$\SPL\CMSIS\CM3\DeviceSupport\MDR32F9Qx\startup\iar\system_MDR32F9Qx.c $MDR_CODE$\SPL\CMSIS\CM3\DeviceSupport\MDR32F9Qx\startup\iar\system_MDR32F9Qx.h ....

Видно, что пути указаны через переменную $MDR_CODE$. Надеюсь данный подход поможет при необходимости перенести весь репозитарий с проектами, то-есть папку IAR_CODE, в новое расположение или на другой компьютер с минимальными усилиями.

Собираем "HelloWorld"

Скопируем в наш файл main.c код из проекта Hello World - светодиод . В этом коде используются библиотечные файлы управления портами и тактовой частотой. Давайте их так же добавим в проект.

Добавляем файлы: IAR_CODE\SPL\MDR32F9Qx_StdPeriph_Driver\src\ MDR32F9Qx_port.c MDR32F9Qx_rst_clk.c

Подключать *.h файлы не будем, пути у нас прописаны и они найдутся сами. Компилируем проект через кнопку в меню или F7. Проект должен успешно скомпилироваться.

Для того, чтобы прошить получившуюся программу в микроконтроллер выбираем в меню Project - Download - Download active application . В Debug Log окне выскакивают некоторые "ворнинги", но прошивка заканчивается успешно и микроконтроллер приветствует Мир!

В случае использования программаторов Segger, при загрузке в устройство подключенное впервые, драйвера Segger запрашивают какое ядро Cortex подключено.

Выбор должен быть таким:

    1986ВЕ9х - "Unspecified Cortex-M3" .

    1986ВЕ1Т, 1986ВЕ3Т - "Unspecified Cortex-M1" ,

    1986ВЕ4У - "Unspecified Cortex-M0"

SPL и пример на GitHUB

Данный пример мигания светодиодом можно скачать с GitHub - IAR_CODE , так же как и аналогичные реализации для 1986ВЕ1Т и 1986ВЕ3Т. В репозитории содержится библиотека SPL на которой реализованы примеры. Эта библиотека собрана из официальной версии, были лишь вырезаны файлы не относящиеся к IAR и исправлены некоторые ошибки.

Запускаем IAR AVR. Откроется окно Embedded Workbench Startup, можно создать проект ипользуя его, но мы пойдем другим путем, поэтому жмем Cancel. Окно закроется и перед нами во всей своей невзрачной красе предстанет IAR.

Выбираем в верхнем меню Project > Create New Project…

IAR предложит выбрать тип шаблона проекта (Project templates). Выбираем C > main и кликаем Ок.

В стандартном Save As диалоге находим или создаем папку и сохраняем проект. Проект готов. Приглядимся к IARу.

Верхняя строка – почти стандартный menu bar. Ниже - tool bar с кнопками.

С правой стороны находится редактор кода. Сейчас там открыт файл main.c, но в нем только пустая функция main().

С левой стороны расположено окно рабочего пространства (workspace), в котором отображается структура проекта. Любой IARовский проект должн находиться по-крайней мере в одном рабочем пространстве.

В верхней части рабочего пространства находится выпадающее меню. Это так называемые конфигурации проекта. По умолчанию их две – Debug и Release. Они отличаются между собой настройками проекта. Можно создавать свои конфигурации.

Сохраним рабочее пространство. Если не сделаем сейчас, придется делать это на этапе компиляции. Выбираем в меню File > Save Workspace

Зададим настройки проекта для конфигурации Debug. Выбираем в меню Project > Options

Или кликаем правой кнопкой мышки по галочке напротив названия проекта.

Откроется диалоговое окно с множеством настроек.

Выбираем тип микроконтроллера
General Options > Target > Processor configuration
У меня это ATmega8535.

Разрешаем использование имен битов определенных в хедер файле
В General Options > System ставим галочку Enable bit definitions in I/O-Include files

Хоть нам и не понадобится сейчас эта настройка, полезно знать где она находится.

Включаем генерацию ассемблерного листинга . Необязательная опция, но я обычно включаю, чтобы посмотреть что натворил компилер.
С/С++ Compiler > List > галочка Output List File

Меняем формат выходного файла
Linker > Output.
B поле Output file cтавим галочку Override default и заменяем расширение d90 на hex
В поле Format выбираем Other и в выпадающем меню Output format выбираем тип файла intel-standart

Жмем ОК.
Теперь копируем и вставляем текст нашей программы в main.c

#include
#include

int main(void )
{
unsigned char led = 1;
DDRC = 255;

while (1)
{
PORTC = ~led;
__delay_cycles (400000);
led = led<<1;
if (led == 0)
led = 1;
}
return 0;
}

Кликаем кнопку Make.

Если все сделано правильно, IAR откомпилирует и соберет проект, а внизу откроется окно Messages.

Среда IAR Workbench проприетарна и требует лицензирования (в случае если ваш код превышает 32 КБ), однако её вполне хватает для домашнего использования.

Непосредственно среда разработки, в состав которой входит компилятор. После установки IAR потребуется зарегистрировать его, заполнив анкету на сайте компании. Укажите реальный почтовый ящик, на него вам вышлют лицензионный ключ.

С сайта ST Microelectronics нужно будет скачать архив - в нём содержатся:

  • CMSIS (Cortex Microcontroller Software Interface Standard) - библиотека, определяющая работу ядра, того самого Cortex M3 (о ней мы поговорим позже);
  • SPL (Standart Peripheral Library) - стандартная периферийная библиотека, которая сэкономит вам много сил в конфигурации той или иной периферии;
  • Examples - если нужно изучить, как работает новая для вас периферия, то в этой папке лежит множество примеров на все случаи жизни.

Запустив IAR, создайте рабочее пространство File New Workspace . Далее новый проект, меню Project Create New Project…

Программу можно писать на ассемблере, Си или С++. Мы будем использовать язык программирования Си.

Созданный проект необходимо настроить, для этого открываем меню Project Options . Во вкладке General Options выбираем целевой микроконтроллер - STM32F100x4 .


Кроме того, в Library Configuration ставим галочку Use CMSIS . Среда IAR уже включает в себя эту библиотеку, и добавлять её к проекту необязательно, однако новые версии могут выдавать предупреждение вида:

Warning : Label ‘xxxxx’ is defined pubweak in a section implicitly declared root

Проблема решается заменой некоторых строк во встроенной библиотеке CMSIS: в местах упоминания CODE:REORDER добавьте NOROOT(1) . Например:

PUBWEAK NMI_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
NMI_Handler

Далее добавляем путь, по которому будут храниться файлы *.c и *.h - для этого заходим во вкладку C/C++ Compile r ⇒ Preprocessor и добавляем &PROJDIR& (переменная, содержащий путь к папке с проектом).


В разделе Debugger выбираем в качестве отладчика ST-LINK . Ставим галочки Use flash loader и Verify во вкладке Download .

В данной статье речь пойдет о том, какие шаги необходимо выполнить для создания минимального и удобного проекта под микроконтроллер серии STM32 в среде разработки IAR. Этот пост скорее напоминалка для меня самого дабы не забыть мелких нюансов IDE в ответственный момент. Ведь в любой момент я смогу просто зайти на эту страницу и скачать готовый стартап проект. Ну а Вам, дорогие читатели, самим решать, чего полезного можно почерпнуть из этого поста! Ну что ж, приступим?

Естественно, в первую очередь необходимо скачать и установить программу IAR. Дальше необходимо скачать полезную библиотеку от производителя процессора, которая называется STM32F10x_StdPeriph_Lib_V3.5.0 (версия в Вашем случае может отличаться). После этого, запускаем установленную среду разработки. Создаем новый проект Project->Create New Project…

Выбираем пустой проект


Получаем


Создаем желаемые условные разделения внутри проекта (с помощью команд Add->Add Group… )

Добавляем необходимые файлы


В результате дерево проекта должно выглядеть следующим образом

Переходим к настройке проекта. Выбираем процессор




Устанавливаем галочку в настройках для использования библиотеки CMSIS

Добавляем путя к библиотечным файлам, а также добавляем определения (Defines) в настройки препроцессора C/C++


Кроме этого есть возможным получать на выходе будущей сборки проекта выходные файлы разного формата. Одним из возможных форматов является обычный двоичных файл. Для его генерации нужно зайти в настройки проекта и установить их следующим образом

Ради приличия считаю должным, упомянуть о самой программе, которую мы собираемся скомпилировать. Что она должна делать? Это своего рода «Hello World» в мире встроенных систем. Иными словами — будем мигать светодиодом. Рассмотрим исходный код главного файла:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #include "stm32f10x_flash.h" int main() { GPIO_InitTypeDef GPIO_InitStructure; /* HCLK = SYSCLK */ RCC_HCLKConfig(RCC_SYSCLK_Div1) ; RCC_PCLK2Config(RCC_HCLK_Div2) ; RCC_PCLK1Config(RCC_HCLK_Div4) ; /* Select HSI as system clock source */ RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI) ; /* Wait till HSI is used as system clock source */ while (RCC_GetSYSCLKSource() != 0x00) { } FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable) ; FLASH_SetLatency(FLASH_Latency_0) ; // Enable peripherals clocks RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE) ; /* LED configuration */ /* Configure PD.05 as output push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, & GPIO_InitStructure) ; while (1) { GPIO_SetBits(GPIOD, GPIO_Pin_5) ; for (long i= 0 ; i< 200000 ; i++ ) ; GPIO_ResetBits(GPIOD, GPIO_Pin_5) ; for (long i= 0 ; i< 200000 ; i++ ) ; } }

Что тут творится? В первую очередь настраиваем систему тактирования микропроцессора и выбираем внутренний источник тактирования (HSI, 8 MHz). Дальше подаём тактирование на порт GPIOD, который «висит» на шине APB2. После, настраиваем 5-ый пин порта GPIOD на выход (к этому пину подключаем светодиод). Ну а дальше видим бесконечный цикл в котором и происходит поочерёдное включение и выключение светодиода. Между включением и выключением также добавлены циклы. Они выполняют роль задержки, дабы человеческий глаз успевал замечать мигание светодиода.

Теперь проект должен без особых проблем собраться по нажатии клавиши F7 . Нами была создана возможно первая прошивка для микропроцессора STM32F103. Поздравляю! На выходе получим желаемый двоичный файл. В одной из следующих статьей рассмотрим способ загрузки полученного бинарного файла, собственно в сам микропроцессор. Это сделать очень просто, если у Вас имеется в наличии переходник USB-UART.

На днях произошла ужасная вещь - на клавиатуру ноутбука вылилось небольшое, но достаточное для глюков количество воды. Хорошо, что вода оказалось чистой, и особенно то, что в Красноярске вода содержит мало примесей (за несколько лет в чайнике нет ни капли накипи). Что нужно делать, если что-то подобное случилось с Вами: Быстро перевернуть ноутбук, позволить жидкости вытечь из клавиатуры (при этом стоит следить, чтобы жидкость в этот момент не стекала на матрицу.Вытереть тряпкой остатки воды(спорный пункт!) Я взял баллон со сжатым воздухом и продул под всеми клавишами, при этом вылетело много жидкости. Возможно, таким образом можно лишь усугубить ситуацию, загнав жидкость потоком воздуха куда не следует.Теперь нужно разобрать ноутбук и просушить клавиатуру. Других вариантов нет. Имейте ввиду, что если Вы конкретно залили клавиатуру, то можете попрощаться с ноутбуком и вот почему: Клавиатур пока нет ни в России, ни в Китае! Я обзвонил много сервисных центров, и даже общался с л…

Мало кто знает, а в особенности те, кто только начинает изучать микроконтроллеры STM32, что их можно запрограммировать не имея специального программатора. Необходимо лишь выбрать режим загрузки контроллера через встроенный загрузчик, подключитьcя через UART и записать необходимый код. Теперь обо всем подробнее. Большая часть контроллеров STM32 имеет встроенный (нестираемый) загрузчик в специальной области памяти, который работает по протоколам UART, SPI, I2C и CAN. Конечно же проще всего работать через UART, т.к. он есть почти у каждого, кто имеет дела с электроникой, поэтому его и будем рассматривать. Выбор области памяти, из которой осуществляется загрузка контроллера осуществляется подачей низкого или высокого уровня на ножки BOOTx (может быть как одна, так и несколько). Подробнее о том, как выбрать загрузчик на конкретном контроллере указано в AN2606. Так же в AN2606 указано, какой интерфейс контроллера можно использовать для программирования. Еще, чтобы записать код в к…

У контроллеров STM32, в большинстве своем, отсутствует как таковой буфер приемника UART. Исходя из этой особенности, приходится создавать кольцевой буфер и использовать прерывания. При низкой тактовой частоте ядра и высоких скоростях UART это оказывается очень накладно как по производительности, так и по энергопотреблению.
Всего этого можно избежать при помощи DMA, но как? Ведь при настройке DMA указывается фиксированный размер буфера, в который копируются принятые данные. К тому же у DMA есть прерывания только при полном и половинном заполнении буфера. Фактически, если вы уверены, что длина принимаемых данных не превысит длину буфера, прерывания от DMA можно не использовать вовсе. А обойтись только прерыванием IDLE от UART.
Флаг прерывания IDLE в интерфейсе UART выставляется в случае, если после стоп-бита последнего переданного символа на линии RX нет данных в течении времени приема одного символа. Флаг IDLE сбрасывается программно.