广州第一网站,上海比较有名的大公司有哪些,做风控的网站,网站排名优化推广公司来自#xff1a;http://blog.csdn.net/xukai871105/article/details/43456985 0.前言 在嵌入式操作系统中互斥型信号量是任务间资源保护的重要手段。下面结合一个具体例子说明FreeRTOS中的互斥型信号量如何使用。 【相关博文】 【FreeRTOS STM32移植笔记】 【FreeRTOS学习笔记…来自http://blog.csdn.net/xukai871105/article/details/43456985 0.前言 在嵌入式操作系统中互斥型信号量是任务间资源保护的重要手段。下面结合一个具体例子说明FreeRTOS中的互斥型信号量如何使用。 【相关博文】 【FreeRTOS STM32移植笔记】 【FreeRTOS学习笔记——任务间使用队列同步数据】 【FreeRTOS学习笔记——二值型信号量】 【如何在FreeRTOS下实现低功耗——MSP430F5438平台】 【代码链接】——示例代码存于百度网盘 1.基本说明
互斥型信号量的使用方法如图1所示。在多数情况下互斥型信号量和二值型信号非常相似但是从功能上二值型信号量用于同步而互斥型信号量用于资源保护。互斥型信号量和二值型信号量还有一个最大的区别互斥型信号量可以有效解决优先级反转现象。图1 互斥型信号量使用方法2.参考代码 本例具有两个任务两个任务都试图通过串口打印内容此时串口就好比一个“资源”某个任务使用串口资源时必须保护该资源使用完串口之后在释放资源。保护和释放动作便对应互斥型信号量的两个基本操作xSemaphoreTake和xSemaphoreGive。【代码】[cpp] view plaincopy /* Standard includes. */ #include stdio.h #include string.h /* Scheduler includes. */ #include FreeRTOS.h #include task.h #include queue.h #include semphr.h /* Library includes. */ #include stm32f10x.h #define LED0_ON() GPIO_SetBits(GPIOB,GPIO_Pin_5); #define LED0_OFF() GPIO_ResetBits(GPIOB,GPIO_Pin_5); static void Setup(void); void TaskA( void *pvParameters ); void TaskB( void *pvParameters ); void LedInit(void); void UART1Init(void); /* 互斥信号量句柄 */ SemaphoreHandle_t xSemaphore NULL; int main(void) { /* 初始化硬件平台 */ Setup(); /* 创建互斥信号量 */ xSemaphore xSemaphoreCreateMutex(); /* 建立任务 */ xTaskCreate( TaskA, TaskA, configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY3, NULL ); xTaskCreate( TaskB, TaskB, configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY4, NULL ); /* 启动OS */ vTaskStartScheduler(); return 0; } void TaskA( void *pvParameters ) { for( ;; ) { xSemaphoreTake( xSemaphore, portMAX_DELAY ); { printf(Task A\r\n); } xSemaphoreGive( xSemaphore ); vTaskDelay( 2000/portTICK_RATE_MS ); } } void TaskB( void *pvParameters ) { for( ;; ) { xSemaphoreTake( xSemaphore, portMAX_DELAY ); { printf(Task B\r\n); } xSemaphoreGive( xSemaphore ); vTaskDelay( 1000/portTICK_RATE_MS ); } } static void Setup( void ) { LedInit(); UART1Init(); } void LedInit( void ) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); /*LED0 GPIOB.5*/ GPIO_InitStructure.GPIO_Pin GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_Init( GPIOB, GPIO_InitStructure ); } void UART1Init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; /* 第1步打开GPIO和USART时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE); /* 第2步将USART1 TxPA9的GPIO配置为推挽复用模式 */ GPIO_InitStructure.GPIO_Pin GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure); /* 第3步将USART1 RxPA10的GPIO配置为浮空输入模式 */ GPIO_InitStructure.GPIO_Pin GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, GPIO_InitStructure); GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure); /* 第4步配置USART1参数 波特率 9600 数据长度 8 停止位 1 校验位 No 禁止硬件流控(即禁止RTS和CTS) 使能接收和发送 */ USART_InitStructure.USART_BaudRate 9600; USART_InitStructure.USART_WordLength USART_WordLength_8b; USART_InitStructure.USART_StopBits USART_StopBits_1; USART_InitStructure.USART_Parity USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, USART_InitStructure); /* 第5步使能 USART1 配置完毕 */ USART_Cmd(USART1, ENABLE); /* 清除发送完成标志 */ USART_ClearFlag(USART1, USART_FLAG_TC); /* 使能USART1发送中断和接收中断并设置优先级 */ NVIC_InitTypeDef NVIC_InitStructure; // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); /* 设定USART1 中断优先级 */ NVIC_InitStructure.NVIC_IRQChannel USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority configLIBRARY_KERNEL_INTERRUPT_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelSubPriority 0; NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; NVIC_Init(NVIC_InitStructure); /* 使能接收中断 */ // USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); } int fputc(int ch, FILE *f) { /* 写一个字节到USART1 */ USART_SendData(USART1, (uint8_t) ch); /* 等待发送结束 */ while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) RESET) {} return ch; } 3.简单说明 SemaphoreHandle_t xSemaphore NULL;申明互斥型信号量在FreeRTOS中二值型信号量和互斥型信号量类型完全相同。xSemaphore xSemaphoreCreateMutex();
创建互斥型信号量。xSemaphoreTake( xSemaphore, portMAX_DELAY ); //Take拿资源
获得资源的使用权此处的等待时间为portMAX_DELAY挂起最大时间如果任务无法获得资源的使用权任务会处于挂起状态。xSemaphoreGive( xSemaphore ); //Give给出资源 释放资源的使用权。4.总结 互斥型信号量和二值型信号量使用方法相似但二值型信号量用于同步而互斥型信号量用于资源保护。