ESP32S3——多线程

2024-06-05 20:52
文章标签 多线程 esp32s3

本文主要是介绍ESP32S3——多线程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、环境:

平台:arduino IDE 或 VS Code PlatformIO 皆可。

我的是后者,具体为:

        框架:VS + PlatformIO + Arduino

二、硬件准备:

一个esp32s3

本文用到的是U0RXD(GPIO44 )与U0TXD(GPIO43)引脚

一台电脑

一根数据线

三、代码功能:

        一个LED一秒亮一次:

        另一个LED两秒两一次。

注意:ESP32S3有两个type-C口,一个UART用来下载调试程序,一个USB用来供电。下载完程序后切换到USB,现象会更明显。

四、最简代码

#include <Arduino.h>#define LED_U0RXD 44
#define LED_U0TXD 43// 创建两个任务,
// TaskBlink1任务:一个LED 1s亮一次,
// TaskBlink2任务:另一个LED 2s亮一次。
void TaskBlink1( void *pvParameters );
void TaskBlink2( void *pvParameters );void setup() {Serial.begin(115200);uint32_t blink_delay1 = 1000; // Delay between changing state on LED pinuint32_t blink_delay2 = 2000; // Delay between changing state on LED pinxTaskCreate(TaskBlink1       // 这个任务运行的函数,  "Task Blink1" //  给人看的名字,  2048        // 任务栈的大小,用于存储任务运行时的上下文信息。简单来说,就是最多存这么多信息,  (void*) &blink_delay1 // 任务参数。要么没有填NULL;要么必须为无类型指针,  2  // 优先级,  NULL // 任务的句柄,用于管理和控制任务,NULL相当于0,意味着此处不需要任务句柄);xTaskCreate(TaskBlink2       // 这个任务运行的函数,  "Task Blink2" //  给人看的名字,  2048        // 任务栈的大小,用于存储任务运行时的上下文信息。简单来说,就是最多存这么多信息,  (void*) &blink_delay2 // 任务参数。要么没有填NULL;要么必须为无类型指针,  2  // 优先级,  NULL // 任务的句柄,用于管理和控制任务,NULL相当于0,意味着此处不需要任务句柄);Serial.printf("Basic Multi Threading Arduino Example\n");// Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
}void loop(){
// 这里什么都不用写
}/*---------------------- Tasks ---------------------*/void TaskBlink1(void *pvParameters){  // This is a task.uint32_t blink_delay = *((uint32_t*)pvParameters);// 初始化LED_U0RXD为output模式pinMode(LED_U0RXD, OUTPUT);
// for死循环for (;;){ // 多线程,每个任务必须是死循环digitalWrite(LED_U0RXD, HIGH);   // turn the LED on (HIGH is the voltage level)delay(blink_delay);digitalWrite(LED_U0RXD, LOW);    // turn the LED off by making the voltage LOWdelay(blink_delay);}
}void TaskBlink2(void *pvParameters){  // This is a task.uint32_t blink_delay = *((uint32_t*)pvParameters);// 初始化LED_U0RXD为output模式pinMode(LED_U0TXD, OUTPUT);for (;;){ // A Task shall never return or exit.digitalWrite(LED_U0TXD, HIGH);   // turn the LED on (HIGH is the voltage level)delay(blink_delay);digitalWrite(LED_U0TXD, LOW);    // turn the LED off by making the voltage LOWdelay(blink_delay);}
}

主要代码解析

        我们可以看到,多线程其实很简单。        

        主要就是函数 xTaskCreate( ) :创建一个线程,然后在线程内运行 TaskBlink1( ) 函数。

  • TaskBlink1 :这个任务运行的函数
  •  "Task Blink1":给人看的名字
  • 2048 :任务栈的大小,用于存储任务运行时的上下文信息。简单来说,就是最多存这么多信息
  •  (void*) &blink_delay1 :任务参数。要么没有填NULL;要么必须为无类型指针
  • 2 :优先级
  • NULL : 任务的句柄,用于管理和控制任务,NULL相当于0,意味着此处不需要任务句柄

五、多核下的多线程

        有些板子有多个核,比如:ESP32S3有两个核,本身就可以就可以让两个核单独控制一个LED,实现上文双线程的效果。所以说,对于有两个核的ESP32S3,既可以指定某一个核运行俩线程,也可以指定俩核单独运行一个线程,而实现相同的效果。

        这里介绍俩核各自运行一个线程,各自控制一个LED的闪烁。

        话不多说,上代码:

