ESP8266 Урок 19. FreeRTOS. UART. Передача данных

 

 

 

Продолжаем учиться писать код для микроконтроллера ESP8266.

На данном занятии мы также продолжим тему передачи данных по шине UART, но попытаемся мы передать данные на ПК уже с использованием ОС. В качестве ОС мы будем использовать операционную системы FreeRTOS.

FreeRTOS — многозадачная операционная система реального времени (ОСРВ) для встраиваемых систем. Использование данной ОС позволит нам организовать сразу несколько потоков и в любой момент уничтожить любой из них.

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

С системой FreeRTOS мы с вами уже хорошо знакомы, так как использовали её для написания наших проектов для контроллера STM32. Поэтому теоретическую часть по работе с данной системой мы смело можем пропустить, так как мы уже знаем, что представляют собой такие механизмы данной операционной системы, как семафоры, задачи, очереди и т.д. Тем не менее код для контроллера ESP8266 будет отличаться, так как имена функций, структур, макросов для STM32 мы использовали специфические для используемых библиотек порта для контроллера STM32, а для написания кода для ESP8266 принято использование классического интерфейса. Но разница здесь не столь велика, так что я думаю вместе мы с этим разберёмся без особого труда.

Поэтому давайте сразу же приступим к делу, а если что будет непонятно, то разберёмся по ходу написания наших проектов.

Схема для начала у нас будет простейшая – отладочная плата, подключенная к ПК по USB

 

 

А проект мы создадим из проекта прошлого занятия с именем I2C_LCD2004_REMAP и назовём его UART_TX_RTOS.

С настройкой проекта придётся повозиться, так как для работы с системой FreeRTOS используется совсем другой SDK. За основу был взят официальный комплект ESP8266_RTOS_SDK-2.0.0.

Для использования в наших проектах данного комплекта SDK создадим каталог (или папку) с именем ESP8266_RTOS_SDK в каталоге ESP8266, в котором у нас хранится обычный подключаемый комплект и скопируем в данный каталог содержимое каталога ESP8266_RTOS_SDK-2.0.0 официального комплекта.

Откроем наш проект в Eclipse и внесём сначала изменения в свойствах проекта во вкладке C/C++ General -> Paths and Symbols -> Includes -> GNU C.

Во-первых, во всех путях заменим имя каталога ESP8266_NONOS_SDK на UART_TX_RTOS. Также добавим ещё 2 пути: D:\ESP8266\ESP8266_RTOS_SDK\include\espressif и D:\ESP8266\ESP8266_RTOS_SDK\include\freertos.

В результате получится вот так

 

 

Сохраним изменения и перейдём к файлу сценария Makefile. Принцип построения данного файла остаётся прежним, только в него было внесено несколько новых переменных, также изменились имена подключаемых библиотек и путей, поэтому не будем его собирать по крупицам, а лучше я сразу дам всё его содержимое

 

 

Удалим из каталога проекта файлы i2c_user.c, i2c_user.h, lcd.c и lcd.h.

Из файла main.h удалим подключение всех заголовочных файлов и подключим вместо них другие

 

 

Из заголовка следующей функции в файле main.c удалим атрибут

 

uint32 ICACHE_FLASH_ATTR user_rf_cal_sector_set(void)

 

А здесь удалим перечисляемый тип

 

enum flash_size_map size_map = system_get_flash_size_map();

 

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

Если мы сейчас попытаемся собрать код, то у нас он все равно не соберётся, так как у нас кое-чего не хватает в библиотеке SDK и в тулчейне.

В каталоге ESP8266\xtensa-lx106-elf\xtensa-lx106-elf\lib не хватает файла libhal.a, поэтому скопируем его туда. Также в каталоге D:\ESP8266\ESP8266_RTOS_SDK\lib не хватает файла libmesh.a, поэтому также его туда скопируем. Здесь возникает резонный вопрос: а где взять эти файлы? Честно признаться, не помню, где я их нашел, поэтому возьмёте их вот в этом архиве.

Вот теперь проект соберётся и можно смело писать код для работы с операционной системой FreeRTOS.

В функции user_init произведём настройку UART на определённую скорость обмена

 

 

Проверим его работу

 

 

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

 

 

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

 

 

 

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

 

 

Мы использовали функцию подготовки строки потому, что функция os_printf некорректно работает с типами long.

Увеличим значение счётчика на один, затем, если оно достигнет некоторого порога, обнулим его, и затем применим задержку на 1 секунду

 

 

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

Создадим нашу задачу в user_init(), пока без всяких параметров

 

 

Соберём наш проект.

Только перед тем как прошивать контроллер, лучше его полностью очистить и прошить по адресу 0x3FC000 файл esp_init_data_default_v05.bin, то есть подготовить, как мы это делали в уроке 5.

Теперь можно проект прошить.

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

 

 

Создадим аналогичную функцию для другой задачи ниже функции task1, только задержку сделаем чуть поменьше

 

 

Создадим данную задачу в user_init()

 

 

Соберём код, пошьём контроллер, и увидим, как наши задачи будут работать одновременно. Поначалу будет казаться, что задачи работают синхронно, но вскоре счётчик задачи 2 обгонит счётчик первой задачи

 

 

Так как коды функций задач почти одинаковые, есть смысл использовать для них только одну функцию и применить параметры.

Удалим функцию task2 вместе с телом.

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

 

 

В функции user_init инициализируем поля данных переменных

 

 

Изменим вызов функций создания наших задач, используя в качестве параметров указатель на переменные структур

 

 

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

 

 

Немного изменим код вызова функции подготовки строки, добавив туда номер задачи из параметров

 

snprintf(str01, sizeof(str01), "Task%d: %7lu", pdt->num_task, cnt);

 

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

 

vTaskDelay(pdt->del / portTICK_RATE_MS);

 

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

 

 

Таким образом, сегодня мы познакомились с тем, как можно настроить тулчейн для сборки проектов в IDE Eclipse для работы с контроллером ESP8266 под управлением операционной системы реального времени FreeRTOS, также мы создали пробный проект, в котором одновременно работают две задачи, а ещё повторили, как применять параметры в задачах.

Всем спасибо за внимание!

 

Предыдущий урок Программирование МК ESP8266 Следующий урок

 

Исходный код

 

 

Модуль ESP NodeMCU можно купить здесь: Модуль ESP NodeMCU

Различные модули ЕSP8266 можно приобрести здесь Модули ЕSP8266

 

 

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

 

ESP8266 FreeRTOS. UART. Передача данных

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

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

*