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.
**************************************************************************************************/