FreeRTOS学习笔记——互斥型信号量

来自:http://blog.csdn.net/xukai871105/article/details/43456985

0.前言

    在嵌入式操作系统中互斥型信号量是任务间资源保护的重要手段。下面结合一个具体例子说明FreeRTOS中的互斥型信号量如何使用。


    【相关博文】
    【FreeRTOS STM32移植笔记
【FreeRTOS学习笔记——任务间使用队列同步数据】
【FreeRTOS学习笔记——二值型信号量】
【如何在FreeRTOS下实现低功耗——MSP430F5438平台】
【代码链接】——示例代码存于百度网盘

1.基本说明
互斥型信号量的使用方法如图1所示。在多数情况下,互斥型信号量和二值型信号非常相似,但是从功能上二值型信号量用于同步,而互斥型信号量用于资源保护。互斥型信号量和二值型信号量还有一个最大的区别,互斥型信号量可以有效解决优先级反转现象。

图1 互斥型信号量使用方法

2.参考代码
    本例具有两个任务,两个任务都试图通过串口打印内容,此时串口就好比一个“资源”,某个任务使用串口资源时必须保护该资源,使用完串口之后在释放资源。保护和释放动作便对应互斥型信号量的两个基本操作,xSemaphoreTakexSemaphoreGive
【代码】
[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. /* Standard includes. */  
  2. #include <stdio.h>  
  3. #include <string.h>  
  4.   
  5. /* Scheduler includes. */  
  6. #include "FreeRTOS.h"  
  7. #include "task.h"  
  8. #include "queue.h"  
  9. #include "semphr.h"  
  10.   
  11. /* Library includes. */  
  12. #include "stm32f10x.h"  
  13.   
  14. #define LED0_ON()   GPIO_SetBits(GPIOB,GPIO_Pin_5);  
  15. #define LED0_OFF()  GPIO_ResetBits(GPIOB,GPIO_Pin_5);  
  16.   
  17. static void Setup(void);  
  18. void TaskA( void *pvParameters );  
  19. void TaskB( void *pvParameters );  
  20.   
  21. void LedInit(void);  
  22. void UART1Init(void);  
  23.   
  24. /* 互斥信号量句柄 */  
  25. SemaphoreHandle_t xSemaphore = NULL;  
  26.   
  27. int main(void)  
  28. {  
  29.     /* 初始化硬件平台 */  
  30.     Setup();  
  31.     /* 创建互斥信号量 */  
  32.     xSemaphore = xSemaphoreCreateMutex();  
  33.     /* 建立任务 */  
  34.     xTaskCreate( TaskA, "TaskA", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+3, NULL );  
  35.     xTaskCreate( TaskB, "TaskB", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+4, NULL );  
  36.     /* 启动OS */  
  37.     vTaskStartScheduler();  
  38.       
  39.     return 0;  
  40. }  
  41.   
  42. void TaskA( void *pvParameters )  
  43. {  
  44.     for( ;; )  
  45.     {  
  46.         xSemaphoreTake( xSemaphore, portMAX_DELAY );  
  47.         {  
  48.             printf("Task A\r\n");  
  49.         }  
  50.         xSemaphoreGive( xSemaphore );  
  51.         vTaskDelay( 2000/portTICK_RATE_MS );  
  52.     }  
  53. }  
  54.   
  55. void TaskB( void *pvParameters )  
  56. {  
  57.     for( ;; )  
  58.     {  
  59.         xSemaphoreTake( xSemaphore, portMAX_DELAY );  
  60.         {  
  61.             printf("Task B\r\n");  
  62.         }  
  63.         xSemaphoreGive( xSemaphore );  
  64.         vTaskDelay( 1000/portTICK_RATE_MS );  
  65.     }  
  66. }  
  67.   
  68. static void Setup( void )  
  69. {  
  70.     LedInit();  
  71.     UART1Init();  
  72. }  
  73.   
  74. void LedInit( void )  
  75. {  
  76.     GPIO_InitTypeDef GPIO_InitStructure;  
  77.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );  
  78.     /*LED0 @ GPIOB.5*/  
  79.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;  
  80.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  81.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
  82.     GPIO_Init( GPIOB, &GPIO_InitStructure );      
  83. }  
  84.   
  85. void UART1Init(void)  
  86. {  
  87.     GPIO_InitTypeDef GPIO_InitStructure;  
  88.     USART_InitTypeDef USART_InitStructure;  
  89.       
  90.     /* 第1步:打开GPIO和USART时钟 */  
  91.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);  
  92.       
  93.     /* 第2步:将USART1 Tx@PA9的GPIO配置为推挽复用模式 */  
  94.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  
  95.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
  96.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  97.     GPIO_Init(GPIOA, &GPIO_InitStructure);  
  98.       
  99.     /* 第3步:将USART1 Rx@PA10的GPIO配置为浮空输入模式 */  
  100.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  
  101.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  102.     GPIO_Init(GPIOA, &GPIO_InitStructure);  
  103.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  104.     GPIO_Init(GPIOA, &GPIO_InitStructure);  
  105.       
  106.     /* 第4步:配置USART1参数 
  107.     波特率   = 9600 
  108.     数据长度 = 8 
  109.     停止位   = 1 
  110.     校验位   = No 
  111.     禁止硬件流控(即禁止RTS和CTS) 
  112.     使能接收和发送 
  113.     */  
  114.     USART_InitStructure.USART_BaudRate = 9600;  
  115.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;  
  116.     USART_InitStructure.USART_StopBits = USART_StopBits_1;  
  117.     USART_InitStructure.USART_Parity = USART_Parity_No;  
  118.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
  119.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  
  120.     USART_Init(USART1, &USART_InitStructure);  
  121.       
  122.     /* 第5步:使能 USART1, 配置完毕 */  
  123.     USART_Cmd(USART1, ENABLE);  
  124.       
  125.     /* 清除发送完成标志 */  
  126.     USART_ClearFlag(USART1, USART_FLAG_TC);  
  127.       
  128.     /* 使能USART1发送中断和接收中断,并设置优先级 */  
  129.     NVIC_InitTypeDef NVIC_InitStructure;  
  130.     // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  
  131.     /* 设定USART1 中断优先级 */  
  132.     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  
  133.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_KERNEL_INTERRUPT_PRIORITY;   
  134.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
  135.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  136.     NVIC_Init(&NVIC_InitStructure);  
  137.     /* 使能接收中断 */  
  138.     // USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);   
  139. }  
  140.   
  141. int fputc(int ch, FILE *f)  
  142. {  
  143.     /* 写一个字节到USART1 */  
  144.     USART_SendData(USART1, (uint8_t) ch);  
  145.     /* 等待发送结束 */  
  146.     while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)  
  147.     {}  
  148.     return ch;  
  149. }  

