FreeRTOS源码分析-10 互斥信号量

这篇具有很好参考价值的文章主要介绍了FreeRTOS源码分析-10 互斥信号量。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

 

1 事件标志组概念及其应用

1.1 事件标志组定义

1.2 FreeRTOS事件标志组介绍

1.3 FreeRTOS事件标志组工作原理

2 事件标志组应用

2.1 功能需求

2.2 API

 2.3 功能实现

3 事件标志组原理

3.1 事件标志组控制块

3.2 事件标志组获取标志位

3.3 等待事件标志触发

3.4 事件标志组设置标志位

3.5 事件标志组任务同步


1 事件标志组概念及其应用

1.1 事件标志组定义

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

门钥匙代表或的问题,每个都可以开启
公交车代表与的问题,到齐了才可以走

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

FreeRTOS事件标志组一共8个bit。

如Task 1或Tast 2去触发第1位,第1位或第三位能触发任务Task3

如Task 6、7、8同时置位触发Task 4

1.2 FreeRTOS事件标志组介绍

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

任务可以和事件标志组进行关联,如bit23,任务阻塞等待消息,和消息队列一样有个超时机制

当任意任务或者中断触发置位的时候,任务会从阻塞变为就绪态。

1.3 FreeRTOS事件标志组工作原理

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

 创建事件控制块,关联事件,等待事件触发

2 事件标志组应用

2.1 功能需求

  • 1、使用事件标志组检测多个按键输入(K3、K4、K5、K6)
  • 2、当检测到任何一个按键按下,串口打印输出按键信息
  • 3、当4路按键都已经按下,触发蜂鸣器报警

2.2 API

CubeMX中未提供,需要自己创建

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

 EventBits_t 返回值返回的是所有24位的值FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

守护任务:处理操作系统不想在中断中处理的任务,是一种特殊类型的任务,它在系统中扮演着重要的角色。它被用于监控和处理FreeRTOS内部的错误和异常情况,以确保系统的稳定性。守护任务可以使用软件定时器来执行一些周期性的任务。通过创建一个周期性的软件定时器,守护任务可以在固定的时间间隔内执行特定的操作。例如,守护任务可以使用软件定时器来定期检查任务堆栈的使用情况、检测任务优先级错误或处理未处理的中断等。软件定时器提供了一种简便的方式来触发守护任务的执行,以确保系统中的重要任务得到及时处理。FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

中断中不允许上下文切换,都是由守护任务来执行的。

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32 使用WaitBits,会让任务进入阻塞态

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

 参数解释:

  • xEventGroup:事件组句柄,表示要操作的事件组。
  • uxBitsToWaitFor:等待的事件位,即需要等待其中的哪些事件发生。可以使用位掩码形式指定多个事件位。若指定为0,则表示不等待任何事件,直接返回当前事件组的位状态。
  • uxBitsToSet:设置的事件位,即在等待期间发生事件后,需要设置哪些事件位。同样,可以使用位掩码指定多个事件位。
  • xTicksToWait:等待的超时时间,以FreeRTOS的Tick单位表示。可以设置为portMAX_DELAY表示无限等待,或者具体的等待时间。

返回值:

  • 返回已经发生的事件位,即满足等待条件的事件。如果等待发生事件时超时,则返回0。

使用xEvetnGroupSync函数的具体步骤如下:

  1. 创建或获取一个事件组句柄。
  2. 使用xEvetnGroupSync函数等待指定的事件位。可以设置需要等待的事件位、需要设置的事件位和等待超时时间。
  3. 根据返回值判断等待是否成功,根据已发生的事件位执行相应的操作。

注意,xEvetnGroupSync函数是一个阻塞函数,即在等待期间会阻塞当前任务的执行。如果有其他任务在等待相同的事件组,则它们可能会被唤醒以执行后续操作。因此,在使用xEvetnGroupSync函数时需要谨慎设计,以避免出现死锁或优先级反转等问题。

 2.3 功能实现

STM32CubeMX功能配置

GPIO略

根据接口说明 ,事件标志组中断中需要开启守护任务

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

 FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

按键中断及事件标志组创建

//freertos.c

//...略
#include "event_groups.h"

EventGroupHandle_t KeyEventGroup; //全局变量句柄

void MX_FREERTOS_Init(void) {

	//创建
	KeyEventGroup = xEventGroupCreate();
	if(KeyEventGroup == NULL){
		printf("KeyEventGroup Create Error\r\n");
	}

    //...略
}

