cc3200php,TICC3200-TI-RTOS按键实现以及消息机制

本文包含以下内容:

1、基于TI-RTOS的线程创建

2、按键扫描的实现(短按、长按)

3、消息队列与同步对象

使用的例程:

C:\ti\CC3200SDK_1.2.0\cc3200-sdk\example\getting_started_with_wlan_station

我预先把TI例程创建的station给注释掉了~(仅仅为了测试~)

#if

0

//

// Start the

WlanStationMode task

//

lRetVal =

osi_TaskCreate( WlanStationMode, \

(const signed char*)"Wlan Station Task", \

OSI_STACK_SIZE, NULL, 1, NULL );

if(lRetVal

< 0)

{

ERR_PRINT(lRetVal);

LOOP_FOREVER();

}

#endif

TI-RTOS线程创建~

用到的API

OsiReturnVal_e osi_TaskCreate(P_OSI_TASK_ENTRY pEntry,const signed

char * const pcName,unsigned short usStackDepth,void

*pvParameters,unsigned long uxPriority,OsiTaskHandle

*pTaskHandle);

传入参数:

\param pEntry - pointer

to the Task Function

, 任务函数名

\param pEntry - pointer

to the Task Function

, 任务名称(取值随意)

\param usStackDepth - Stack

Size Stack Size in 32-bit long words , 任务栈深度(即你该任务所使用到的内存大小大致会有多大)

\param pvParameters - pointer

to structure to be passed to the Task Function , 传给该函数的指针

\param uxPriority - Task

Priority , 任务优先级

返回0即表示任务创建成功

示例代码:

lRetVal

= osi_TaskCreate( UserFunction, \

(const signed char*)"User Application Task", \

OSI_STACK_SIZE, NULL, 3, NULL );

if(lRetVal

< 0)

{

ERR_PRINT(lRetVal);

LOOP_FOREVER();

}

