TI-RTOS 之 事件同步(Event, 类似semaphore)
TI-RTOS 之 事件同步(Event, 类似semaphore)
Event 是类似Semaphore的存在,官方如下描述:
SYS/BIOS events are a means of communication between Tasks and other threads such as Hwis, Swis, and other Tasks, or between Tasks and other SYS/BIOS objects. Other SYS/BIOS objects include semaphores, mailboxes, message queues, etc. Only tasks can wait for events; whereas tasks, Hwis, Swis, or SYS/BIOS objects can post them.
重点是它可用来处理任务间,任务与中断间同步。主要的API有以下:

此前我们作GPIO中断演示时,曾在中断中为了消抖而非常勉强地使用一个函数 CPUdelay(), 这样可以实现我们的目标,不过CPU仍然要进行计算,而且是在中断之中,有可能会影响到其他Task的执行时间。同样也会增加系统的功耗。如果使用Event就能解决这类问题。
思路 是这样, 用一个任务专门来处理按键,在没有按键时,任务处于Sleep状态,当按键按下时,它的中断会唤醒这个任务,唤醒的方法就是使用Event, 唤醒之后,可以再次Sleep一小段时间,用于消抖,然后再去读按键的状态,之后再进行处理。
完整的演示代码如下:
/**************************************************************************************************
Filename: keyDemo2.c
Editor: Tome @ newbit
Revised: $Date: 2016-8-11 11:20:02 +0800 $
Revision: $Revision: 00001 $
Description: 了解 TI-RTOS的使用之,Event的使用,它用来同步任务,或者
Task - Hwis, Swis
History:
Notes: 要了解到这部分的接口,可阅读TI文档
1. TI-RTOS 2.20 User's Guide.pdf
2. Bios User Guide.pdf
硬件平台 CC1130_LAUNCHPAD Rev1.3
**************************************************************************************************/
/**************************************************************************************************
// INCLUDES
**************************************************************************************************/
/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Event.h>
/* TI-RTOS Header files */
#include <ti/drivers/PIN.h>
#include "Board.h"
/**************************************************************************************************
// TYPEDEF
**************************************************************************************************/
/**************************************************************************************************
// CONSTANTS
**************************************************************************************************/
#define TASKSTACKSIZE 768
/**************************************************************************************************
// LOCAL VERIABLE
**************************************************************************************************/
Task_Struct keyTaskStruct;
Char keyTaskStack[TASKSTACKSIZE]; // 本任务的栈空间,静态分配
/* Global memory storage for a PIN_Config table */
static PIN_State ledPinState;
static PIN_State buttonPinState;
PIN_Handle ledPinHandle;
PIN_Handle buttonPinHandle;
// 新建 Event, 它用来通知任务,按键已经按下
Event_Struct evtStruct;
Event_Handle evtHandle;
/*
* Initial LED pin configuration table
* - LEDs Board_LED0 is on.
* - LEDs Board_LED1 is off.
*/
PIN_Config ledPinTable[] = {
Board_LED0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
Board_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
PIN_TERMINATE
};
/*
* Application button pin configuration table:
* - Buttons interrupts are configured to trigger on falling edge.
*/
PIN_Config buttonPinTable[] = {
Board_BUTTON0 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
Board_BUTTON1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
PIN_TERMINATE
};
/**************************************************************************************************
// FUNCTIONS DECLERATION
**************************************************************************************************/
Void keyFxn(UArg arg0, UArg arg1);
void buttonCallbackFxn(PIN_Handle handle, PIN_Id pinId);
/**************************************************************************************************
// FUNCTIONS
**************************************************************************************************/
/**************************************************************************************************
* @fn keyTaskAdd
*
* @brief
*
* @param void
*
* @return void
**************************************************************************************************/
void keyTaskAdd(void)
{
Task_Params taskParams;
/* Construct BIOS objects */
Task_Params_init(&taskParams); // 创建任务所要的参数,都设置为默认值
taskParams.stackSize = TASKSTACKSIZE; // 栈空间
taskParams.stack = &keyTaskStack; // 栈地址
// 向bios 传递参数,建立控制灯的任务
Task_construct(&keyTaskStruct, (Task_FuncPtr)keyFxn, &taskParams, NULL);
}
/*
* ======== keyFxn ========
* Task for this function is created statically. See keyTaskAdd().
*/
Void keyFxn(UArg arg0, UArg arg1)
{
uint_t ledState;
Event_Params evtParams;
Event_Params_init(&evtParams);
Event_construct(&evtStruct, &evtParams);
evtHandle = Event_handle(&evtStruct);
// 这里不是为了初始化,而是为了拿到操作的句柄 (handle)
// 函数说明:Allocate one or more pins for a driver or an application.
ledPinHandle = PIN_open(&ledPinState, ledPinTable);
if(!ledPinHandle) {
System_abort("Error initializing board LED pins\n");
}
// 得到按键IO的操作句柄
buttonPinHandle = PIN_open(&buttonPinState, buttonPinTable);
if(!buttonPinHandle) {
System_abort("Error initializing button pins\n");
}
/* Setup callback for button pins */
// 注册按键的中断回调函数
if (PIN_registerIntCb(buttonPinHandle, &buttonCallbackFxn) != 0) {
System_abort("Error registering button callback function");
}
//
while(1)
{
// 任务将在这里阻塞,直到有键按下
Event_pend(evtHandle,Event_Id_00, Event_Id_NONE, BIOS_WAIT_FOREVER );
// 任务休眠 20 ms 用于消抖
/* Debounce logic, only toggle if the button is still pushed (low) */
Task_sleep(20*100);
// 读取按键的状态,并控制灯
if ( !PIN_getInputValue(Board_BUTTON0))
{
ledState = PIN_getOutputValue(Board_LED0);
PIN_setOutputValue(ledPinHandle, Board_LED0, !ledState);
}
if ( !PIN_getInputValue(Board_BUTTON1))
{
ledState = PIN_getOutputValue(Board_LED1);
PIN_setOutputValue(ledPinHandle, Board_LED1, !ledState);
}
}
}
/**************************************************************************************************
* @fn buttonCallbackFxn
*
* @brief 按键中断的回调函数
*
* @param PIN_Handle handle, PIN_Id pinId
*
* @return void
**************************************************************************************************/
void buttonCallbackFxn(PIN_Handle handle, PIN_Id pinId)
{
// 解除任务的阻塞
Event_post(evtHandle, Event_Id_00 );
}
/**************************************************************************************************
Copyright 2016 Newbit Studio. All rights reserved.
**************************************************************************************************/
TI-RTOS 之 事件同步(Event, 类似semaphore)的更多相关文章
- C++多线程同步之事件(Event)
原文链接:http://blog.csdn.net/olansefengye1/article/details/53291074 一.事件(Event)原理解析 1.线程同步Event,主要用于线程间 ...
- 锁机制(Lock) 信号量机制(Semaphore) 事件机制(Event)
IPC 进程间通信(inter-Process Communicate) 锁机制(Lock) l = Lock() 开启一个锁机制(实例化) 一把锁配一个钥匙 l.acquire() 获得钥匙 ...
- 并发编程概述 委托(delegate) 事件(event) .net core 2.0 event bus 一个简单的基于内存事件总线实现 .net core 基于NPOI 的excel导出类,支持自定义导出哪些字段 基于Ace Admin 的菜单栏实现 第五节:SignalR大杂烩(与MVC融合、全局的几个配置、跨域的应用、C/S程序充当Client和Server)
并发编程概述 前言 说实话,在我软件开发的头两年几乎不考虑并发编程,请求与响应把业务逻辑尽快完成一个星期的任务能两天完成绝不拖三天(剩下时间各种浪),根本不会考虑性能问题(能接受范围内).但随着工 ...
- Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
code&monkey Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...
- 事件循环Event loop到底是什么
摘要:本文通过结合官方文档MDN和其他博客深入解析浏览器的事件循环机制,而NodeJS有另一套事件循环机制,不在本文讨论范围中.process.nextTick和setImmediate是NodeJS ...
- Cocos2d-X3.0 刨根问底(七)----- 事件机制Event源码分析
这一章,我们来分析Cocos2d-x 事件机制相关的源码, 根据Cocos2d-x的工程目录,我们可以找到所有关于事件的源码都存在放在下图所示的目录中. 从这个event_dispatcher目录中的 ...
- Ext JS treegrid 发生的在tree上增加itemclick 与在其它列上增加actioncolumn 发生事件冲突(event conflict)的解决办法
Ext JS treegrid 发生的在tree上增加itemclick 与在其它列上增加actioncolumn 发生事件冲突(event conflict)的解决办法 最近在适用Ext JS4开发 ...
- JavaScript:事件对象Event和冒泡
本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. 绑定事件的两种方式 我们在上一篇文章中已经讲过事件的概念.这里讲一下注册 ...
- mysql 事件(Event) 总结
1 事件简介 事件(event)是MySQL在相应的时刻调用的过程式数据库对象.一个事件可调用一次,也可周期性的启动,它由一个特定的线程来管理的,也就是所谓的“事件调度器”. 事件和触发器类似,都是在 ...
随机推荐
- Swift学习第二天--面向对象
//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...
- shell脚本-批量执行机器命令
场景:通过跳板机,批量获取线上机器日志 使用方式:run2 host 'ls -al /home/admin/' #! /bin/sh USER_NAME=$USER if [ $# -ne 2 ]; ...
- [编织消息框架][JAVA核心技术]异常基础
Java异常体系结构 Thorwable类所有异常和错误的超类,有两个子类Error和Exception,分别表示错误和异常. 其中异常类Exception又分为运行时异常(RuntimeExcept ...
- vim 当前用户显示行号
在 -/.vimrc 中添加 set nu 如果文件不存在可以直接新建这个文件 -表示当前用户的主目录
- shiro中 UnknownAccountException
一 shiro的session.request和response与服务端容器自身的这三个对象的关系 在web.xml中配置了一个Filter,拦截/*,所有的uri.在拦截器中还会调用ShiroFil ...
- php SeasLog使用以及liunx环境下安装
1.下载SeasLog http://pecl.php.net/package/SeasLog php官方 https://github.com/Neeke/SeasLog 作者的github 2. ...
- 适合小白/外行的git与github最基础最浅显教程
首先声明,这是适合小白/外行/初学者/学生看的最基础最简单的git与github教程,已经能使用svn,git等工具的朋友请不要看这篇文章来浪费时间了. 想进一步学习git的,推荐去廖雪峰博客学习. ...
- Spring之设置Bean值
Java实例的属性值可以有很多种数据类型.基本类型值.字符串类型.java实例甚至其他的Bean实例.java集合.数组等.所以Spring允许通过如下几个元素为Bean实例的属性指定值: value ...
- 通过 python的 __call__ 函数与元类 实现单例模式
简单一句话,当一个类实现__call__方法时,这个类的实例就会变成可调用对象. 直接上测试代码 class ClassA: def __call__(self, *args, **kwargs): ...
- Hadoop2.9.0安装
参考 https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html 1.下载并解 ...