按键检测任务和蜂鸣器报警任务

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

 FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

//gpio.c

#include "event_groups.h"

//...略
/*  
#define KEY3_EVENT_BIT  (1<<0)
#define KEY4_EVENT_BIT  (1<<1)
#define KEY5_EVENT_BIT  (1<<2)
#define KEY6_EVENT_BIT  (1<<3) 
	 
typedef enum
{
	KEY_DOWN,
	KEY_UP,
	KEY_RESET

}teKeyStatus;

*/

teKeyStatus KeyStatus;
extern EventGroupHandle_t KeyEventGroup;


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){

	if(Key3_Pin == GPIO_Pin)
    {
		if(HAL_GPIO_ReadPin(Key3_GPIO_Port,Key3_Pin) == GPIO_PIN_RESET)
        {
			HAL_Delay(10);
			if(HAL_GPIO_ReadPin(Key3_GPIO_Port,Key3_Pin) == GPIO_PIN_RESET)
            {
                //设置事件
				xEventGroupSetBitsFromISR(KeyEventGroup,KEY3_EVENT_BIT,NULL);
			}
		}
	}
	
	if(Key4_Pin == GPIO_Pin)
    {
		if(HAL_GPIO_ReadPin(Key4_GPIO_Port,Key4_Pin) == GPIO_PIN_RESET)
        {
			HAL_Delay(10);
			if(HAL_GPIO_ReadPin(Key4_GPIO_Port,Key4_Pin) == GPIO_PIN_RESET)
            {
                //设置事件
				xEventGroupSetBitsFromISR(KeyEventGroup,KEY4_EVENT_BIT,NULL);
			}
		}
	}

	if(Key5_Pin == GPIO_Pin)
    {
		if(HAL_GPIO_ReadPin(Key5_GPIO_Port,Key5_Pin) == GPIO_PIN_RESET)
        {
			HAL_Delay(10);
			if(HAL_GPIO_ReadPin(Key5_GPIO_Port,Key5_Pin) == GPIO_PIN_RESET)
            {
                //设置事件
				xEventGroupSetBitsFromISR(KeyEventGroup,KEY5_EVENT_BIT,NULL);
			}
		}
	}

	if(Key6_Pin == GPIO_Pin)
    {
		if(HAL_GPIO_ReadPin(Key6_GPIO_Port,Key6_Pin) == GPIO_PIN_RESET)
        {
			HAL_Delay(10);
			if(HAL_GPIO_ReadPin(Key6_GPIO_Port,Key6_Pin) == GPIO_PIN_RESET)
            {
                //设置事件
				xEventGroupSetBitsFromISR(KeyEventGroup,KEY6_EVENT_BIT,NULL);
			}
		}
	}
}
//freertos.c



void Delay_Task(void const * argument)
{
  /* USER CODE BEGIN Delay_Task */
	EventBits_t KeyEventBits;
  /* Infinite loop */
  for(;;)
  {
	  KeyEventBits = xEventGroupWaitBits(KeyEventGroup,
							KEY3_EVENT_BIT|KEY4_EVENT_BIT|KEY5_EVENT_BIT|KEY6_EVENT_BIT,
								pdFALSE,
								pdFALSE,
								portMAX_DELAY);
	  printf("Key is Down Key Event Bit is %x\r\n",KeyEventBits);
	  osDelay(10);
  }
}




void High_Task(void const * argument)
{
  EventBits_t KeyEventBits;
  for(;;)
  {
	  KeyEventBits = xEventGroupWaitBits(KeyEventGroup,
							KEY3_EVENT_BIT|KEY4_EVENT_BIT|KEY5_EVENT_BIT|KEY6_EVENT_BIT,
								pdTRUE,
								pdTRUE,
								portMAX_DELAY);	
	  if(KeyEventBits == (KEY3_EVENT_BIT|KEY4_EVENT_BIT|KEY5_EVENT_BIT|KEY6_EVENT_BIT))
      {
		printf("Buzzer is Toggle\r\n");
		HAL_GPIO_TogglePin(Buzzer_GPIO_Port,Buzzer_Pin);
	  }
      osDelay(10);
  }
}

3 事件标志组原理

