FreeRTOS学习——同步互斥

本文详细介绍了FreeRTOS中的同步与互斥概念,通过实例展示了有缺陷的同步和互斥问题,并提供优化方案,强调了正确使用FreeRTOS提供的同步机制如信号量、互斥量和队列的重要性。

FreeRTOS学习——同步互斥

一、概念

1.1 同步

在FreeRTOS中,同步是指任务之间按照某种规则进行协调和按序执行的过程。其目的是保证任务或线程之间的有序交互,使它们能够按照预期的顺序完成各自的操作或实现特定的约束条件。常见的同步场景包括等待其他任务完成、等待某个条件满足、协调任务之间的依赖关系等。

FreeRTOS提供了多种同步机制,例如信号量、互斥量、消息队列等,用于实现任务之间的同步。这些机制可以帮助任务之间进行协作,以确保它们按照一定的顺序、时机和约束进行执行。

同步机制在FreeRTOS中非常重要,因为它们可以确保系统的正确性和稳定性。如果没有同步机制,任务之间可能会出现竞争条件,导致系统行为不可预测。通过使用同步机制,FreeRTOS可以确保任务之间的正确交互,从而提高系统的可靠性和性能。

1.2 互斥

FreeRTOS中,互斥是一种同步机制,用于保护共享资源,确保任务访问这些资源时的原子性,避免数据错误。具体来说,互斥是指在多任务环境中,运行特定代码段时确保数据的一致性和完整性,避免多个任务同时访问和修改共享资源导致错误的发生。它通过互斥量(又称互斥信号量)来实现,互斥量是一种特殊的二值信号量,用于实现对临界资源的独占式处理。任意时刻互斥量的状态只有两种,开锁或闭锁。当互斥量被任务持有时,该互斥量处于闭锁状态,这个任务获得互斥量的所有权。当该任务释放这个互斥量时,该互斥量处于开锁状态,任务失去该互斥量的所有权。当一个任务持有互斥量时,其他任务将不能再对该互斥量进行开锁或持有。持有该互斥量的任务也能够再次获得这个锁而不被挂起,这就是递归访问,也就是递归互斥量的特性。

一句话理解同步与互斥:我等你用完厕所,我再用厕所。

什么叫同步?就是:哎哎哎,我正在用厕所,你等会。

什么叫互斥?就是:哎哎哎,我正在用厕所,你不能进来。

同步与互斥经常放在一起讲,是因为它们之的关系很大, “互斥”操作可以使用“同步”来实现。我“等”你用完厕所,我再用厕所。这不就是用“同步”来实现“互斥”吗?

二、示例——有缺陷的同步

实验目的:计算ul变量累加到1000000需要多长时间

具体实现:

创建2个Task,定义一个全局变量taskFlag,当taskFlag等于1时表示Task1正在运行,当taskFlag等于0时表示Task2正在运行

Task1:

  • Task1中定义一个累加变量ul
  • 第一次运行Task1(开始累加ul)时记录系统此刻tick时间vstartTime
  • 当ul>1000000(ul累加完毕)时记录系统此刻tick时间vendTime
  • 累加完毕后将累加结束标志endFlag置位,将vendTime-vstartTime时间赋值给全局变量vtotleTime

Task2:

  • 判断全局变量endFlag是否置位
  • 若endFlag置位,打印出vtotleTime

实验代码:

#define mainDELAY_LOOP_COUNT 1000000

volatile TickType_t vtotleTime;
volatile TickType_t vstartTime = 0, vendTime = 0;
volatile bool endFlag = FALSE;
volatile bool endLock = FALSE;
volatile uint8_t taskFlag = 0;

void vTask1( void *pvParameters )
{
   
   
	volatile uint32_t ul; /* volatile用来避免被优化掉 */
	
	vstartTime = xTaskGetTickCount();
	/* 打印任务1的信息 */
	printf( "Count start: %d\r\n",vstartTime );	

	/* 任务函数的主体一般都是无限循环 */
	for( ;; )
	{
   
   	
		/* 表示Task1在运行 */
		taskFlag = 1;

		/* 延迟一会(比较简单粗暴) */
		if(endLock == FALSE)
		{
   
   
			ul++;

			if((ul > mainDELAY_LOOP_COUNT)  && (endFlag != TRUE))
			{
   
   
				endFlag = TRUE;
				vendTime = xTaskGetTickCount();
				vtotleTime = vendTime - vstartTime;
				vTaskDelay(10);
			}
		}		
	}
}

void vTask2( void *pvParameters )
{
   
   
	volatile uint32_t ul; /* volatile用来避免被优化掉 */
	
	/* 任务函数的主体一般都是无限循环 */
	for( ;; )
	
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

studyingdda

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

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

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

打赏作者

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

抵扣说明:

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

余额充值