FreeRTOS--计数信号量
时间:2019-09-04
本文章向大家介绍FreeRTOS--计数信号量,主要包括FreeRTOS--计数信号量使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
计数信号量有两种典型的用法:
1.事件计数:
每次事件发生时,中断ISR会释放(Give)信号量,信号量的计数值加1 。事件处理任务每次处理一个事件会获取(Take)一次信号量,计数值减1. 信号量的值就是已发生事件数目与已处理事件数目之间的差值。用于事件的计数的计数信号量,在被创建时其计数值被初始化为0。
2.资源管理:
信号量的计数值表示可用资源的数目,一个任务获取资源的控制权,必须先获取(Take)信号量,使信号的计数值减1。当资源总数为0,表示没有资源可用。当任务利用资源完成工作后,归还信号量,信号量的计数值加1.用于资源管理的信号量,在被创建时其计数值为可用的最大资源数。
典型的生产者与消费者问题如下图示:
这里对生产者与消费者问题,进行验证:
资源:生产线上有5个箱子(共享资源),一开始都是空的。
生产者:先判断在5个箱子(共享资源)中有木有空箱子,若有空箱子则向空箱子放入数字(依次放入1,2,…10);若无空箱子则需要等待。
消费者:先判断在5个箱子(共享资源)中有木有已放入数字的箱子,若有则取出箱子的数字,进行累加处理,若无则需要等待。
1 #define BOX_NUM 5 2 uint32_t box[BOX_NUM]; 3 uint32_t put = 0,get = 0; 4 5 6 void MX_FREERTOS_Init(void) { 7 /* USER CODE BEGIN Init */ 8 9 /* USER CODE END Init */ 10 11 12 /* Create the semaphores(s) */ 13 /* definition and creation of lockSem */ 14 osSemaphoreDef(lockSem); 15 //lockSem用于对共享资源的互斥访问 16 lockSemHandle = osSemaphoreCreate(osSemaphore(lockSem), 1); 17 18 /* definition and creation of emptySem */ 19 osSemaphoreDef(emptySem); 20 //emptySem代表空箱子的资源数,初始计数值5 21 emptySemHandle = osSemaphoreCreate(osSemaphore(emptySem), 5); 22 23 /* definition and creation of fullsem */ 24 //fullSem代表装有数字箱子的资源数,初始计数值0 25 fullsemHandle = xSemaphoreCreateCounting(5, 0); 26 27 /* USER CODE BEGIN RTOS_TIMERS */ 28 /* start timers, add new ones, ... */ 29 /* USER CODE END RTOS_TIMERS */ 30 31 /* Create the thread(s) */ 32 /* definition and creation of vTask1 */ 33 osThreadDef(vTask1, producer_task, osPriorityNormal, 0, 256); 34 vTask1Handle = osThreadCreate(osThread(vTask1), NULL); 35 36 /* definition and creation of vTaks2 */ 37 osThreadDef(vTaks2, consumer_task, osPriorityHigh, 0, 256); 38 vTaks2Handle = osThreadCreate(osThread(vTaks2), NULL); 39 40 /* USER CODE BEGIN RTOS_THREADS */ 41 /* add threads, ... */ 42 /* USER CODE END RTOS_THREADS */ 43 44 /* USER CODE BEGIN RTOS_QUEUES */ 45 /* add queues, ... */ 46 /* USER CODE END RTOS_QUEUES */ 47 } 48 49 /* producer_task function */ 50 void producer_task(void const * argument) 51 { 52 53 /* USER CODE BEGIN producer_task */ 54 static int Count = 0; 55 /* Infinite loop */ 56 while(Count < 10) 57 { 58 //尝试获取一个空箱子 59 osSemaphoreWait(emptySemHandle,osWaitForever); 60 61 //互斥访问共享资源 62 osSemaphoreWait(lockSemHandle,osWaitForever); 63 64 //向空箱子放入数字 65 box[put % BOX_NUM] = Count + 1; 66 67 printf("the producer package box[%d] which content is : %d\n",put % BOX_NUM,box[put % BOX_NUM]); 68 69 //放入数字次数 70 put++; 71 72 //当对共享资源访问完毕,解锁。 73 osSemaphoreRelease(lockSemHandle); 74 75 //释放一个“满”信号量,代表已完成对一个box的加工 76 osSemaphoreRelease(fullsemHandle); 77 78 //循环执行次数 79 Count++; 80 81 //生产者休息一会 82 osDelay(20); 83 } 84 85 printf("producer finish!!!!!\n"); 86 87 osThreadSuspend(vTask1Handle); 88 /* USER CODE END producer_task */ 89 } 90 91 /* consumer_task function */ 92 void consumer_task(void const * argument) 93 { 94 /* USER CODE BEGIN consumer_task */ 95 static int sum = 0; 96 /* Infinite loop */ 97 while(1) 98 { 99 //尝试获取一个已放入数字箱子 100 osSemaphoreWait(fullsemHandle,osWaitForever); 101 102 //互斥访问共享资源 103 osSemaphoreWait(lockSemHandle,osWaitForever); 104 105 //获取箱子里数字进行累加计算 106 sum = sum + box[get % BOX_NUM]; 107 108 printf("the consumer : box[%d] get a num %d\n",get%BOX_NUM, box[get%BOX_NUM]); 109 110 //获取数字的次数 111 get++; 112 113 //当对共享资源访问完毕,解锁。 114 osSemaphoreRelease(lockSemHandle); 115 116 //释放一个空箱子资源 117 osSemaphoreRelease(emptySemHandle); 118 119 //获取10次数字后退出 120 if(get == 10) 121 { 122 break; 123 } 124 125 osDelay(120); 126 } 127 128 printf("the consumer sum is: %d\n", sum); 129 printf("the consumer exit!\n"); 130 131 osThreadSuspend(vTaks2Handle); 132 /* USER CODE END consumer_task */ 133 }
测试验证结果:
原文地址:https://www.cnblogs.com/mickey-double/p/11457667.html
- 使用xUnit为.net core程序进行单元测试(1)
- 用 Identity Server 4 (JWKS 端点和 RS256 算法) 来保护 Python web api
- asp.net core 2.0 查缺补漏
- SQL Server 性能优化之——T-SQL NOT IN 和 NOT Exists
- SQL Server 性能优化之——重复索引
- SQL Server 性能优化之——系统化方法提高性能
- C# 调用PowerShell方法
- 使用Visual Studio 2010 一步一步创建Powershell Module 和 Cmdlet
- [SQLServer大对象]——FileTable初体验
- JavaScript闭包,只学这篇就会了
- [数据库基础]——编码标准之格式
- [数据库基础]——编码标准之结构
- 2017前端开发手册三-前端职位描述
- [.NET自我学习]Delegate 泛型
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 想用深度学习谱写自己的音乐吗?这篇指南来帮你!(附代码)
- 你不是说你会aop吗?
- 开源:推荐一个不错的离线IP地址定位库
- 武磊告别西甲!Python带你解读「全村的希望」武磊职业数据
- 谁在崛起,谁在没落?新一线城市竞争力盘点,用Python绘制动态图带你看懂!
- 两数相加
- 这样设置 IDEA,让你爽到飞起!
- Tensorflow基础入门十大操作总结
- Spring Boot 2.x基础教程:使用EhCache缓存集群
- 白平衡初探
- Activity的启动过程详解(基于10.0源码)
- Activity生命周期-你真的了解吗?
- Activity启动模式
- Redis6.0主从、哨兵、集群搭建和原理
- Linux入门学习笔记二