// Initialize board I/O InitBoard( OB_COLD );
// Initialze HAL drivers HalDriverInit();
// Initialize NV System osal_nv_init( NULL );
// Initialize the MAC ZMacInit();
// Determine the extended address zmain_ext_addr();
// Initialize basic NV items zgInit();
#ifndef NONWK
// Since the AF isn't a task, call it's initialization routine afInit(); #endif
// Initialize the operating system osal_init_system();
// Allow interrupts
osal_int_enable( INTS_ALL );
// Final board initialization
InitBoard( OB_READY );
// Display information about this device zmain_dev_info();
/* Display the device info on the LCD */ #ifdef LCD_SUPPORTED zmain_lcd_init();
#endif
#ifdef WDT_IN_PM1
/* If WDT is used, this is a good place to enable it. */ WatchDogEnable( WDTIMX ); #endif
osal_start_system(); // No Return from here
return 0; // Shouldn't get here. } // main()
OSAL即Operating System (OS) Abstraction Layer,是一个基于事件驱动的轮询式的操作系统。它主要提供了任务切换,内存管理等功能。我们在实验中也主要是通过它来开发并管理应用程序。
在main()函数的最后,调用了osal_start_system(),此函数是OSAL的灵魂,也体现了协议栈的工作方式和流程。其主要方法就是:不断查看事件表,如果有事件发生就调用相应的事件处理函数。
相关代码如下:
/*********************************************************************
* @fn osal_start_system *
* @brief *
* This function is the main loop function of the task system. It
* will look through all task events and call the task_event_processor() * function for the task with the event. If there are no events (for * all tasks), this function puts the processor into Sleep. * This Function doesn't return.
*
* @param void *
* @return none */
void osal_start_system( void ) {
#if !defined ( ZBIT ) && !defined ( UBIT )
for(;;) // Forever Loop
#endif {
uint8 idx = 0;
osalTimeUpdate();
Hal_ProcessPoll(); // This replaces MT_SerialPoll() osal_check_timer().
do {
if (tasksEvents[idx]) // Task is highest priority that is ready.
{
break; }
} while (++idx < tasksCnt);
if (idx < tasksCnt) {
uint16 events;
halIntState_t intState;
HAL_ENTER_CRITICAL_SECTION(intState); events = tasksEvents[idx];
tasksEvents[idx] = 0; // Clear the Events for this task. HAL_EXIT_CRITICAL_SECTION(intState);
events = (tasksArr[idx])( idx, events );
HAL_ENTER_CRITICAL_SECTION(intState);
tasksEvents[idx] |= events; // Add back unprocessed events to the current task.
HAL_EXIT_CRITICAL_SECTION(intState); }
#if defined( POWER_SAVING )
else // Complete pass through all task events with no activity?
{
osal_pwrmgr_powerconserve(); // Put the processor/system into sleep }
and
#endif
} }
在OSAL中提供了开发所用的API。主要有消息管理、任务同步、时间管理、终端管理、任务管理等。下面对其进行简单的介绍。
(1)消息管理类API 主要用于处理任务间的消息的交换,主要包括任务分配消息缓存、释放消息缓存、接受消息和发送消息等。
Uint8 *osal_msg_allocate(unit16 len) 为消息分配缓存空间。
Uint8 osal_msg_deallocate(uint8 *msg_ptr) 释放消息的缓存空间。 Uint8 osal_msg_send(unit8 destination-task, uint8 *msg_ptr ) 一个任务发送消息到消息队列
Uint8 osal_msg_receive(uint8 task_id)
一个任务从消息队列接受属于自己的消息。 (2) 任务同步API 用于任务的同步,允许一个任务等待某个事件的发生。 Uint8 osal_set_event(uint8 task_id,uint16 event_flag) 运行一个任务设置某个事件。
(3 时间管理API 开启和关闭定时器,
Uint8 osal_start_timerEx(uint8 task_id,uint16 event_id,uint16 timeout_value) 设置一个定时时间,到后,相应的事件被设置。
Uint8 osal_stop_timerEx(uint8 task_id,uint16 event_id)
停止已经启动的定时器。
OSAL提供的API还有很多,这里仅列出了较为常用的,完整API介绍TI公司提供了相应的用户手册。
关于OSAL的较为详细的介绍,将在本段3节中给出。
4.2.5 设备相关功能主要函数介绍
(1)协调器(采集器)编程 协调器主要完成网络的建立维护等功能,这些功能由协议栈提供,其原理在此暂且不描述(下节将有较为详细的描述)。在其编程过程中,我主要完成的是具体应用的开发。就是将数据接收并发送到串口。函数如下:
void zb_ReceiveDataIndication( uint16 source, uint16 command, uint16 len, uint8 *pData )
这是协调器最主要的功能函数,处理的是接受到另一个数据后执行的操作。简单来说就是数据归类处理后发送到串口。
函数的代码如下:
/******************************************************************************
* @fn zb_ReceiveDataIndication
*
* @brief The zb_ReceiveDataIndication callback function is called * asynchronously by the ZigBee stack to notify the application
* when data is received from a peer device. *
* @param source - The short address of the peer device that sent the data
* command - The commandId associated with the data * len - The number of bytes in the pData parameter
* pData - The data sent by the peer device *
* @return none
*/
CONST uint8 strDevice[] = \CONST uint8 strTemp[] = \CONST uint8 strBattery[] = \
void zb_ReceiveDataIndication( uint16 source, uint16 command, uint16 len, uint8 *pData )
{
uint8 buf[32]; uint8 *pBuf; uint8 tmpLen;
uint8 sensorReading;
if (command == SENSOR_REPORT_CMD_ID) {
// Received report from a sensor sensorReading = pData[1];
// If tool available, write to serial port
// 下面的功能是把发数据的设备号(网络地址)写入缓存
tmpLen = (uint8)osal_strlen( (char*)strDevice ); pBuf = osal_memcpy( buf, strDevice, tmpLen ); _ltoa( source, pBuf, 16 ); pBuf += 4;