3.简单说明
SemaphoreHandle_t xSemaphore = NULL;
申明互斥型信号量,在FreeRTOS中二值型信号量和互斥型信号量类型完全相同。

xSemaphore = xSemaphoreCreateMutex();
创建互斥型信号量。

xSemaphoreTake( xSemaphore, portMAX_DELAY ); //Take:拿资源
获得资源的使用权,此处的等待时间为portMAX_DELAY(挂起最大时间),如果任务无法获得资源的使用权,任务会处于挂起状态。

 xSemaphoreGive( xSemaphore ); //Give:给出资源
    释放资源的使用权。

4.总结
    互斥型信号量和二值型信号量使用方法相似,但二值型信号量用于同步而互斥型信号量用于资源保护。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458592.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JSP动态网站环境搭建应用中的详细步骤(Tomcat和Apache/IIS的整合)

链接地址&#xff1a;http://www.cnblogs.com/dartagnan/archive/2011/03/25/2003426.html JSP动态网站环境搭建应用中的详细步骤(Tomcat和Apache/IIS的整合)sun推出的JSP&#xff08;Java Server Pages&#xff09;是一种执行于服务器端的动态网页开发技术&#xff0c;它基于J…

关于JS获取select值的两种实现方法

前几天发了一篇关于javascript获取select值的方法&#xff0c;后来发现有另一种实现方法&#xff0c;所以就都发出来比较一下&#xff1a; 方法一&#xff1a;通过获取option标签的value值来确定&#xff1a; <!DOCTYPE html> <html> <head><meta charset…

c语言题库1

1. 用预处理指令#define 声明一个常数&#xff0c;用以表明1年中有多少秒&#xff08;忽略闰年问题&#xff09; #define time (365*24*60*60) #define SECONDS_PER_YEAR (60 * 60 * 24 * 365) 2. 写一个“标准”宏MIN&#xff0c;这个宏输入两个参数并返回较小的一个。 #di…

FreeRTOS系列第19篇---FreeRTOS信号量

来自&#xff1a;http://blog.csdn.net/zhzht19861011/article/details/50835613 本文介绍信号量的基础知识&#xff0c;详细源码分析见《FreeRTOS高级篇6---FreeRTOS信号量分析》 1.信号量简介 FreeRTOS的信号量包括二进制信号量、计数信号量、互斥信号量&#xff08;以后简称…

mysql语法替换字符串

UPDATE ht_business_task SET url REPLACE ( url, &amp;, & )转载于:https://www.cnblogs.com/lz20150121/p/5030739.html

POJ1274 The Perfect Stall(二分图)

题意&#xff1a; 一些奶牛只有在特定的围栏中才能产奶&#xff0c;要求合理安排使能产奶的奶牛数达到最大。 要点&#xff1a; 二分图裸题&#xff0c;最近刚学了二分图&#xff0c;看下面的参考博客&#xff0c;写的比较好&#xff1a; 参考博客&#xff1a;匈牙利算法 15479…

蓝牙HCI剖析(一)

来自&#xff1a;http://blog.csdn.net/xiaoxiaopengbo/article/details/51334257 一.HCI介绍 HCI提供了访问bluetooth control的统一接口&#xff0c;通俗来讲&#xff0c;就是定义了特定的格式来控制蓝牙芯片来做相应的动作&#xff08;比如inquiry,connect,disconnect&#…

