当前位置: 首页 > article >正文

Linux下基于最新稳定版ESP-IDF5.3.2开发esp32s3入门任务间的通讯-信号量【入门三】

继续上一篇任务创建

【Linux下基于最新稳定版ESP-IDF5.3.2开发esp32s3入门任务创建【入门二】-CSDN博客】

今天要实现再创建一个任务。【二值和互斥都进行测试】

①、通过任务A发送一个信号量,另一个任务得到信号量后再发送helloworld。

②、两个任务通过互斥信号量打印消息。

一、创建任务。

这和上一篇一样,我们再创建一个同样优先级的任务SendSemTask

	xTaskCreatePinnedToCore(SendSemTask,
							"SendSemTask",
							2048,
							NULL,
							4,
							NULL,
							1);

二、先来看下我们要用到的API

1、xSemaphoreCreateBinary()创建二值信号量

2、xSemaphoreTake(xSemaphore, xBlockTime)等待一个信号量【形参:xSemaphore信号量句柄,xBlockTime等等时间】【返回:pdTRUE才是获取到】

3、xSemaphoreGive(xSemaphore)发送一个信号量

注意:我们这里是任务间的通讯所以使用以上的三个API,如果你要在中断中使用需要使用带FromISR结尾的API。

如:xSemaphoreTakeFromISR。

三、创建二值信号量【因为参数有句柄->所以我们需要先定义一个信号量句柄】

SemaphoreHandle_t s_tSem;

创建信号量,这个信号量创建需要再任务创建前就创建好。因为任务中要用。

s_tSem = xSemaphoreCreateBinary();

四、任务中发送信号量

1000ms发送一个信号量

xSemaphoreGive(s_tSem);

五、获取信号量,获取到信号量打印get semaphore

获取信号量,我们等等时间使用一直等等。也就是得到一个信号量才往下执行输出

xSemaphoreTake(s_tSem, portMAX_DELAY)

注意:我这里是使用一直等等,所以没有vTaskDelay。如果你使用0。那就必须要等等,否则优先级比该任务低的任务都不能得到执行。

六、编译下载验证【和预期的一样1000ms打印一次】

===========================以下测试互斥信号量===============================

为什么我们要使用互斥信号量?

实际项目中我们的系统往往是多个任务运行的,而且各个任务优先级是不一样的,如果多个任务刚好又需要用到同一资源的时候,这时候多个任务调用这共有资源的时刻是不确定的。

假如:低优先级的任务先使用资源的时候,如果还没有使用完,高优先级的任务也使要用这共有资源就会打断低优先级的任务,这时候可能:低优先级执行异常甚至系统奔溃。

所以我们希望的是等低优先级任务使用完这资源后,这资源再被其他任务使用。

一、重新cp一份刚才的工程【可以修改下文件名,我修改如下】

二、先来看下我们要用到的API

创建互斥锁:xSemaphoreCreateMutex()也可以用上面的信号量创建函数。

三、定义一个打印函数,这里增加延迟是为了模拟出效果。

void testPrintf(char *param)
{

    printf("%s starting\r\n", param);
    printf("1======2345678\r\n");
        vTaskDelay(100 / portTICK_PERIOD_MS);
    printf("2======2345678\r\n");
        vTaskDelay(100 / portTICK_PERIOD_MS);
    printf("3======2345678\r\n");
        vTaskDelay(100 / portTICK_PERIOD_MS);
    printf("4======2345678\r\n");
        vTaskDelay(100 / portTICK_PERIOD_MS);
    printf("5======2345678\r\n");
        vTaskDelay(100 / portTICK_PERIOD_MS);
    printf("6======2345678\r\n");
        vTaskDelay(100 / portTICK_PERIOD_MS);
    printf("7======2345678\r\n");
        vTaskDelay(100 / portTICK_PERIOD_MS);
    printf("8======2345678\r\n");
        vTaskDelay(100 / portTICK_PERIOD_MS);
    printf("9======2345678\r\n");
        vTaskDelay(100 / portTICK_PERIOD_MS);
    printf("1======2345678\r\n");
        vTaskDelay(100 / portTICK_PERIOD_MS);
    printf("%s end\r\n", param);
}

四、创建两个任务,两个任务的优先级需要不一样。【这里一个优先级3,一个优先级4】

	//	创建一个互斥信号量
	s_tMux = xSemaphoreCreateMutex();


	xTaskCreatePinnedToCore(TaskA,
							"TaskA",
							2048,
							NULL,
							3,
							NULL,
							1);

	xTaskCreatePinnedToCore(TaskB,
							"TaskB",
							2048,
							NULL,
							4,
							NULL,
							1);

五、两个任务都打印testPrintf【我们先不使用互斥信号量看下效果】

void TaskA(void *param)
{
	while(1)
	{
		testPrintf("TaskA");
		vTaskDelay(1000 / portTICK_PERIOD_MS);
	}
}

void TaskB(void *param)
{
	while(1)
	{
		testPrintf("TaskB");
		vTaskDelay(900 / portTICK_PERIOD_MS);
	}
}

六、下载验证。看下效果

七、增加互斥信号量看下效果【这里的互斥信号量和前面的信号量是一样的】

void TaskA(void *param)
{
	while(1)
	{
		xSemaphoreTake(s_tMux, portMAX_DELAY);
		testPrintf("TaskA");
		xSemaphoreGive(s_tMux);
		vTaskDelay(1000 / portTICK_PERIOD_MS);
	}
}

void TaskB(void *param)
{
	while(1)
	{
		xSemaphoreTake(s_tMux, portMAX_DELAY);
		testPrintf("TaskB");
		xSemaphoreGive(s_tMux);
		vTaskDelay(900 / portTICK_PERIOD_MS);
	}
}

这里申请一个信号量后,等使用完了,再释放。

八、下载验证。【最后的1是打印任务是1-9-1打印】

至此,实现了互斥锁。下一篇我们一起看下消息队列。


http://www.kler.cn/a/447557.html

相关文章:

  • springboot463学生信息管理系统论文(论文+源码)_kaic
  • 西游记战力排名、笔记等
  • 每日十题八股-2024年12月21日
  • Docker:Dockerfile(补充四)
  • 深入了解Python模拟负载均衡器:将请求高效分发至多个服务器
  • 时间序列异常值检测方法
  • 前端项目打包部署后,如何避免让用户强制去清除浏览器缓存
  • STM32低功耗模式结合看门狗
  • 【RK3588 Linux 5.x 内核编程】-内核中断与ThreadedIRQ
  • 学习Cookie 提升
  • 裸机按键输入实验
  • linux源码编译libunwind
  • 条款34 考虑lambda而非std::bind
  • JS中的innerHTML,innerText,value的区别
  • STM32-笔记5-按键点灯(中断方法)
  • java线程
  • Unity实用技能-协作规范总结
  • MySQL数据库下载及安装教程
  • linux美化命令行
  • 文件I/O操作:C语言
  • 纯血鸿蒙APP实战开发——Text实现部分文本高亮和超链接样式
  • el-tabs标签过多
  • TCP与UDP的端口连通性
  • Ubuntu22.04安装CH340/CH341驱动
  • Python自动化测试图片比对算法
  • 电商项目-网站首页高可用(二)