概述
一、前言
本文用于学习交流,如有不完整或者错误之处,请留言指出。如果在阅读过程中有不理解的地方可能是我没写清楚。也可能是其他原因。本文假定你的具备但不限于以下相关知识:
1、MCU的基础知识。
2、操作系统的概念。
3、知道OSAL的任务调度是怎样实现的。
二、关于OSAL
OSAL中文直译过来叫”操作系统抽象层”,由此可以看出它并不是一个真正意思上的操作系统。它是TI公司开发用于构建蓝牙和ZigBee协议栈和基于其上的应用框架、应用。主要的任务调度是基于一个死循环轮询任务数组或基于定时器查询,不支持任务优先级抢占,因此它实时性较差。具体更多信息www.ti.com/ble-stack
三、按键流程剖析
本部分内容基于TI CC2540系列蓝牙芯片之上运行OSAL进行按键流程分析。如下图所示是OSAL中关于按键的流程时序图。
图1:完整
图2:上部
图3:下部
整个按键处理流程主要涉及五个对象,分别将其称为INIT(初始化)、中断INT(按键硬件中断)、HAL_KAY(OSAL硬件抽象层)、BOARD(硬件平台相关,主要处理从中断过来信息)、TASK(应用层对象,一般是按键信息处理的最终归宿)。以上时序基本就是按键在OSAL中的处理流,在时序图中列出了主要的处理函数和信息流方向。下面来进行具体分析。
1、INIT(初始化)
初始化指的是在系统运行任务调度死循环之前对平台硬件运行时钟和外围设备(按键、UART等)的寄存器进行配置和OSAL的任务处理函数进行注册等。在这个过程中,对按键的初始化处理的操作主要有:HalKeyInit()、RegisterForKeys()、HalKeyConfig().
HalKeyInit()主要是配置按键IO的寄存器。下面是它的代码。
如果你使用的是TI的CC2540_MINIDK的一个评估板,那么它的初始化就是上图画圈的部分。主要是选择按键IO的功能和设置IO为输入方向。
RegisterForKeys()在SimpleBLEPeripheral_Init()中调用,主要是将接收按键消息的任务ID(即对应于这里的TASK的ID)赋值给registeredKeysTaskID,后续的按键消息将通过该ID传递给对应的应用层处理任务。
HalKeyConfig()在InitBoard()中调用,该函数指定硬件按键在HAL层的响应是中断方式还是轮询。另外还指定了HAL层的按键处理回调函数(OnBoard_KeyCallback),用于HAL接收处理来自硬件中断的按键消息。下面是它的具体代码片段。
图:InitBoard()
图:HalKeyConfig()片段
上图可以看出,如果用户指定以中断的方式响应按键,则配置寄存器打开按键IO相关中断。
图:HalKeyConfig()片段2
反之,如果不打开中断则,使能所有按键IO中断,并向HAL层任务发送HAL_KEY_EVENT事件,在HAL层任务执行时扫描按键IO判断是否有按键事件产生(该动作是在HalKeyPoll()执行的,后面分析具体分析)。
至此,初始化完成后,调用osal_start_system()运行系统。
2、流程分析
初始化完成后,系统运行。此时按键事件的大致流程可以简单归纳为:硬件响应按键中断并发送按键事件消息给HAL层→HAL获取按键信息→通过回调BOARD层函数打包按键消息发送给相应的TASK→TASK最终处理按键。
中断INT
最先接收到按键事件的是中断INT,在HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )中调用halProcessKeyInterrupt(),这里主要完成的工作是清除硬件中断标志位,并通过osal_start_timerEx()给HAL层发送HAL_KEY_EVENT事件消息通知处理按键。
HAL_KEY
在HAL的任务处理函数Hal_ProcessEvent中,以下是该函数中的代码片段图。
可以看到,HAL的按键处理实际上是在HalKeyPoll()中处理的。它集中处理了以中断和轮询两种按键响应方式获取按键值。下图是HalKeyPoll()代码片段。
可以看到,在该函数中主要是获取按键值,然后通过调用在HalKeyConfig()中注册的回调函数(OnBoard_KeyCallback)将按键处理转交给BOARD
BOARD
在OnBoard_KeyCallback()中主要是调用OnBoard_SendKeys()将按键消息打包并通过调用osal_msg_send()将按键消息发送给指定的TASK处理。该TASK通过在初始化阶段调用的RegisterForKeys()将自己的task ID赋值给registeredKeysTaskID。需要说明的是,osal_msg_send()发送的是SYS_EVENT_MSG,这个是系统实现的。
另一方面在OnBoard_KeyCallback()中还会将按键硬件中断使能。以下是相关的代码片段。
TASK
在TASK的任务处理函数中SimpleBLECentral_ProcessEvent()轮询到SYS_EVENT_MSG事件时调用osal_msg_receive()接收系统消息,再simpleBLECentral_ProcessOSALMsg()处理,以下是其代码片段。
然后根据消息的事件类型pMsg->event再调用按键处理函数simpleBLECentral_HandleKeys()最终处理按键操作。
至此,整个按键处理流程结束。相应的其他设备处理流程在OSAL中的也大致相当,但不完全一致,具体情况具体分析。
最后
以上就是安静母鸡为你收集整理的基于TI C2540的OSAL按键事件处理流程解析的全部内容,希望文章能够帮你解决基于TI C2540的OSAL按键事件处理流程解析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复