ImageVerifierCode 换一换
格式:DOCX , 页数:56 ,大小:48.02KB ,
资源ID:16389963      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-16389963.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(OSAL解读笔记.docx)为本站会员(b****7)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

OSAL解读笔记.docx

1、OSAL解读笔记A 先粗看了一些东西如果某一个任务的event被置位了,就处理它。即 taskEventsidx!=0 而这个事件是由中断程序之类的设置的或者由某一任务设置的?只有有events事件发生的任务才去处理。没有事件发生的任务将跳过。系统信息,可能会发给本任务,这个用函数:Osal_msg_receve(simpleosal_taskID)就可以得知。猜想:当系统事件发生时,它会将一个全局变量中的事件数组的某一个与0x8000或运算,到底是哪一个就是我们的任务排列的序号来决定的,例如我们在本例子中有11个任务(后来我自已又加了一个)如果第2个任务要发系统信息运去,就将这个数组置为1。

2、程序中的这样处理的: tasksEventstask_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; /发现的指针处 halIntSt

3、ate_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

4、_id ) /事件队列中的目标ID是指向本地ID否? if ( foundHdr = NULL ) /第一次发现消息是给自已的 / Save the first one 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

5、( 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

6、_msg_extract( &osal_qHead, foundHdr, prevHdr ); / Release interrupts HAL_EXIT_CRITICAL_SECTION(intState); return ( (uint8*) foundHdr );B再看一下操作系统,从中断到处理的过程现在基本理清了按键消息是如何发过来的,有点绕。首先,在初始化中,允许了中断并配置了回调函数(这个函数在文件onBoard.c中InitBoard()调用了它): /* Initialize Key stuff */ OnboardKeyIntEnable = HAL_KEY_INTERRUP

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

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

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

10、te())当定时时间一到,就将事件发送给相应的任务IDosal_set_event( freeTimer-task_id, freeTimer-event_flag );所以是它将这个按键事件是发送给内核这个任务的。注意到这里的任务ID,就是内核任务ID。而这个事件就是按键事件。注意到在中断程序中,并不确定按键是哪一个,它是在HalKeyPoll()中检测键的。而这个事件的处理在什么地方呢?它在Hal_ProcessEvent( uint8 task_id, uint16 events )中。这个是一直在调用的,它是11个运行的任务之一(事实上它是第2个任务)在这个任务中,如果发现有系统事件,

11、它会将这个事件读出来。没做什么事情,也不会有这样的系统事件(在我们这个程序中)如果是按键事件,则调用HalKeyPoll()在这个函数中将检测这个键值传送到这个回调函数中。(pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL); 注意到第2个参数它=0OnBoard_KeyCallback( uint8 keys, uint8 state )注意到这个state=0.而这个shift的值为多少呢?如果不是SW6,它就是true.如果是SW6,它就是false. shift = (OnboardKeyIntEnable = HAL_KEY_IN

12、TERRUPT_ENABLE) ? false : (keys & HAL_KEY_SW_6) ? true : false); -如果是单键,它为false,为5键,它就是true. 这个回调函数,调用了OnBoard_SendKeys( keys, shift ) 在这个函数中,它调用了: osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );这个注册的任务ID,就是我们在初始化中指定的任务(最后一个任务ID)。而这个信息就含有我们的事件名,状态,键名称。发送消息的函数调用了osal_msg_enqueue_push( destina

13、tion_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 )完美地解决了这个问题,这个问

