77范文网 - 专业文章范例文档资料分享平台

关于TI的CC2541的程序解读

来源:网络收集 时间:2018-11-12 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

A 先粗看了一些东西

如果某一个任务的event被置位了,就处理它。

即 taskEvents[idx]!=0

而这个事件是由中断程序之类的设置的或者由某一任务设置的?

只有有events事件发生的任务才去处理。没有事件发生的任务将跳过。

系统信息,可能会发给本任务,这个用函数: Osal_msg_receve(simpleosal_taskID)就可以得知。

猜想:当系统事件发生时,它会将一个全局变量中的事件数组的某一个与0x8000或运算,到底是哪一个就是我们的任务排列的序号来决定的,例如我们在本例子中有11个任务(后来我自已又加了一个)如果第2个任务要发系统信息运去,就将这个数组置为1。 程序中的这样处理的:

tasksEvents[task_id] |= event_flag; // Stuff the event bit(s)---见osal.c中。

这个信息处理函数(带任务ID参数)它就是读这个全局变量,看这个是发给谁的。

所以它先看有没有系统事件是发给本任务的,

uint8 *osal_msg_receive( uint8 task_id ) {

osal_msg_hdr_t *listHdr; ///队列指针,用于搜索的 osal_msg_hdr_t *prevHdr = NULL; ///前一个

osal_msg_hdr_t *foundHdr = NULL; ///发现的指针处

halIntState_t intState; ///这个不知是干什么用的

// Hold off interrupts

HAL_ENTER_CRITICAL_SECTION(intState); ////进入

// Point to the top of the queue

listHdr = osal_qHead; ////指向队列的前部

// Look through the queue for a message that belongs to the asking task while ( listHdr != NULL ) ////只要队列不空,就一直往下走 {

if ( (listHdr - 1)->dest_id == task_id ) ///事件队列中的目标ID是指向本地ID否? {

if ( foundHdr == NULL ) ///第一次发现消息是给自已的 {

// Save the first one

1

foundHdr = listHdr; ////发现一个消息是给自已的 } else {

// Second msg found, stop looking 又发现一个 直接退出了 break; } }

if ( foundHdr == NULL ) {

prevHdr = listHdr; ///当前这个就是第一个 }

listHdr = OSAL_MSG_NEXT( listHdr ); ///指向下一个 }

// Is there more than one? if ( listHdr != NULL ) {

// Yes, Signal the task that a message is waiting osal_set_event( task_id, SYS_EVENT_MSG ); } else {

// No more 如果没有消息就告诉任务,现在没有系统消息 osal_clear_event( task_id, SYS_EVENT_MSG ); }

// Did we find a message?

if ( foundHdr != NULL ) ////将这个消息从中间抽出来让它消失掉,这时就要知道前一个 {

// Take out of the link list

osal_msg_extract( &osal_qHead, foundHdr, prevHdr ); }

// Release interrupts

HAL_EXIT_CRITICAL_SECTION(intState);

return ( (uint8*) foundHdr ); }

B再看一下操作系统,从中断到处理的过程

现在基本理清了按键消息是如何发过来的,有点绕。 首先,在初始化中,允许了中断并配置了回调函数(这个函数在文件onBoard.c中InitBoard()

2

调用了它):

/* Initialize Key stuff */

OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE; //OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;

HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);---halkey.c中定义 在配置回调函数中,它初始化了两个键盘的中断允许位和上下沿等细节,将中断屏蔽位打开,且将这个中断标志位清除。注意到它将全局变量置为有效OnboardKeyIntEnable=1 而这个变量本来没什么意义的,但发现它可以用来读键盘中断位时,在区分是用中断方式来做还是用查询方式来做时用得着这个变量。 中断函数的定义有点小技巧(宏),它就是将中断矢量放到合适的位置,而且申明了这个函数。它既是定义,也是申明。这个在hal_mcu.h中定义了。(Keil和IAR不一样)

但是这个配置程序中可能有点错,PICTL是用来控制上升沿或下降沿中断的,在多功能键初始化中,即P2.0处理中,它错误将P2IEN的D3位置为1,而不是将PICTL的D3位置1。所以这个键变成了上升沿了。当然这并不影响程序的运行。下面我们看一下是上升沿还是下降沿。先看一下电路图按下去时,它会产生一个上升沿,仿真器调一下看是否是上升沿时中断?果然,在刚按下去,还没抬起来的时候,就捕获到一个中断了。这说明这个中断是上升尚的,证明了程序的配置下降沿是没成功的,看来TI也会出点小错误。

中断响应程序中,最后调用了:----中断函数定义在halkey.c中.

osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE);将生成一个按键事件。注意到这个Hal_TaskID这个是内核ID的任务。延时一下可抗抖动干扰? 注意到这个函数中调用了 newTimer = osalAddTimer( taskID, event_id, timeout_value ); 而这个加定时器这个函数,当时只是加了一个定时器,后面的事情,就是要延时一点时间后,等时间到了后再去设置它,这个终于发现了(在定时器更新中osalTimerUpdate()) 当定时时间一到,就将事件发送给相应的任务ID

osal_set_event( freeTimer->task_id, freeTimer->event_flag ); 所以是它将这个按键事件是发送给内核这个任务的。

