IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【ESP32】arduino中的ESP32实时系统FreeRTOS使用教程(一) -> 正文阅读

[嵌入式]【ESP32】arduino中的ESP32实时系统FreeRTOS使用教程(一)

简单的本节略过,详细的可以看视频:单片机ESP32上的FREERTOS这个作者讲的挺好的,通俗易懂

任务的状态

FreeRTOS中的任务有运行态、就绪态、阻塞态、挂起态四种状态,在任何时候都只处于其中一种状态。任务状态之间的转换如下图所示:
在这里插入图片描述

任务的优先级

每一个任务都会有一个任务优先级,其范围为 0 (configMAX_PRIORITIES - 1),0优先级最低,(configMAX_PRIORITIES - 1)优先级最大,通常空闲任务的优先级最低,为0。

创建任务

使用动态的方法创建一个任务:


void setup() {
	xTaskCreate(task1, 		//任务函数
	            "task1",    //任务名字
	            4096,       //任务堆栈大小
		        NULL,		//传递给任务函数的参数
	            5,          //任务优先级
	            NULL);      //任务句柄
}

void task1(void *pvParameters)
{
//任务初始化程序
   while(1)
   {
   //任务的循环任务
    vTaskDelay(1);    //任务延时调度
   }
   vTaskDelete(NULL);  //删除自身函数
}

更多的任务创建和FreeRTOS函数说明看这里:
ESP32之FreeRTOS–任务的创建和运行

传递给任务函数的参数

/*
  程序: FREERTOS - 单个参数传递
        大家在看本程序的时候,需要对指针非常的了解
        知道 * -> &的作用
  作业: 添加LED3_PIN 15
  公众号:孤独的二进制
*/
byte LED1_PIN = 23;
byte LED2_PIN = 21;

void task1(void *pt) {
  byte * pbLEDPIN;
  pbLEDPIN = (byte *)pt;

  byte LEDPIN;
  LEDPIN = *pbLEDPIN;
  pinMode(LEDPIN, OUTPUT);
  while (1) {
    digitalWrite(LEDPIN, !digitalRead(LEDPIN));
    vTaskDelay(1000);
  }
}

void task2(void *pt) {
  byte LEDPIN = *(byte *)pt;
  pinMode(LEDPIN, OUTPUT);
  while (1) {
    digitalWrite(LEDPIN, !digitalRead(LEDPIN));
    vTaskDelay(3000);
  }
}

void setup() {
  Serial.begin(9600);

  byte * pbLED1PIN;
  pbLED1PIN = &LED1_PIN;

  void * pvLED1PIN;
  pvLED1PIN = (void *)pbLED1PIN;

  if (xTaskCreate(task1,
                  "Blink 23",
                  1024,
                  pvLED1PIN,
                  1,
                  NULL) == pdPASS)
    Serial.println("Task1 Created.");

  if (xTaskCreate(task2,
                  "Blink 21",
                  1024,
                  (void *)&LED2_PIN,
                  1,
                  NULL) == pdPASS)
    Serial.println("Task2 Created.");

}

void loop() {
}

程序出处
该程序task1创建一个字节指针 byte * pbLED1PIN,通过 pbLED1PIN =&LED1_PIN来指向LED1_PIN的地址,再创建pvLED1PIN这个void类型的指针来存储pbLED1PIN转换成void的值。

函数传递的是void类型的指针,所以参数需要转换成void类型的指针才能在任务函数传递。

task2则简单粗暴一点,(void *)&LED2_PIN,直接取地址,然后用空指针去指向,也一样完成传递。

结构体多参数传递

程序出处


typedef struct {
  byte pin;
  int delayTime;
} LEDFLASH;

LEDFLASH led1, led2;

if (xTaskCreate(ledFlash,
                  "FLASH LED",
                  1024,
                  (void *)&led1,
                  1,
                  NULL) == pdPASS)
    Serial.println("led1 flash task Created.");
    
void ledFlash(void *pt) {
  LEDFLASH * ptLedFlash = (LEDFLASH *)pt;
  byte pin = ptLedFlash->pin;
  int delayTime = ptLedFlash->delayTime;

  pinMode(pin,OUTPUT);
  while (1) {
    digitalWrite(pin, !digitalRead(pin));
    vTaskDelay(delayTime);
  }
}

