OSAL初始化作业流程.docx
- 文档编号:3711604
- 上传时间:2023-05-06
- 格式:DOCX
- 页数:19
- 大小:27.45KB
OSAL初始化作业流程.docx
《OSAL初始化作业流程.docx》由会员分享,可在线阅读,更多相关《OSAL初始化作业流程.docx(19页珍藏版)》请在冰点文库上搜索。
OSAL初始化作业流程
转载OSAL初始化流程
我使用合同栈版本及例子信息:
ZigBee\TexasInstruments\ZStack-1.4.3-1.2.1\Projects\zstack\Samples\SampleApp
一方面借用前人一种阐明:
顾客自己添加应用任务程序在Zstack中调用过程是:
(1).main()执行(在ZMain.c中)
main()--->osal_init_system()
(2).osal_init_system()调用osalInitTasks(),(在OSAL.c中)
osal_init_system()--->osalInitTasks()
(3).osalInitTasks()调用SampleApp_Init(),(在OSAL_SampleApp.c中)
osalInitTasks()--->SampleApp_Init()
在osalInitTasks()中实现了各种任务初始化设立,其中macTaskInit(taskID++)到ZDApp_Init(taskID++)几行代码表达对于几种系统运营初始化任务调用,而顾客自己实现SampleApp_Init()在最后,这里taskID随着任务增长也随之递增.因此顾客自己实现任务初始化操作应当在osalInitTasks()中增长.
//----------------------------------------------------------------------------------------------------
1、一方面来看下主函数main()
ZSEGintmain(void)//主函数功能就是完毕初始化任务,然后进入OSAL
{
//Turnoffinterrupts
/*关闭中断*/
osal_int_disable(INTS_ALL);
//InitializeHAL
/*初始化硬件*/
HAL_BOARD_INIT();
//Makesuresupplyvoltageishighenoughtorun
/*电压检测,保证芯片能正常工作电压*/
zmain_vdd_check();
//Initializestackmemory
/*初始化stack存储区*/
zmain_ram_init();
//InitializeboardI/O
/*初始化板载IO*/
InitBoard(OB_COLD);
//InitialzeHALdrivers
/*初始化硬件驱动*/
HalDriverInit();
//InitializeNVSystem
/*初始化NV系统*/
osal_nv_init(NULL);
//Determinetheextendedaddress
/*拟定扩展地址(64位IEEE/物理地址)*/
zmain_ext_addr();
//InitializebasicNVitems
/*初始化基本NV条目*/
zgInit();
//InitializetheMAC
/*初始化MAC*/
ZMacInit();
#ifndefNONWK
//SincetheAFisn'tatask,callit'sinitializationroutine
afInit();
#endif
#ifdefLCD_SUPPORTED
HalLcdInit();
#endif
//Initializetheoperatingsystem
/*初始化操作系统*/
osal_init_system();
//Allowinterrupts
/*启动中断*/
osal_int_enable(INTS_ALL);
//Finalboardinitialization
/*最后板载初始化*/
InitBoard(OB_READY);
//HalLcdInit();
//Displayinformationaboutthisdevice
/*显示设备信息*/
zmain_dev_info();
/*DisplaythedeviceinfoontheLCD*/
#ifdefLCD_SUPPORTED
zmain_lcd_init();
#endif
osal_start_system();//NoReturnfromhere没有返回,即进入操作系统!
!
!
}
阐明:
初始化各软硬件后进入系统主循环函数。
这里重点是两个函数:
系统初始化函数osal_init_system();系统主循环函数osal_start_system();
下面记录下个人个人对系统初始化流程和系统主循环流程学习。
这里先记录下系统初始化流程。
//----------------------------------------------------------------------------------------------------
2、系统初始化流程
2.1osal_init_system()——系统初始化函数
byteosal_init_system(void)
{
//InitializetheMemoryAllocationSystem
/*初始化内存分派系统*/
osal_mem_init();
//Initializethemessagequeue
/*初始化系统消息队列*/
osal_qHead=NULL;
#ifdefined(OSAL_TOTAL_MEM)
osal_msg_cnt=0;
#endif
//Initializethetimers
/*初始化定期器*/
osalTimerInit();
//InitializethePowerManagementSystem
/*初始化电源管理系统*/
osal_pwrmgr_init();
//Initializethesystemtasks.
/*初始化系统任务*/
osalInitTasks();//初始化系统任务
//Setupefficientsearchforthefirstfreeblockofheap.
osal_mem_kick();
return(ZSUCCESS);
}
阐明:
这里重点是初始化系统任务函数:
osalInitTasks();下面进入系统任务初始化:
//----------------------------------------------------------------------------------------------------
2.2osalInitTasks();——任务初始化函数
voidosalInitTasks(void)
{
uint8taskID=0;
//osal_mem_alloc()为当前OSAL中各任务分派存储空间(事实上是一种任务数组),函数返回指向任务缓冲
//区指针,因而tasksEvents指向该任务数组(任务队列).注意tasksEvents和背面谈到tasksArr[]里顺
//序是一一相应,tasksArr[]中第i个事件解决函数相应于tasksEvents中第i个任务事件.
tasksEvents=(uint16*)osal_mem_alloc(sizeof(uint16)*tasksCnt);
//osal_memset()把开辟内存所有设立为0;sizeof(uint16)是4个字节,即一种任务
//长度(同样是uint16定义),乘以任务数量tasksCnt,即所有内存空间
osal_memset(tasksEvents,0,(sizeof(uint16)*tasksCnt));//OSAL.c中定义
macTaskInit(taskID++);//初始化各层任务mac_taskID=0;
nwk_init(taskID++);//nwk_taskID=1;
Hal_Init(taskID++);//Hal_taskID=2;
#ifdefined(MT_TASK)
MT_TaskInit(taskID++);//MT_taskID=3;(ifdefined)
#endif
APS_Init(taskID++);//APS_taskID=4;
ZDApp_Init(taskID++);//ZDAPP_taskID=5;
SampleApp_Init(taskID);//SampleApp_taskID=6;顾客创立任务
}
阐明:
任务初始化,就是为系统各个任务分派存储空间,固然,这个空间初始化时为全0(NULL),然后为各任务分派taskID;这里顺序要注意.系统主循环函数里tasksEvents[idx]和tasksArr[idx]idx与这里taskID是一一相应关系。
背面再分析。
指针数组tasksEvents[]里面最后分别指向是各任务存储空间
指针数组tasksArr[]里面最后分别指向是各任务事件解决函数
这两个指针数组里面各元素顺序要一一相应,由于背面需要相应任务调用相应事件解决函数.
对这两个数组定义请参见背面.
问题:
对于osal_mem_alloc()这个函数返回是一种指向任务数组指针,看前人分析,我还没有去看这个函数。
阐明:
那么这里重点是各任务初始化,MAC层和NWK层未开源看不到,先记录下顾客自己添加任务初始化函数SampleApp_Init(taskID);
//----------------------------------------------------------------------------------------------------
2.3SampleApp_Init(taskID);——顾客应用任务初始化函数
voidSampleApp_Init(uint8task_id)
{
SampleApp_TaskID=task_id;//osal分派任务ID,这里为6,随着顾客添加任务增多而变化
SampleApp_NwkState=DEV_INIT;//设备状态设定为ZDO层中定义初始化状态(无连接)
/*初始化应用设备网络类型,设备类型变化都要产生一种事件—ZDO_STATE_CHANGE,从字面理解为
//ZDO状态发生了变化。
因此在设备初始化时候一定要把它初始化为什么状态都没有。
那么它就要去检测
//整个环境,看与否能重新建立或者加入存在网络。
但是有一种状况例外,就是当NV_RESTORE被设立
//时候(NV_RESTORE是把信息保存在非易失存储器中),那么当设备断电或者某种意外重启时,由于网络
//状态存储在非易失存储器中,那么此时就只需要恢复其网络状态,而不需要重新建立或者加入网络了*/
SampleApp_TransID=0;//消息发送ID(多消息时有顺序之分)
//Devicehardwareinitializationcanbeaddedhereorinmain()(Zmain.c).
//Ifthehardwareisapplicationspecific-addithere.
//Ifthehardwareisotherpartsofthedeviceadditinmain().
#ifdefined(SOFT_START)
//如果选取了SOFT编译选项,则作为协调器启动
//The"Demo"targetissetuptohaveSOFT_STARTandHOLD_AUTO_START
//SOFT_STARTisacompileoptionthatallowsthedevicetostart
//asacoordinatorifoneisn'tfound.
//Wearelookingatajumper(definedinSampleAppHw.c)tobejumpered
//together-iftheyare-wewillstartupacoordinator.Otherwise,
//thedevicewillstartasarouter.
//if(readCoordinatorJumper())
zgDeviceLogicalType=ZG_DEVICETYPE_COORDINATOR;
//else
//zgDeviceLogicalType=ZG_DEVICETYPE_ROUTER;
#endif//SOFT_START
#ifdefined(HOLD_AUTO_START)
//如果定义了HOLD_AUTO_START选项,则调用层ZDOInitDevice,按照默认顺
//序网络中第一种设备作为协调器,其她设备作为子设备
//HOLD_AUTO_STARTisacompileoptionthatwillsurpressZDApp
//fromstartingthedeviceandwaitfortheapplicationto
//startthedevice.
ZDOInitDevice(0);
#endif
/*设立发送数据方式和目地址寻址模式*/
//---------------------------
//周期消息,广播发送
//Setupfortheperiodicmessage'sdestinationaddress周期消息事件
//Broadcasttoeveryone
/*广播到所有设备*/
SampleApp_Periodic_DstAddr.addrMode=(afAddrMode_t)AddrBroadcast;//发送模式(广播)
SampleApp_Periodic_DstAddr.endPoint=SAMPLEAPP_ENDPOINT;//指定端点号EP20
SampleApp_Periodic_DstAddr.addr.shortAddr=0xFFFF;//指定目网络地址为广播地址
/*单播到一种设备*/
/*WXL_SampleApp_Single_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;;
WXL_SampleApp_Single_DstAddr.endPoint=WXL_SAMPLEAPP_ENDPOINT;*/
//--------------------------
//闪烁消息:
发送到组
//Setupfortheflashcommand'sdestinationaddress-Group1闪烁消息事件
/*设立endpointdescription.*/
SampleApp_Flash_DstAddr.addrMode=(afAddrMode_t)afAddrGroup;//(组寻址)
SampleApp_Flash_DstAddr.endPoint=SAMPLEAPP_ENDPOINT;//EP20
SampleApp_Flash_DstAddr.addr.shortAddr=SAMPLEAPP_FLASH_GROUP;//组号0x0003
//-------------------------
//Fillouttheendpointdescription.
/*定义本设备用来通信APS层端点描述符*/
SampleApp_epDesc.endPoint=SAMPLEAPP_ENDPOINT;//SampleAppEP描述符EP号:
20
SampleApp_epDesc.task_id=&SampleApp_TaskID;//SampleAppEP描述符任务ID:
0
SampleApp_epDesc.simpleDesc
=(SimpleDescriptionFormat_t*)&SampleApp_SimpleDesc;//SampleAppEP简朴描述符
SampleApp_epDesc.latencyReq=noLatencyReqs;//延时方略
//RegistertheendpointdescriptionwiththeAF
/*向AF层登记EP描述符*/
/*登记endpointdescription到AF,要对该应用进行初始化并在AF进行登记,告诉应用层有这样一种EP已
经开通可以使用,那么下层要是关于于该应用信息或者应用要对下层做哪些操作,就自动得到下层配
合。
*/
afRegister(&SampleApp_epDesc);
//Registerforallkeyevents-Thisappwillhandleallkeyevents
/*登记所有按键事件*/
RegisterForKeys(SampleApp_TaskID);
//Bydefault,alldevicesstartoutinGroup1为闪烁消息配备组
/*设定一种新组*/
SampleApp_Group.ID=0x0003;//组号
osal_memcpy(SampleApp_Group.name,"Group3",7);//设定组名
aps_AddGroup(SAMPLEAPP_ENDPOINT,&SampleApp_Group);//把该组登记添加到APS中
/*如果支持LCD,显示一串字符*/
#ifdefined(LCD_SUPPORTED)
//HalLcdWriteString("SampleApp",HAL_LCD_LINE_1);
Print8(HAL_LCD_LINE_2,20,"SampleApp",1);
#endif
}
阐明:
在SampleAPP例子中,应用层提供了节点间两种逻辑关系:
一种是周期性消息发送,另一种是Flash消息发送。
我个人以为就是两个簇,例如节点1EP20与节点2EP20通信,(可以单播,广播,间接,组传递),这两种逻辑关系属于两节点EP20简朴描述符下簇列表元素.且可以看到SampleApp_SendPeriodicMessage(void)与SampleApp_SendFlashMessage()下clusterID项分别为SAMPLEAPP_PERIODIC_CLUSTERID和SAMPLEAPP_FLASH_CLUSTERID。
顾客应用任务初始化大体是:
设立本应用发送数据方式和目地址寻址模式,登记注册本应用所用到端点,以及配备有关发送模式所需参数.
(个人觉得就此应用来说,ZC,ZR,ZD用到都是EP20,详细后来再作记录)
//----------------------------------------------------------------------------------------------------
以上为OSAL初始化大体流程,OSAL以及各软硬部件初始化完毕后,就进入了系统主循环函数osal_start_system();系统主循环流程个人记录见下篇.
OSAL系统主循环函数:
voidosal_start_system(void)
{
#if!
defined(ZBIT)//不懂得是什么
东西
for(;;)//ForeverLoop
#endif
{
uint8idx=0;
Hal_ProcessPoll();//ThisreplacesMT_SerialPoll()andosal_check_timer().
//轮询TIMER与UART
//--------------------------
//执行循环语句:
tasksEvents[idx]是一种指针变量,指向存储任务idx存储空间,初始化时由
//osal_memset()设为0,只要不为空类型NULL,
//即有相相应任务事件发生,就break跳出循环体,通过下面程序进行任务事件解决。
//如果为空,执行判断语句,即idx自增,再返回轮询有无各层任务事件发生。
如果
//执行完循环语句都没有检测到有事件发生,idx=7,进入睡眠。
(对于本例子来说,任务数组里只有七个任务,tasksEvents[0]~tasksEvents[6],tasksEvents[6]就是顾客自已添加任务,idx随着顾客添加任务增多而增大)
do{
if(tasksEvents[idx])//Taskishighestprioritythatisready.
{
break;
}
}while(++idx //------------------------- if(idx { uint16events; halIntState_tintState;//中断位状态 HAL_ENTER_CRITICAL_SECTION(intState);//中断临界状态: 保存先前中断状态,然后关中断 events=tasksEvents[idx];//uint16events;相应有事件发生任务 tasksEvents[idx]=0;//CleartheEventsforthistask.NULL HAL_EXIT_CRITICAL_SECTION(intState);//跳出中断临界状态: 恢复先前中断状态 events=(tasksArr[idx])(idx,events);//调用相相应任务事件解决函数解决,各类事件解决函 //数M(task_id,event)返回都是这个任务未被解决事件 HAL_ENTER_CRITICAL_SECTION(intState); tasksEvents[idx]|=events;//Addbackunprocessedeventstothecurrenttask. //把刚才返回未解决任务事件添加加当前任务中再进行解决 //(跳出此if(idx HAL_EXIT_CRITICAL_SECTION(intState); } #ifdefined(POWER_SAVING) else//Completepassthrougha
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OSAL 初始化 作业 流程