STM Урок 143. USB HS Host MSC FREERTOS. Часть 1



Продолжаем тему программирования шины USB, устройства Host (ведущего), класса MSC (Mass Storage Class) с использованием интерфейса HS (High Speed). Только проект мы будем на данном занятии уже разрабатывать для использования с операционной системой реального времени FREERTOS. При использовании данной системы будут свои тонкости. Поэтому такой урок было принято решение сделать.

В уроке 141 мы уже работали с данным интерфейсом, поэтому нам все равно будет проще, чем изучать всё с нуля.

В качестве подопытной платы мы по-прежнему будем использовать отладочную плату STM32F746G-DISCOVERY, а также тот же самый FLASH-накопитель на 8 гигабайт, которым мы пользовались в уроке 141

 

 

Поэтому многие участки кода будут использоваться из этого урока.

Тогда не будем медлить и сразу приступим к проекту.

Проект мы сделаем из проекта урока 111 с именем TASKS_QUEUES и назовём его USB_HS_HOST_MSC_FREERTOS.

Прежде чем открывать проект в Cube MX, удалим из папок Src и Inc все те файлы, которые создавали не мы, а также кроме файла main.c.

Теперь откроем проект в Cube MX и первым делом настроим FreeRTOS, так как в то время, когда мы изучали LWIP при взаимодействии с FREERTOS, мы многому научились.

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

 

 

В разделе Tasks and Queues удалим задачу myTask02

 

 

Немного уменьшим стек для задачи по умолчанию

 

 

Добавим задачу для вывода строк на дисплей

 

 

Подключим остальные два банка памяти SDRAM в настройках FMC

 

 

Зайдём в настройки Cortex M7 и добавим туда данные банки в другой регион памяти

 

 

Включим шину USB HOST HS

 

 

Контакт ULPI DIR переопределим на ножку PC2

 

 

Включим USB Host

 

 

Также произведём его некоторые настройки, в которых кроме всего прочего увеличим стек на процесс

 

 

Включим библиотеку FATFS

 

 

Задействуем в ней поддержку длинных имён, а также увеличим максимальную величину сектора и увеличим максимальное количество одновременно открытых файлов

 

 

Прежде чем генерировать проект, в файле ff.h в папке репозитория «ДИСК:\Users\Имя пользователя\STM32Cube\Repository\STM32Cube_FW_F7_V1.12.0\Middlewares\Third_Party\FatFs\src» добавим некоторый код, с помощью которого отключим проверку повторных вхождений. У нас таких не ожидается, а с включенными почему-то не работает

 

 

Сгенерируем проект для System Workbench, несмотря на предупреждение Cube MX по USB_HOST, и откроем его там. Установим уровень оптимизации в 1, а также уберём при наличии отладочные настройки.

 

 

Также вот здесь установим галку, чтобы проект побыстрее собирался

 

 

Откроем файл main.c и удалим пользовательскую функцию TaskStringOut вместе с телом.

Также вместе с телом удалим и функцию Task01.

Удалим также глобальный идентификатор этой задачи вместе с идентификаторами остальных пользовательских задач

 

osThreadId Task01Handle,Task02Handle,Task03Handle,TaskStringOutHandle;

 

Удалим прототипы функций этих задач

 

void Task01(void const * argument);
void TaskStringOut(void const * argument);

 

В структуру для очереди отправки данных на дисплей добавим ещё два поля

 

 

А структуру для параметров удалим

 

typedef struct struct_arg_t {

  char str_name[10];

  uint16_t y_pos;

  uint32_t delay_per;

} struct_arg;

 

Переменные параметров тоже удалим

 

struct_arg arg01, arg02, arg03;

 

Добавим глобальный строковый массив

 

 

В функции main() удалим код создания данных задач

 