实例化结构体led1,然后传入结构体的指针地址,再创建结构体指针(类型为LEDFLASH )使其等于pt(类型转换为LEDFLASH *),这样子就可以获取到结构体led1的地址了。

互斥量Mutex

程序
多个任务一起用同一个变量就会出问题了,所以就要引入互斥量的概念,简单来说,就是互斥锁锁住一个变量之后,只有等这个锁解了,其他任务才能使用这个变量。

/*
  程序: Tasks之间数据传递
        有多任务同时写入,或者数据大小超过cpu内存通道时,或者对共享资源的访问时候,需要有防范机制
        使用MUTEX对数据对Cirtical Section的内容进行保护
        可以想象成MUTEX就是一把锁

  公众号:孤独的二进制

  语法:
  SemaphoreHandle_t xHandler; 创建Handler
  xHandler = xSemaphoreCreateMutex(); 创建一个MUTEX 返回NULL,或者handler
  xSemaphoreGive(xHandler); 释放
  xSemaphoreTake(xHanlder, timeout); 指定时间内获取信号量 返回pdPASS, 或者pdFAIL

  理解方法:
  MUTEX的工作原理可以想象成
  共享的资源被锁在了一个箱子里,只有一把钥匙,有钥匙的任务才能对改资源进行访问
*/
SemaphoreHandle_t xMutexInventory = NULL; //创建信号量Handler

void retailTask(void *pvParam) {
  while (1) {

    // 在timeout的时间内如果能够获取就继续
    // 通俗一些:获取钥匙
    if (xSemaphoreTake(xMutexInventory, timeOut) == pdPASS) {
      //被MUTEX保护的内容叫做 Critical Section

      for (int i; i < random(10, 100); i++) 
      vTaskDelay(pdMS_TO_TICKS(i));

        //释放钥匙
        xSemaphoreGive(xMutexInventory);
      } else {
        //无法获取钥匙
      }


    };

    vTaskDelay(100); //老板要求慢一些,客户升级后,可以再加快速度
  }
}
  if (xSemaphoreTake(xMutexInventory, timeOut) == pdPASS)
   如果没有获取到互斥量,则执行以下内容,超时时间是timeOut
        xSemaphoreGive(xMutexInventory);

ESP32的双核心

在这里插入图片描述
ESP32是具有两个核心的芯片(可以对应一下你手中的型号作对比),是一个40nm的芯片。

核心0主要负责WiFi和蓝牙,如果不是操作这两个,十分不建议将代码放在核心0中运行

/*
  程序: 多核多任务

  API:
      xPortGetCoreID() 获取当前任务运行的核心
      xTaskCreate() 有系统选择运行核心,优先选择0
      xTaskCreatePinnedToCore() 指派任何给指定核心

  公众号:孤独的二进制
*/

void taskA(void *ptParam) {
  while (1) {
    Serial.println(xPortGetCoreID());	//获取当前任务在哪个核心运行
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  xTaskCreatePinnedToCore(taskA, "Task A", 1024 * 4, NULL, 1, NULL,1);
  

}

void loop() {

Serial.println(xPortGetCoreID());

}

主要是这一句,修改最后一个参数0或1即可修改核心数,使用Arduino环境对esp进行开发时建议使用Application CPU(id=1),否则可能有bug,不建议使用xTaskCreate

  xTaskCreatePinnedToCore(taskA, "Task A", 1024 * 4, NULL, 1, NULL,1);

固定频率运行任务

以固定频率运行任务,不多也不少


  TickType_t xLastWakeTime = xTaskGetTickCount();

    vTaskDelayUntil(&xLastWakeTime, xFrequency);
    vTaskDelayUntil(上一次唤醒的时间的结构体地址, 下一次运行的时间);

软件定时器

FreeRTOS中只要内存允许,想要多少个Timer 就有多少个Timer

  lockHandle = xTimerCreate("Lock Car",
                            2000,		//两秒钟唤醒一次
                            pdFALSE,
                            (void *)0,
                            lockCarCallback);

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-09-30 01:07:48  更:2022-09-30 01:10:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 17:45:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码