3.1 事件标志组控制块

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32


	
	#define eventCLEAR_EVENTS_ON_EXIT_BIT	0x01000000UL		//表示退出是否清楚已经触发的标志位 25bit表示
	#define eventUNBLOCKED_DUE_TO_BIT_SET	0x02000000UL		//解除阻塞是否,已经设置标志位 26位
	#define eventWAIT_FOR_ALL_BITS			0x04000000UL		//是与逻辑还是或逻辑
	#define eventEVENT_BITS_CONTROL_BYTES	0xff000000UL		//用于分解出,事件标志组位使用

typedef struct xEventGroupDefinition
{
	//事件标志组
	EventBits_t uxEventBits;
	//任务等待的列表
	List_t xTasksWaitingForBits;		/*< List of tasks waiting for a bit to be set. */
} EventGroup_t;

3.2 事件标志组获取标志位

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

 全局变量一定要保护,所以要进入临界段

#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )

/*
	参数:
	1、控制块/句柄
	2、要清除位
	返回值:
		事件标志位

*/ 1<<0
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
{
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
EventBits_t uxReturn;

	/*
		1、进入临界段
		2、获取当前事件标志位
		3、清除要设置的事件标志位
		4、退出临界段
		5、返回事件标志组值
	
	*/
	taskENTER_CRITICAL();
	{

		/* The value returned is the event group value prior to the bits being
		cleared. */
		uxReturn = pxEventBits->uxEventBits;

		/* Clear the bits. */
		pxEventBits->uxEventBits &= ~uxBitsToClear;
	}
	taskEXIT_CRITICAL();

	return uxReturn;
}

/*
	参数:	
		1、事件控制块
	返回值:
		事件标志位

*/
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
{
UBaseType_t uxSavedInterruptStatus;
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
EventBits_t uxReturn;
	
	//禁止中断 带返回值
	uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
	{
		//获取事件标志位
		uxReturn = pxEventBits->uxEventBits;
	}
	//恢复中断,在进入禁止之前的状态
	portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );

	return uxReturn;
}

3.3 等待事件标志触发

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

 复位列表项:表示事件信息

/*
	参数:
		1、事件控制块
		2、要等待出发的标志位
		3、退出是否要清除
		4、与逻辑还是或逻辑
		5、阻塞等待时间
	返回值:
		当前事件标志位
*/
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, 
								const EventBits_t uxBitsToWaitFor, 
								const BaseType_t xClearOnExit, 
								const BaseType_t xWaitForAllBits, 
								TickType_t xTicksToWait )
{
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
EventBits_t uxReturn, uxControlBits = 0;
BaseType_t xWaitConditionMet, xAlreadyYielded;
BaseType_t xTimeoutOccurred = pdFALSE;
	//挂起调度器
	vTaskSuspendAll();
	{
		//获取当前的事件标志位
		const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;

		/* 检查是否触发 
			参数:	
				1、当前的事件标志位
				2、要等待触发的事件标志位
				3、触发逻辑???
			返回值:	
				pdFALSE  pdTRUE
		*/
		xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );

		if( xWaitConditionMet != pdFALSE )
		{
			
			/* 已经触发 */
			uxReturn = uxCurrentEventBits;
			xTicksToWait = ( TickType_t ) 0;

			/* 清楚已经触发的标志 */
			if( xClearOnExit != pdFALSE )
			{
				pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}
		}
		else if( xTicksToWait == ( TickType_t ) 0 )
		{
			/* 不需要超时,直接返回标志位. */
			uxReturn = uxCurrentEventBits;
		}
		else
		{
			/* 事件没有触发,并且需要超时*/
			if( xClearOnExit != pdFALSE )
			{
				//uxControlBits = 0x01000000UL;
				uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}

			if( xWaitForAllBits != pdFALSE )
			{
				//uxControlBits = 0x05000000UL;
				uxControlBits |= eventWAIT_FOR_ALL_BITS;
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}

			/* 把任务添加到事件列表中
				参数:
					1、列表的地址
					2、传入列表项值
					3、任务阻塞时间

			*/
			vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );

			uxReturn = 0;

			traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
		}
	}
	//恢复调度器
	xAlreadyYielded = xTaskResumeAll();
	//再次判断是否需要超时
	if( xTicksToWait != ( TickType_t ) 0 )
	{
		if( xAlreadyYielded == pdFALSE )
		{
			//进行上下文切换 ->pendSV
			portYIELD_WITHIN_API();
		}
		else
		{
			mtCOVERAGE_TEST_MARKER();
		}

		/* 
			任务已经恢复
			1、复位列表项中的值  复位为任务有优先级
		*/
		uxReturn = uxTaskResetEventItemValue();
		//是不是通过事件置位解除的任务
		if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
		{
			//进入临界段
			taskENTER_CRITICAL();
			{
				/* 获取当前事件位. */
				uxReturn = pxEventBits->uxEventBits;

				/* 再此判断是否已经置位 */
				if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
				{
					//如果需要清除,清除触发后的标志位
					if( xClearOnExit != pdFALSE )
					{
						pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
					}
					else
					{
						mtCOVERAGE_TEST_MARKER();
					}
				}
				else
				{
					mtCOVERAGE_TEST_MARKER();
				}
			}
			taskEXIT_CRITICAL();
			xTimeoutOccurred = pdFALSE;
		}
		else
		{
			/* The task unblocked because the bits were set. */
		}

		/* 返回当前事件标志位. */
		uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
	}
	traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );

	return uxReturn;
}