注意到这里的任务ID,就是内核任务ID。而这个事件就是按键事件。

注意到在中断程序中,并不确定按键是哪一个,它是在HalKeyPoll()中检测键的。

而这个事件的处理在什么地方呢?

它在Hal_ProcessEvent( uint8 task_id, uint16 events )中。

这个是一直在调用的,它是11个运行的任务之一(事实上它是第2个任务)

在这个任务中,如果发现有系统事件,它会将这个事件读出来。没做什么事情,也不会有这样的系统事件(在我们这个程序中)

如果是按键事件,则调用HalKeyPoll()在这个函数中将检测这个键值传送到这个回调函数中。(pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL); 注意到第2个参数它=0 OnBoard_KeyCallback( uint8 keys, uint8 state )注意到这个state=0.

而这个shift的值为多少呢?如果不是SW6,它就是true.如果是SW6,它就是false.

shift = (OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE) ? false : ((keys & HAL_KEY_SW_6) ? true : false); ---如果是单键,它为false,为5键,它就是true.

3

这个回调函数,调用了OnBoard_SendKeys( keys, shift ) 在这个函数中,它调用了: osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );

这个注册的任务ID,就是我们在初始化中指定的任务(最后一个任务ID)。而这个信息就含有我们的事件名,状态,键名称。

发送消息的函数调用了osal_msg_enqueue_push( destination_task, msg_ptr, FALSE)在这个函数的开始,将消息推送到消息队列中,osal_msg_enqueue( &osal_qHead, msg_ptr ); 最后调用了osal_set_event( destination_task, SYS_EVENT_MSG );即告诉目标任务ID,你的系统事件到了。

有一个问题是程序是如何按键去抖动的呢?例如由于抖动,发生了N次按键中断。难道就要加N个定时器吗?终于后来又发现了,它在osalAddTimer( uint8 task_id, uint16 event_flag, uint32 timeout )完美地解决了这个问题,这个问题就在这个函数中,当增加定时器时,如果发现同样的事件,同样的任务,已经有一个定时器在运行了,则我们就不会再增加定时器了,而是将这个定时器更新一下就可以了。而如果从来没有定时器用于这个事件和这个任务(两者同时符合,则不生成一个新的定时器)

newTimer = osalFindTimer( task_id, event_flag );

if ( newTimer ) ///如果发现了定时器已经存在了 {

// Timer is found - update it. ///只是将这个定时时间更新一下而已。 newTimer->timeout.time32 = timeout;

return ( newTimer ); }

Else ///如果没有这个定时器存在,就生成一个定时器 {

// New Timer

newTimer = osal_mem_alloc( sizeof( osalTimerRec_t ) ); ///分配一段内存 。。。。 以下设置定时器的参数

}

真正的键的最后处理,交给应用层了。因为这个信息已经封装,发送到最未的一个任务了,消息中的事件就是KEY_CHANGE 它的状态就是true or false---这个依赖于是5键还是单个键。 它的键名就是预定义好的6个键,分别为0x01,0x02,0x04....

后面还有注意到

tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);

分配的是一个2*事件个数的数组 例如11个任务,就分配了一个22个字节的指针处。 它是一个int16的数组,每个位表示一个事件,每个任务最多有16个事件,其中的0x8000表示的是系统事件。即最高位为1的事件。

我们还要看一下这个始终运行的任务 do {

4

if (tasksEvents[idx]) // Task is highest priority that is ready. 注意到这个数组。它代表? {

break; }

} while (++idx < tasksCnt);

在什么地方设置这个呢?tasksEvents[idx]

uint8 osal_set_event( uint8 task_id, uint16 event_flag ) {

if ( task_id < tasksCnt ) {

halIntState_t intState;

HAL_ENTER_CRITICAL_SECTION(intState); // Hold off interrupts tasksEvents[task_id] |= event_flag; // Stuff the event bit(s)

HAL_EXIT_CRITICAL_SECTION(intState); // Release interrupts return ( SUCCESS ); } else {

return ( INVALID_TASK ); } }

C自已在工程中试着加任务,传事件和附加消息,还是成功了

下面,我们试着在一个工程中,加一个任务,这个任务让一个LED灯闪。且时间到了,就给主任务发送一条自定义的消息,此消息含一个变量,这个变量每次都++的。通过串口打印一个 时间到了XX出来。

先加一个任务试试。

1.首先在任务组中增加一个函数 MyTestEvent() 这个在OSAL_simpleBLECentral.c中。 2.

A 增加一个 MyTest_Init(taskID );注意到前面一个任务必须将tasdID++;只有最后一个才不要++。 simpleBLECentral.c中,这个是初始化的调用。

B 增加一个定义static uint8 MyTestTaskId; -----simpleBLECentral.c中。

C extern uint16 MyTestEvent( uint8 task_id, uint16 events );----这个在simpleBLECentral.h中要定义,同时要定义的还有 extern void MyTest_Init(task_id) 不然编译会出警告

3.写这个初始化函数及处理函数

A初始化函数部分:它定义在simpleBLECentral.c中

先: HalLedSet( HAL_LED_2, HAL_LED_MODE_ON ); ///没什么事就让一个灯亮一下吧

5

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库关于TI的CC2541的程序解读在线全文阅读。

关于TI的CC2541的程序解读.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/267938.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: