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

继续上一篇任务创建

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

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

①、通过任务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打印】

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ching·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值