上一篇《如何快速理解一个全新的嵌入式操作系统》我们已经分析了如何快速理解OSAL的任务调度和任务间通信(其实OSAL只是酷似多任务操作系统的单任务系统),再理解好OASL的消息产生和处理过程,我们就能够进行快速开发了。
一、消息的来源
嵌入式系统的消息包括两种,一是系统消息,包括低电、热插拔等,由系统进程去处理;二是用户消息,包括Timer、按键、串口、绘图等消息,由各应用进程进行处理。对于TI CC254x的OSAL,我们理解好Timer、key、UART就已足够。
二、HAL
OSAL向用户提供HAL硬件抽象层,对CC254x的所支持的硬件模块进行了封装抽象,如timer、key、UART、LED、LCD、flash、ADC等等,并向用户提供硬件模块的操作接口。
CC254x是低功耗蓝牙集成芯片,用户的产品和电路设计一般都会参考官方的典型电路,而OSAL为官方针对典型电路所设计的系统库和接口,用户的代码编程就只需要按照其提供的HAL接口进行调用就可以实现功能,而不需要通过GPIO级别的驱动编程来实现模块的功能。
针对CC254x的编程是应用编程,关注的是HAL接口,可以认为是基于硬件功能的API接口,而且电路的外设的功能也相对固定,如LED、LCD、UART所使用的pin脚都是相对固定的,因此调用简单的HAL层接口即可实现功能;而驱动编程则是针对SOC片上资源来进行开发,需要根据SOC的datasheet明确的物理地址资源进行访问和控制,并向用户提供API接口。从两者的区别可以理解HAL硬件抽象层的含义。当然,透传理解SOC datasheet也有助于HAL接口编程。
三、Timer
对于Timer定时器接口,一般是设置定时器、编写定时器时间到达时的回调函数。而定时器模块的初始化函数一般由系统初始化完成。
OSAL对于Timer的HAL层代码对用户并不透明,我们可以理解Timer的HAL层是设置Timer模块的硬件相关操作,并且实现了Timer中断时的服务处理过程。OSAL的Timer的封装接口实际上是在HAL层的基础进行再次封装。其主要提供的接口如下:
uint8osal_start_timerEx( uint8 taskID, uint16 event_id, uint32 timeout_value )
taskID标识哪个目标任务来处理这个定时到达消息,即当定时完成时,定时器中断服务器函数会往这个目标任务的taskEvents[taskID]写入event_id这个消息;event_id可以由用户自定义;timeout_value是定时时间,1毫秒为单位。
可见这个定时接口并没有设置定时完成时的回调函数,而是在定时完成时向这个目标任务发送一个事件。而在目标任务的执行过程中要检测这个事件并执行相应的处理。
四、UART
UARTHAL层代码对用户是透明的,对于用户编程来