3.4 事件标志组设置标志位

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

/*
	参数:
		1、事件控制块
		2、要设置的事件位
	返回值:
		1、当前事件标志位
*/
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
{
ListItem_t *pxListItem, *pxNext;
ListItem_t const *pxListEnd;
List_t *pxList;
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
BaseType_t xMatchFound = pdFALSE;

	//获取事件列表头
	pxList = &( pxEventBits->xTasksWaitingForBits );
	//获取列表尾节点
	pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
	//挂起调度器
	vTaskSuspendAll();
	{
		//获取头节点
		pxListItem = listGET_HEAD_ENTRY( pxList );

		/* 设置事件标志位 */
		pxEventBits->uxEventBits |= uxBitsToSet;

		/* 循环遍历整个列表项,直到列表头节点等于尾节点(指针) */
		while( pxListItem != pxListEnd )
		{
			//获取下个列表项
			pxNext = listGET_NEXT( pxListItem );
			//获取当前列表项的值
			uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem );
			//标记,是否找到需要处理的节点
			xMatchFound = pdFALSE;

			/* 拆分*/
			uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES;
			uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES;

			if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 )
			{
				//或逻辑
				/* 等待位已经置位 */
				if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 )
				{
					//找到了已经触发的节点
					xMatchFound = pdTRUE;
				}
				else
				{
					mtCOVERAGE_TEST_MARKER();
				}
			}
			//表示所有等待的位都已经触发
			else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor )
			{
				/*找到触发的节点 */
				xMatchFound = pdTRUE;
			}
			else
			{
				/* Need all bits to be set, but not all the bits were set. */
			}

			if( xMatchFound != pdFALSE )
			{
				/* 是否需要清除 */
				if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 )
				{
					//做个标记
					uxBitsToClear |= uxBitsWaitedFor;
				}
				else
				{
					mtCOVERAGE_TEST_MARKER();
				}

				/* 把任务从事件列表中移除
					参数:	
						1、列表项
						2、事件标志位+解锁处理标志位  内部写入了列表项的value里面

				*/
				( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
			}

			/* 当前列表项指向下个,继续遍历*/
			pxListItem = pxNext;
		}

		/* 清除设置后的标志位 */
		pxEventBits->uxEventBits &= ~uxBitsToClear;
	}
	//开启调度器
	( void ) xTaskResumeAll();

	return pxEventBits->uxEventBits;
}

	/*
		参数:
		1、事件控制块
		2、要设置的标志位
		3、NULL
	*/
	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
	{
	BaseType_t xReturn;
		//调用软件定时器函数,,用于发送消息到软件定时器任务,进行处理
		xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );

		return xReturn;
	}
	/*
		设置事件标志位的回调函数,内部其实就是调用xEventGroupSetBits
	*/
	void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
	{
	( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
	}
	
	BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken )
	{
	DaemonTaskMessage_t xMessage;
	BaseType_t xReturn;

		/* 封装消息 */
		xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR;
		xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;
		xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;
		xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2;
		//通过消息队列和软件定时器任务进行通信
		xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );
		/*
			分析:
				软件定时器任务要等待消息队列,之后解析处理,最终调用xEventGroupSetBits
		
		*/

		return xReturn;
	}

3.5 事件标志组任务同步

FreeRTOS源码分析-10 互斥信号量,FreeRTOS源码分析,物联网,单片机,stm32

 待完成文章来源地址https://www.toymoban.com/news/detail-631935.html