#include <Arduino.h>// #if CONFIG_FREERTOS_UNICORE
// #define ARDUINO_RUNNING_CORE 0
// #else
// #define ARDUINO_RUNNING_CORE 1
// #endif#define LED_U0RXD 44
#define LED_U0TXD 43// 创建两个任务,
// TaskBlink1任务:一个LED 1s亮一次,
// TaskBlink2任务:另一个LED 2s亮一次。
void TaskBlink1(void *pvParameters);
void TaskBlink2(void *pvParameters);void setup() {Serial.begin(115200);xTaskCreatePinnedToCore(TaskBlink1,  "TaskBlink1"   // 任务名,  1024  // This stack size can be checked & adjusted by reading the Stack Highwater,  NULL,  2  // 任务优先级, with 3 (configMAX_PRIORITIES - 1) 是最高的,0是最低的.,  NULL ,  0); // 第一个核xTaskCreatePinnedToCore(TaskBlink2,  "TaskBlink2" //任务名,  1024  // 栈大小,  NULL,  1  // 任务优先级,  NULL ,  1); // 第二个核//现在,接管单个任务调度控制的任务调度程序将自动启动。
}void loop()
{// Empty. Things are done in Tasks.
}/*---------------------- Tasks ---------------------*/void TaskBlink1(void *pvParameters){  // This is a task.uint32_t blink_delay = 1000;// 初始化LED_U0RXD为output模式pinMode(LED_U0RXD, OUTPUT);
// for死循环for (;;){ // 多线程,每个任务必须是死循环digitalWrite(LED_U0RXD, HIGH);   // turn the LED on (HIGH is the voltage level)delay(blink_delay);digitalWrite(LED_U0RXD, LOW);    // turn the LED off by making the voltage LOWdelay(blink_delay);}
}void TaskBlink2(void *pvParameters){  // This is a task.uint32_t blink_delay = 2000;// 初始化LED_U0RXD为output模式pinMode(LED_U0TXD, OUTPUT);for (;;){ // A Task shall never return or exit.digitalWrite(LED_U0TXD, HIGH);   // turn the LED on (HIGH is the voltage level)delay(blink_delay);digitalWrite(LED_U0TXD, LOW);    // turn the LED off by making the voltage LOWdelay(blink_delay);}
}

主要代码解析

        我们可以看到,多核、多线程其实也很简单。        

        主要就是函数 xTaskCreatePinnedToCore ( ) :创建一个线程,并指定哪一个核运行线程,然后在线程内运行 TaskBlink1( ) 函数。与函数 xTaskCreate( ) 相比只多了指定运行的核,这一步。 

  • TaskBlink1 :这个任务运行的函数
  •  "Task Blink1":给人看的名字
  • 2048 :任务栈的大小,用于存储任务运行时的上下文信息。简单来说,就是最多存这么多信息
  •  (void*) &blink_delay1 :任务参数。要么没有填NULL;要么必须为无类型指针
  • 2 :优先级
  • NULL : 任务的句柄,用于管理和控制任务,NULL相当于0,意味着此处不需要任务句柄
  • 0 :第一个核。只有俩核,只能填0或1

最后,我有话说:

        如果文章对你有帮助,我很开心。有疑问,请留言,看到后,我会回复。

这篇关于ESP32S3——多线程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1034154

相关文章

Android多线程下载见解

通过for循环开启N个线程,这是多线程,但每次循环都new一个线程肯定很耗内存的。那可以改用线程池来。 就以我个人对多线程下载的理解是开启一个线程后: 1.通过HttpUrlConnection对象获取要下载文件的总长度 2.通过RandomAccessFile流对象在本地创建一个跟远程文件长度一样大小的空文件。 3.通过文件总长度/线程个数=得到每个线程大概要下载的量(线程块大小)。

如何在Android中实现多线程与线程池?

目录 一、Android介绍二、什么是多线程三、什么是线程池四、如何在Android中实现多线程与线程池 一、Android介绍 Android是一种基于Linux内核的开源操作系统,由Google公司领导开发。它最初于2007年发布,旨在为移动设备提供一种统一、可扩展的操作系统。Android系统以其高度的可定制性和丰富的应用生态而受到广泛欢迎,如今已经成为全球最流行的

【c2】编译预处理,gdb,makefile,文件,多线程,动静态库

文章目录 1.编译预处理:C源程序 - 编译预处理【#开头指令和特殊符号进行处理,删除程序中注释和多余空白行】- 编译2.gdb调试:多进/线程中无法用3.makefile文件:make是一个解释makefile中指令的命令工具4.文件:fprint/fgets/fwrite/fread,ftell/rewind/fseek/fflush4.1 文本文件:FILE结构体4.2 二进制文件:没

多线程简单运用---时钟的实现

效果图:   代码: package game;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Container;import java.awt.Font;import java.awt.event.ActionEvent;import java.awt.event.ActionListe

多线程的简单应用----彩票摇号器

效果图:   package game;import java.awt.BorderLayout;import java.awt.Container;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.Random;import javax.swing.JBu

通过简单的售票程序理解多线程

售票程序要求:1:多个窗口同时卖票  2:同一编号的票的不能多次卖出   错误程序解析: public class TicketDemo {public static void main(String[] args) {Ticket t1=new Ticket("窗口1:");Ticket t2=new Ticket("窗口2:");Ticket t3=new Ticket("窗口3

多线程相关方法详解

Thread中的方法 start()   用start() 方法来启动线程,真正实现了多线程运行,这时无需等待run() 方法内代码执行完毕,而是直接继续执行下面的代码。通过start()方法启动一个线程后,线程处于就绪状态,并没有运行,一旦得到CPU时间片,就开始执行run()方法。 注意:多次start()启动一个线程是非法的 run()   run()称为线程体,它包含了要执

如何保证单例模式在多线程中的线程安全性

如何保证单例模式在多线程中的线程安全性         对大数据、分布式、高并发等知识的学习必须要有多线程的基础。这里讨论一下如何在多线程的情况下设计单例模式。在23中设计模式中单例模式是比较常见的,在非多线程的情况下写单例模式,考虑的东西会很少,

Java多线程:线程8锁案例分析

线程8锁案例分析 通过分析代码,推测打印结果,并运行代码进行验证 1、两个线程调用同一个对象的两个同步方法 被synchronized修饰的方法,锁的对象是方法的调用者。因为两个方法的调用者是同一个,所以两个方法用的是同一个锁,先调用方法的先执行。 public class Demo {public static void main(String[] args) {Number numbe

多线程环境下 System.out.println 导致死锁问题分析

背景 一个文件采集系统,使用了多线程递归采集指定目录下的文件,并为每个目录创建一个线程去采集。 这个应用每隔几天就出现罢工情况,查看进程还在,堆内存空间还很充足,就是导出堆栈时,发现几乎所有的采集线程都处于 BLOCKED 状态了: "thread/dir/1718963987160" #82581 prio=5 os_prio=0 tid=0x00007f498c109000 nid=0x