c语言题库2

96. struct name1{ char str; short x; int num; } struct name2{ char str;0 1 2 3 int num; 4 5 6 7 short x; 8 9 10 11 } sizeof(struct name1)? sizeof(struct name2)? 8、12 97. 读文件file1.txt的内容&#xff08;例如&#xff09;&#xff1a; 12 34 56 …

ASP.NET状缓存Cache的应用-提高数据库读取速度

ASP.NET状缓存Cache的应用-提高数据库读取速度 原文:ASP.NET状缓存Cache的应用-提高数据库读取速度一、 Cache概述 既然缓存中的数据其实是来自数据库的&#xff0c;那么缓存中的数据如何和数据库进行同步呢&#xff1f;一般来说&#xff0c;缓存中应该存放改动不大或者对…

2016年学习Linux决心书(老男孩教育在线课程班第二期)

我经过这4-5个月的学习后&#xff0c;我一定要达到月薪20&#xff2b;&#xff0c;为了达到这个目标我要付出如下10大行动&#xff1a;1.提前预习上课内容2.上课认真听讲&#xff0c;做好上课笔记3.课后认真做总结&#xff0c;完善笔记5.反复做实验&#xff0c;并写实验文档6.学…

WPF XAML 从零开始认识XAML

来自&#xff1a;http://blog.csdn.net/aoshilang2249/article/details/44158403 剖析最简单的XMAL代码: [html] view plaincopy <Window x:Class"MyFirstApplication.MainWindow" xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentati…

c语言题库3

143. 枚举元素本身由系统定义了一个表示序号的数值&#xff0c;从0 开始顺序定义为0&#xff0c;1&#xff0c;2…。如在weekday中&#xff0c;sun值为0&#xff0c;mon值为1&#xff0c; …,sat值为6。 main(){  enum weekday  {   sun,mon,tue,wed,thu,fri,sat  } a,b…

入门级----测试的执行、环境的搭建、每日构建、测试记录和跟踪、回归测试、测试总结和报告...

测试用例的准备&#xff0c;都是为了执行测试准备的。 测试环境的搭建 &#xff08;1&#xff09;测试数据&#xff1a;有些测试需要使用大批量的数据&#xff0c;例如容量测试、压力测试等。根据产品的具体测试要求&#xff0c;可能需要在数据库表插入大量的数据&#xff0c;准…

MFC读取配置文件GetPrivateProfileString

VC中 3 个主要 写入/读取配置文件ini的函数&#xff1a;bool WritePrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpString,LPCTSTR lpFileName);写入.ini文件&#xff1b;DWORDGetPrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpD…

UESTC 250 windy数 数位dp

题目链接 1 #include<bits/stdc.h>2 using namespace std;3 #define mem1(a) memset(a, -1, sizeof(a))4 #define ll long long5 int dp[20][20], digit[20], len;6 ll dfs(int len, int pre, bool fp, bool first) { //first表示前面的数是否全部为0&#xff0c; pr…

c语言面试题大全

C语言面试题大汇总 4. static有什么用途&#xff1f;&#xff08;请至少说明两种&#xff09; 1.限制变量的作用域(DL:使其只在定义的当前文件中起作用&#xff0c;static是只能由与变量在同一个文件中定义的程序存取的全局变量。也就是说使全局变量成为文件的私有变量&#…

WindowsAPI详解——GetCurrentDirectory 获得程序当前目录

每个Windows程序都有一个自己的当前目录&#xff0c;默认是程序exe文件所在的目录。系统在给程序加载动态链接库文件(DLL)时先在程序当前目录里查找要加载的DLL&#xff0c;如果在此目录下没有找到系统便会去Windows目录下查找。在这儿我们主要将如何获得程序的当前目录&#x…

20151210小问题2

1、各浏览器下 scrollTop的差异 IE6/7/8&#xff1a; 对于没有doctype声明的页面里可以使用 document.body.scrollTop 来获取 scrollTop高度 &#xff1b; 对于有doctype声明的页面则可以使用 document.documentElement.scrollTop&#xff1b; Safari: safari 比较特别&#x…

限制MySQL Binlog的传输速率

最近一台核心库备库完成恢复后打开slave&#xff0c;导致主库传送binlog&#xff0c;瞬间占满网络&#xff0c;触发故障。 为了做一些限制&#xff0c; 给mysql在发送binlog的函数(mysql_binlog_send)里每隔一段时间sleep一次&#xff0c; 增加了两个参数&#xff1a; master_s…

sprintf用法详解

printf可能是许多程序员在开始学习C语言时接触到的第二个函数&#xff08;我猜第一个是main&#xff09;&#xff0c;说起来&#xff0c;自然是老朋友了&#xff0c;可是&#xff0c;你对这个老朋友了解多吗&#xff1f;你对它的那个孪生兄弟sprintf了解多吗&#xff1f;在将各…