15. Uart (Transmit) FreeRTOS

Передадим данные по UART с использованием FreeRTOS и созданием задачи.
Для работы с freeRTOS необходимо изменить SDK (в папке с исходниками все добавлено).
В создаваемый проект необходимо дописать следующие пути:
Выбираем Проект->Properties->C/C++ General -> Paths and Symbols -> GNU C
Изменим Makefile (лучше взять из примера в папке с исходниками)

Изменим содержимое файла main.h, дописав

#include "esp_common.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "uart.h"
#include "gpio.h"

Начнем изменять файл main.c

После #include "main.h" напишем тела 2-х задач:

void ICACHE_FLASH_ATTR task1(void *pvParameters)
{
  uint32 cnt=0;
  char str01[20];
  for(;;)
  {
    snprintf(str01, sizeof(str01), "Task 1: %7lu",cnt);
    os_printf("%s\n", str01);
    cnt++;
    if(cnt>=10000000) cnt=0;
    vTaskDelay(1000 / portTICK_RATE_MS);
  }
}

void ICACHE_FLASH_ATTR task2(void *pvParameters)
{
  uint32 cnt=0;
  char str01[20];
  for(;;)
  {
    snprintf(str01, sizeof(str01), "Task 2: %7lu",cnt);
    os_printf("%s\n", str01);
    cnt++;
    if(cnt>=10000000) cnt=0;
    vTaskDelay(900 / portTICK_RATE_MS);
  }
}

Изменим системную функцию (в дальнейшем в проектах она должна выглядеть так)

uint32 user_rf_cal_sector_set(void)
{
    flash_size_map size_map = system_get_flash_size_map();
    uint32 rf_cal_sec = 0;

    switch (size_map) {
        case FLASH_SIZE_4M_MAP_256_256:
            rf_cal_sec = 128 - 8;
            break;

        case FLASH_SIZE_8M_MAP_512_512:
            rf_cal_sec = 256 - 5;
            break;

        case FLASH_SIZE_16M_MAP_512_512:
        case FLASH_SIZE_16M_MAP_1024_1024:
            rf_cal_sec = 512 - 5;
            break;

        case FLASH_SIZE_32M_MAP_512_512:
        case FLASH_SIZE_32M_MAP_1024_1024:
            rf_cal_sec = 1024 - 5;
            break;

        default:
            rf_cal_sec = 0;
            break;
    }

    return rf_cal_sec;
}

Изменим «функцию main», добавив задачи

void ICACHE_FLASH_ATTR user_init()
{
	UART_SetBaudrate(UART0,BIT_RATE_115200);//изменяем скорость uart
	UART_SetBaudrate(UART1,BIT_RATE_115200);//в FreeRTOS это так 

	os_printf("r\n");
	os_printf("SDK version:%s\n", system_get_sdk_version());
	os_printf("\r\n");
	xTaskCreate(task1, "task1", 256,  NULL, 1, NULL);
	xTaskCreate(task2, "task2", 256,  NULL, 1, NULL);
}

Сигнатура функции для добавления задач:
#define xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask)
Где: pvTaskCode- имя функции, которая вызывается в задаче
pcName — пользовательское имя функции
usStackDepth- глубина стека (в словах-uint32)
pvParameters — параметры, передаваемые в функцию
uxPriority- приоритет
pxCreatedTask -хендл созданной задачи

//———————————————————————-

В примере выше задачи 1 и 2 имеют одинаковый функционал и отличия только в номере задачи и делителе.
Можно использовать функции 1 задачи передавая в качестве параметров различия в 1 и 2 задачах.

Удалим тела 2-х задач и вместо них напишем:

typedef struct
{
  unsigned char num_task;
  unsigned short del;
} pData;
pData dt1, dt2;
//------------------------------------------------------

void ICACHE_FLASH_ATTR task1(void *pvParameters)
{
  uint32 cnt=0;
  pData *pdt = (pData*) pvParameters;
  char str01[20];
  while(1)
  {
    snprintf(str01, sizeof(str01), "Task%d: %7lu", pdt->num_task, cnt);
    os_printf("%s\n", str01);
    cnt++;
    if(cnt>=10000000) cnt=0;
    vTaskDelay(pdt->del / portTICK_RATE_MS);
  }
}

В функции main вызовем эту задачу

void ICACHE_FLASH_ATTR user_init()
{
	UART_SetBaudrate(UART0,BIT_RATE_115200);
	UART_SetBaudrate(UART1,BIT_RATE_115200);

	os_printf("r\n");
	os_printf("SDK version:%s\n", system_get_sdk_version());
	os_printf("\r\n");
	dt1.del = 1000; dt1.num_task = 1; 	dt1.cnt=0;
	dt2.del = 900; 	dt2.num_task = 2;	dt2.cnt=0;
	xTaskCreate(task1, "task1", 256,  (void *) &dt1, 1, NULL);
	xTaskCreate(task1, "task2", 256,  (void *) &dt2, 1, NULL);
}

Как наглядно видно, физически на стеке выделяется место под 1 задачу и «параметры», что меньше чем 2 задачи и «параметры».
За счет передачи параметров мы избавляемся от дублирования части кода.

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

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