(注:一定要对返回值进行判断,这样才能确保创建是否成功,如果返回非零

返回的错误代码可参看osi.h:

typedef

enum

{

OSI_OK = 0,

OSI_FAILURE = -1,

OSI_OPERATION_FAILED = -2,

OSI_ABORTED = -3,

OSI_INVALID_PARAMS = -4,

OSI_MEMORY_ALLOCATION_FAILURE = -5,

OSI_TIMEOUT = -6,

OSI_EVENTS_IN_USE = -7,

OSI_EVENT_OPEARTION_FAILURE = -8

}OsiReturnVal_e;

自己添加的函数:

void

UserFunction( void *pvParameters )

{

MESSAGE

msg;

while(1)

{

UART_PRINT("UserFunction run \r\n");

osi_Sleep(1000);

}

}

以上一个线程创建完毕~,(在此可以使用uart打印消息来查看是否程序执行了~debug x下,每1s打印一次UserFunctionrun 的提示~说明线程创建完毕)。

大家可以多写其他线程来试试~~~

按键扫描实现~

独立按键,采用定时扫描IO口的方式。

前面一章有介绍IO口的初始化,不多说,看代码:

void

KeyPadInit()

{

// Enable

clock ... gpio 13 and gpio 22

MAP_PRCMPeripheralClkEnable(PRCM_GPIOA2, PRCM_RUN_MODE_CLK);

MAP_PRCMPeripheralClkEnable(PRCM_GPIOA3, PRCM_RUN_MODE_CLK);

// Configure

PIN_02 for GPIOOutput

MAP_PinTypeGPIO(PIN_15, PIN_MODE_0, false);

MAP_GPIODirModeSet(GPIOA1_BASE, GPIO_PIN_5,

GPIO_DIR_MODE_IN); // gpio13 -- pin15

MAP_PinTypeGPIO(PIN_04, PIN_MODE_0, false);

MAP_GPIODirModeSet(GPIOA2_BASE, GPIO_PIN_6,

GPIO_DIR_MODE_IN); // gpio22 -- pin04

}

// 扫描两个IO口的高低变化,有按键按下返回非零~

int

KeyPadScan(void)

{

int key =

0;

if(

GPIOPinRead(GPIOA2_BASE,GPIO_PIN_6) )

key = key | 0x01;

key = key

<< 1;

if(

GPIOPinRead(GPIOA1_BASE,GPIO_PIN_5) )

key = key | 0x01;

return key;

}

有RTOS干脆创建个线程来扫描按键好了~~贴代码~:

大致流程如下:每20ms检测一次IO口,如果一个或者多个按键按下那么KeyValue = KeyPadScan();

得到的值不为0计数值count+1,当count大于最小的检测值时(消抖)当成一次短按出现~串口打印相关信息

,当按键持续按下且时间超过长按的计数值则串口打印一次长按消息,当按键弹起打印按键弹起消息~。详细看上传的工程。

lRetVal

= osi_TaskCreate( KeyDetectFunction, \

(const signed char*)"User Key Detect Task", \

OSI_STACK_SIZE, NULL, 2, NULL );

if(lRetVal

< 0)

{

ERR_PRINT(lRetVal);

LOOP_FOREVER();

}

void

KeyDetectFunction( void *pvParameters )

{

static

unsigned int Count = 0;

static

KEY_TYPE KeyState = KEY_IDLE;

static

unsigned int KeyValue = 0;

static

unsigned int tKey = 0;

MESSAGE

tMSG;

unsigned

char ch[10];

memset(ch,0xaa,sizeof(ch));

ch[9] =

0xbb;

tMSG.uMsg =

MESSAGE_KEYDOWN;

while(1)

{

KeyValue = KeyPadScan();

if(0 != KeyValue)

{

Count ++;

if(Count >= KEY_MIN_DETECT_TIME && KeyState ==

KEY_IDLE)

{

// post short key press message

KeyState = KEY_PRESS_100MS;

UART_PRINT("Key short press %x \r\n",KeyValue);

tKey = KeyValue;

}

if(Count >= KEY_LONG_DETECT_TIME && KeyState ==

KEY_PRESS_100MS)

{

KeyState = KEY_PRESS_1S;

UART_PRINT("Key long press %x \r\n",KeyValue);

tKey =

KeyValue;

}

if(Count >= MAX_PRESS_TIME)

{ //

ERROR ~

KeyState = KEY_IDLE;

}

}

else

{

if(KeyState != KEY_IDLE)

{

KeyState = (KeyState == KEY_PRESS_100MS) ? KEY_100MS_RELEASE :

KEY_1S_RELEASE;

KeyValue = tKey;

UART_PRINT("Key release %x \r\n",KeyValue);

KeyState = KEY_IDLE;

}

Count = 0;

}

osi_Sleep(20);

}

}

以上~按键的检测部分完成,当然接下去是要抛消息给其他线程让其他线程来执行咯~

消息队列与同步对象

用到的API 摘抄自osi.h文件

OsiReturnVal_e

osi_SyncObjCreate(OsiSyncObj_t* pSyncObj); //同步对象的创建~This function deletes a sync

object

OsiReturnVal_e osi_SyncObjWait(OsiSyncObj_t*

pSyncObj , OsiTime_t Timeout); // 等待同步对象This function waits for a sync signal of the

specific sync object

OsiReturnVal_e

osi_SyncObjSignalFromISR(OsiSyncObj_t*

pSyncObj);//产生同步对象

(ISR中使用)This function generates a sync signal for the

object. from ISR

context.

OsiReturnVal_e

osi_SyncObjSignal(OsiSyncObj_t* pSyncObj); // 产生同步对象,非ISR中使用。This function generates a sync signal for the

object.

示例:

上面创建了个检测按键的任务,当有按键按下时就产生一次同步对象~再创建另一个线程用于等待同步对象~一旦有按键产生可通过串口将数据打印出来~。(详细看代码)。

要注意的地方:同样每个函数都有返回值,最好做返回值检测,才能更好的解决问题)。

消息队列

用到的API摘抄自osi.h文件

OsiReturnVal_e osi_MsgQCreate(OsiMsgQ_t*

pMsgQ

, ……. // 创建消息 This function creates a message queue that is

typically used for inter thread communication.

OsiReturnVal_e osi_MsgQWrite(OsiMsgQ_t*

pMsgQ, void* pMsg , OsiTime_t Timeout); // 发送消息 This function writes a message to a specific

message queue.

OsiReturnVal_e osi_MsgQRead(OsiMsgQ_t* pMsgQ,

void* pMsg , OsiTime_t Timeout);// 接收消息 This function retrieves a message from the

specified message queue.

比如创建消息代码如下:12代表12个字节~,10代表总共可以一口气发送10次消息(类似有个缓存)。

lRetVal =

osi_MsgQCreate(&keyMsg,"key MSG ",12,10);

if(lRetVal

< 0)

{

ERR_PRINT(lRetVal);

LOOP_FOREVER();

}

osi_MsgQWrite(OsiMsgQ_t* pMsgQ, void* pMsg ,

OsiTime_t Timeout); 关于这个pMsg,此msg为指针,指向的大小为上面创建msg的大小(12)。也就是一个消息可以存放12个字节。

osi_MsgQRead 时,pMsg指向的是一个12字节的内存区域。

综合以上,我修改了例程,创建了个线程用于检测按键,有按键触发即产生同步对象以及将按键消息送入消息队列。

再另一个线程用于等待同步对象,并接收消息,解析消息,对相应按键进行处理(通过按键打印出来)。

详细代码看附件,运行效果:短按sw2,sw3以及长按sw2,,sw3

a4c26d1e5885305701be709a3d33442f.png

以上就是TI-RTOS提供的部分API简单示例~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值