strcpy(arg01.str_name,»task1");

strcpy(arg02.str_name,»task2");

strcpy(arg03.str_name,»task3");

arg01.y_pos = 60;

arg02.y_pos = 110;

arg03.y_pos = 160;

arg01.delay_per = 1000;

arg02.delay_per = 677;

arg03.delay_per = 439;

osThreadDef(tskstrout, TaskStringOut, osPriorityBelowNormal, 0, 1280);

TaskStringOutHandle = osThreadCreate(osThread(tskstrout), NULL);

osThreadDef(tsk01, Task01, osPriorityIdle, 0, 128);

Task01Handle = osThreadCreate(osThread(tsk01), (void*)&arg01);

osThreadDef(tsk02, Task01, osPriorityIdle, 0, 128);

Task02Handle = osThreadCreate(osThread(tsk02), (void*)&arg02);

osThreadDef(tsk03, Task01, osPriorityLow, 0, 128);

Task03Handle = osThreadCreate(osThread(tsk03), (void*)&arg03);

 

В функции задачи по умолчанию StartDefaultTask удалим вот это

 

uint32_t syscnt;

osThreadList((unsigned char *)str_buf);

HAL_UART_Transmit(&huart1,(uint8_t*)str_buf,strlen(str_buf),0x1000);

HAL_UART_Transmit(&huart1,(uint8_t*)«\r\n»,2,0x1000);

 

А в бесконечном цикле данной функции оставим только задержку, удалив всё остальное

 

/* Infinite loop */

for(;;)

{

  osDelay(1);

}

 

В функции TaskStringOut объявим переменную и указатель

 

 

А в бесконечном цикле обработаем очередь, удалив оттуда задержку

 

 

Подготовим глобальные переменные идентификаторов двух задач для работы с USB

 

 

Вот это поднимем повыше, а то некрасиво

 

 

Вот эти массивы удалим

 

char str1[60];

char str_buf[1000]={'\0'};

 

Подключим переменную состояний программы

 

 

Создадим идентификатор очереди для передачи состояний программы между задачами

 

 

 

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

 

 

Добавим массивы для регионов кучи

 

 

И задействуем их в функции main()

 

 

Уберём все старые надписи с дисплея

 

TFT_DisplayString(0, 10, (uint8_t *)«Queues», CENTER_MODE);

TFT_SetTextColor(LCD_COLOR_MAGENTA);

TFT_DisplayString(14, 60, (uint8_t *)«Task1:», LEFT_MODE);

TFT_DisplayString(14, 110, (uint8_t *)«Task2:», LEFT_MODE);

TFT_DisplayString(14, 160, (uint8_t *)«Task3:», LEFT_MODE);

 

Добавим новую шапку и изменим цвет вывода текста

 

 

Создадим очередь

 

 

Перейдём в файл usb_host.c и подключим библиотеку FATFS

 

 

Подключим идентификатор очереди, путь к корневому разделу и переменную структуры файловой системы

 

 

Удалим изменение состояния программы при отключении накопителя, так как мы его изменим сами, но чуть позже

 

case HOST_USER_DISCONNECTION:

Appli_state = APPLICATION_DISCONNECT;

 

Вместо этого мы отмонтируем файловую систему и отправим в очередь состояние

 

 

Аналогично поступим и со следующим кейсом (вариантом)

 

case HOST_USER_CLASS_ACTIVE:

Appli_state = APPLICATION_READY;

 

Здесь мы просто в очередь отправим новое состояние программы

 

 

Удалим также изменение состояния и в следующем кейсе

 

case HOST_USER_CONNECTION:

Appli_state = APPLICATION_START;

 

А здесь мы только примонтируем нашу файловую систему

 

 

Вернёмся в файл main.c и добавим функцию первой задачи

 

 

А в функции задачи по умолчанию StartDefaultTask мы данную задачу создадим

 

 

В функции первой задачи USB_Task01 изменим состояние программы

 

 

Добавим бесконечный цикл, в котором будем следить за очередью и в зависимости от этого менять состояние программы

 

 

Выше добавим функцию для второй задачи

 

 

Создадим эту задачу в функции для первой задачи USB_Task01

 

 

В функции для второй задачи добавим бесконечный цикл, в котором будем обрабатывать варианты пользовательского состояния программы, не забывая о задержке, иначе рискуем не дать работать остальным задачам

 

 

Добавим указатель на переменную структуры для очереди отправки строки на дисплей и локальный строковый массив

 

 

Обработаем состояние программы на отключение носителя. Сделаем это не в теле условия вариантов, а за телом условия

 

 

В условии вариантов добавим ещё один кейс, в котором отправим сообщение в терминальную программу о том, что мы вставили FLASH-накопитель в разъём, а также установим другое пользовательское состояние

 

 

Добавим ещё три, пока почти пустых варианта (кейса)

 

 

Теперь мы можем уже проверить, как наша программа почувствует то, что в плату будет вставлен FLASH-накопитель, а также и то, когда он будет извлечён.

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

Затем вставим накопитель и через некоторое время должна будет появиться надпись Start на дисплее платы

 

 

Извлечём накопитель, и надпись Start поменяется на Stop

 

 

Также в терминальной программе мы увидим сообщение, что файловая система отмонтирована

 

 

Можно попробовать такие манипуляции по вставке и извлечению накопителя несколько раз, всё будет работать.

 

В следующей части нашего урока мы попробуем записать и прочитать файлы, а также получить определённую информацию о файловой системе средствами FATFS.

 

 

Предыдущий урок Программирование МК STM32 Следующая часть

 

 

Отладочную плату можно приобрести здесь STM32F746G-DISCOVERY

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

STM USB HS Host MSC FREERTOS

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*