到了这里,关于FreeRTOS源码分析-10 互斥信号量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 二、操作系统进程管理(10)——用信号量机制实现进程互斥、同步、前驱关系

        (1)分析并发进程的关键活动,划定临界区。(如对临界区资源打印机的访问就应放在临界区)     (2)设置互斥信号量mutex,初值为1。     (3)在临界区之前执行P(mutex)。      //即使用资源前先申请(P操作)     (4)在临界区之后执行V(mutex)。     (5)对不

    2023年04月08日
    浏览(43)
  • 线程同步-信号量-互斥量-条件变量

    线程同步其实实现的是线程排队。 防止线程同步访问共享资源造成冲突。 多个线程访问共享资源的代码有可能是同一份代码,也有可能是不同的代码;无论是否执行同一份代码,只要这些线程的代码访问同一份可变的共享资源,这些线程之间就需要同步。 1. 问题 同一个进程

    2023年04月16日
    浏览(39)
  • TinyWebServer学习笔记-互斥锁、信号量、条件变量

    网站不可能是单线程的,否则网站的性能和响应都会收到严重的影响。因此,这个项目一定是运行在多线程条件下的。而在多线程条件下,对共享资源的互斥访问就极其重要。 首先,我们要明确资源的使用一般有三个步骤: 1、获取资源 2、使用资源 3、释放资源 然而,大多

    2024年02月07日
    浏览(49)
  • FreeRTOS教程5 信号量

    正点原子stm32f407探索者开发板V2.4 STM32CubeMX软件(Version 6.10.0) Keil µVision5 IDE(MDK-Arm) 野火DAP仿真器 XCOM V2.6串口助手 一个滑动变阻器 本文主要学习 FreeRTOS 信号量的相关知识, 包括创建/删除信号量、释放信号量、获取信号量等知识 信号量是进程间用于通信的一种手段,其是

    2024年03月15日
    浏览(46)
  • 【系统编程】线程安全(POSIX信号量、互斥锁、读写锁等)

    (꒪ꇴ꒪ ),Hello我是 祐言QAQ 我的博客主页:C/C++语言,数据结构,Linux基础,ARM开发板,网络编程等领域UP🌍 快上🚘,一起学习,让我们成为一个强大的攻城狮! 送给自己和读者的一句鸡汤🤔: 集中起来的意志可以击穿顽石! 作者水平很有限,如果发现错误,请在评论区指

    2024年02月10日
    浏览(67)
  • 【STM32】FreeRTOS消息队列和信号量学习

    一、消息队列(queue) 队列是一种用于实现任务与任务之间,任务与中断之间消息交流的机制。 注意:1.数据的操作是FIFO模式。 2.队列需要明确数据的大小和队列的长度。 3.写和读都会出现堵塞。 实验:创建一个消息队列,两个发送任务,一个接收任务。 其中任务一任务三

    2024年02月13日
    浏览(41)
  • 一文搞定Linux线程间通讯 / 线程同步方式-互斥锁、读写锁、自旋锁、信号量、条件变量、信号等等

    目录 线程间通讯 / 线程同步方式 锁机制 互斥锁(Mutex) 读写锁(rwlock) 自旋锁(spin) 信号量机制(Semaphore) 条件变量机制 信号(Signal) 线程间通讯 / 线程同步方式 p.s 以下有很多段落是直接引用,没有使用 markdown 的 “引用” 格式,出处均已放出。 参考 / 引用: 100as

    2024年02月10日
    浏览(44)
  • 【Linux】详解进程通信中信号量的本质&&同步和互斥的概念&&临界资源和临界区的概念

             访问资源在安全的前提下,具有一定的顺序性,就叫做同步 。在多道程序系统中,由于资源有限,进程或线程之间可能产生冲突。同步机制就是为了解决这些冲突,保证进程或线程之间能够按照既定的顺序访问共享资源。同步机制有助于避免竞态条件和死锁(

    2024年04月25日
    浏览(46)
  • 6.物联网操作系统信号量

    一。信号量的概念与应用 信号量定义 FreeRTOS信号量介绍 FreeRTOS信号量工作原理 1.信号量的定义         多任务环境下使用,用来协调多个任务正确合理使用临界资源。 2.FreeRTOS信号量介绍         Semaphore包括Binary,Count,Mutex;         Mutex包括RecursiveMutex,Mutex。 3.Free

    2024年02月14日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包