14、题就在这个函数中,当增加定时器时,如果发现同样的事件,同样的任务,已经有一个定时器在运行了,则我们就不会再增加定时器了,而是将这个定时器更新一下就可以了。而如果从来没有定时器用于这个事件和这个任务(两者同时符合,则不生成一个新的定时器) newTimer = osalFindTimer( task_id, event_flag ); if ( newTimer ) /如果发现了定时器已经存在了 / Timer is found - update it. /只是将这个定时时间更新一下而已。 newTimer-timeout.time32 = timeout; return ( newTimer

15、); 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( u

16、int16 ) * tasksCnt);分配的是一个2*事件个数的数组 例如11个任务,就分配了一个22个字节的指针处。它是一个int16的数组,每个位表示一个事件,每个任务最多有16个事件,其中的0x8000表示的是系统事件。即最高位为1的事件。我们还要看一下这个始终运行的任务 do if (tasksEventsidx) / Task is highest priority that is ready. 注意到这个数组。它代表? break; while (+idx tasksCnt);在什么地方设置这个呢?tasksEventsidxuint8 osal_set_event( uint8

17、 task_id, uint16 event_flag ) if ( task_id msg.readRsp.value0;证明这个消息中含有读的值。这个消息格式如下:typedef struct osal_event_hdr_t hdr; /! GATT_MSG_EVENT and status uint16 connHandle; /! Connection message was received on uint8 method; /! Type of message gattMsg_t msg; /! Attribute protocol/profile message gattMsg

18、Event_t;如果不是读,也不是写,而且正在忙的话,就是在做发现的事情。例如,在接到发现从机事件时,就将这个状态改变成正在发现状态:simpleBLEDiscState = BLE_DISC_STATE_SVC;此时就不是闲了。而如果有消息过来,要不就是读,要不就是写,要不就是在发现。所在在收到了系统消息后,一个看这个消息是不是按键消息,一个看消息中附加的事件是不是GATT消息,如果是GATT消息,则进一步看是读还是写还是其它。其它只有一种情况就是发现消息。而这个发现消息也是因为按了UP键引发的。最后我们还是看一下键处理,尽管这个键处理比较复杂一些。先看UP键。如果没建立连接,就调用一个函数

19、去发现从机扫描。如果正在扫描时按下UP键,就终止扫描了。不过除非你连接按两下UP,不然因为连接速度很快,不会出现终止扫描这种情况。如果已经建立连接了,按UP键的话就是一次是写,一次就是读,一直按一直这样做下去。再看一下左键处理。显示扫描到的设备号。按一下换一个,直到最多8个又回来了。再看右键 是连接更新。这个不知在做什么,因为源代码看不到在库里。再看中心键,如果选择要连接的从机是空闲状态,还没有进行连接,则进行连接,如果已经是连接状态,则断开连接。再看DOWN键,每按一次,是读取RSSI或取消读取RSSI。注意到扫描和连接是两件事情。扫描只是看下面有多少从机。而连接则是给指定的从机去连接。连的

20、是谁则通过左键去选。做试验时我们只有一个从机,只买了一个。程序还是没有看完全,还得继续努力去消化一下。只有多花时间多去看,对代码看上去就记住得差不多的时候,这个代码也就看得差不多了。这样下来速度是慢了点,但是比较深入一点。我们再一次将客户机(中心)这个程序解读一遍:先看在这个事件处理程序:它处理三种事件,第1种是系统事件,第2种是启动事件,第3种是开始发现事件。简单点的先看第3种。第3种是一个开始发现事件。我想这个开始发现事件应该是按了UP键后发出的吧。本来也没有必要搞这么一个绕来绕去的,在按键中直接调这个函数simpleBLECentralStartDiscovery( );不就行了吗?我们

21、看一下在什么地方触发了这个事件?static void simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent )中调用了这个事件。在GAP_LINK_ESTABLISHED_EVENT事件中,发调用这个osal_start_timerEx(simpleBLETaskId,START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY );照理,我们应该在UP键中会出现这个发现设备事件?理解错了,原来这个是发现FFF0服务?而不是发现从机。原来是与从机建立连接后,再启动这个发现从机服务的过程,而不是扫描从机。注意到这里发现FFF0服务的服务。下位机如果有N个,则怎样去发现呢?另外每个下位机它的服务都是FFF0吗?我估计下回还要看一下同时连接3个从机的例子能从中间找点线索吧。调用了这个发现从机服务后,还要做什么呢?此时应该可以与服务器的特征参数通讯了吧?只能先跟踪到这里了。过一会再来回顾这部分的处理吧。接下来我们看到第2种事件,就是启动事件,启动事件由这个任务的init()的。启动事件中,也做了不少事情的,主要有:注册了两个函数,其中一个是RSSI事件处理回调函数和一个状态处理回调函数,也就是收到一些事件后,如何处理收到的事件消息。绑定处理函数

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2