zoukankan      html  css  js  c++  java
  • Ztack学习笔记(3)-系统启动分析

    一 系统启动

    //OSAL.c
    void
    osal_start_system( void ) { #if !defined ( ZBIT ) && !defined ( UBIT ) for(;;) // Forever Loop #endif { osal_run_system(); } }

    二 操作系统运行

    //OSAL.c
    void
    osal_run_system( void ) { uint8 idx = 0; osalTimeUpdate(); Hal_ProcessPoll();//轮询TIMERUART do { if (tasksEvents[idx]) // Task is highest priority that is ready. { break; } } while (++idx < tasksCnt); 初始化时由osal_memset()设为0只要不为空类型NULL,即有相对应任务事件发生,就break跳出循环体,通过下面的程序进行任务事件处理。如果为空,执行判断语句,即idx自增,再返回轮询有无各层的任务事件发生。如果执行完循环语句都没有检测到有事件发生,idx=7(任务初始化时,最下面的 SampleApp_Init( taskID )为task=6,即最大为6,进入睡眠。 if (idx < tasksCnt) { uint16 events; halIntState_t intState; HAL_ENTER_CRITICAL_SECTION(intState);//中断临界状态:保存先前中断状态,然后关中断,见备注1 events = tasksEvents[idx];//对应有事件发生的任务的数组 tasksEvents[idx] = 0; // Clear the Events for this task.//取出任务事件后,清除此任务数据的事件 HAL_EXIT_CRITICAL_SECTION(intState);//跳出中断临界状态:恢复先前中断状态  activeTaskID = idx; events = (tasksArr[idx])( idx, events ); //调用相对应的任务事件处理函数处理,各类事件处理函M(task_id,event)返回的都是这个任务未被处理的事件。 activeTaskID = TASK_NO_TASK; HAL_ENTER_CRITICAL_SECTION(intState); //把刚才返回未处理的任务事件添加加当前任务中再进行处理,跳出此if(idx < tasksCnt)循环再进行if (tasksEvents[idx])判断并处理) 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 } #endif /* Yield in case cooperative scheduling is being used. */ #if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION == 0) { osal_task_yield(); } #endif }

    三  事件机制

    events = (tasksArr[idx])( idx, events );任务idx的事件处理函数

    以上代码是响应具体的事件函数,其中tasksArr定义为如下:

    //OSAL_SampleApp.c
    const
    pTaskEventHandlerFn tasksArr[ ] = { macEventLoop, //MAC层任务事件处理函数 nwk_event_loop, //NWK层任务事件处理函数 Hal_ProcessEvent, //PHY层事件处理函数 #if defined( MT_TASK ) MT_ProcessEvent, //MT任务事件处理函数 #endif APS_event_loop, //APS层任务事件处理函数 ZDApp_event_loop, //ZDO任务事件处理函数 SampleApp_ProcessEvent //用户应用任务事件处理函数 };

    pTaskEventHandlerFn又定义为

    //OSAL_Tasks.h
    typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );

    即:pTaskEventHandlerFn声明为一种函数指针,该函数指针指向M(task_id,event)这种类型的函数,而tasksArr是一个指针数组,数组里面的元素的类型为pTaskEventHandlerFn,就是函数指针,这样tasksArr[ ]就是一个按照idx顺序排列的函数数组。如果调用tasksArr中相对应的函数,直接使用 tasksArr[idx](task_id,event)就行了。在osal_run_system中,调用events = (tasksArr[idx])( idx, events ),执行由idx相对应的事件任务。

    四 参考链接

    【1】zstack sampleApp程序分析3 

    备注1

    1 #define HAL_ENABLE_INTERRUPTS()         st( EA = 1; )
    2 #define HAL_DISABLE_INTERRUPTS()        st( EA = 0; )
    3 #define HAL_INTERRUPTS_ARE_ENABLED()    (EA)
    4 
    5 typedef unsigned char halIntState_t;
    6 #define HAL_ENTER_CRITICAL_SECTION(x)   st( x = EA;  HAL_DISABLE_INTERRUPTS(); )
    7 #define HAL_EXIT_CRITICAL_SECTION(x)    st( EA = x; )
    8 #define HAL_CRITICAL_STATEMENT(x)       st( halIntState_t _s; HAL_ENTER_CRITICAL_SECTION(_s); x; HAL_EXIT_CRITICAL_SECTION(_s); )
    View Code
  • 相关阅读:
    控件显示和隐藏
    删除标题和边框
    界面图片
    VC界面最前端显示
    在VC++6.0开发中实现全屏显示
    VC比例放大缩小
    plsql dev
    通过OCCI连接oracle(C++)
    VC++使用Pro*CC++
    文件对话框
  • 原文地址:https://www.cnblogs.com/gjianw217/p/4493350.html
Copyright © 2011-2022 走看看