HEXIWEAR---FreeRTOS之任务

创建第一个任务

系统主函数如下:

void main()
{
  /** initialize the hardware */
  PE_low_level_init();

  /** disable write buffering end enable ARM exceptions */
  HEXIWEAR_EnableExceptions();

  /** initialize the startup task */
  HEXIWEAR_Init();

  /** start RTOS scheduler */
  HEXIWEAR_Start();

  while (1) {}
}

函数HEXIWEAR_Init初始化启动任务HEXIWEAR_startup



任务创建完成后,静态变量指针pxCurrentTCB(见《FreeRTOS高级篇2—FreeRTOS任务创建分析》第7节内容)指向优先级最高的就绪任务。但此时任务并不能运行,因为接下来还有关键的一步:启动FreeRTOS调度器


开启内核运行,调度便由此开始

调度器是FreeRTOS操作系统的核心,主要负责任务切换,即找出最高优先级的就绪任务,并使之获得CPU运行权。调度器并非自动运行的,需要人为启动它
API函数vTaskStartScheduler()用于启动调度器,它会:

  • 创建一个空闲任务;
  • 初始化一些静态变量;
  • 最主要的,它会初始化系统节拍定时器并设置好相应的中断;
  • 然后启动第一个任务。

http://blog.csdn.net/zhzht19861011/article/details/51331638


执行第一个任务,也就是启动任务HEXIWEAR_startup

code/HEXIWEAR/src/HEXIWEAR_driver.c

HEXIWEAR_startup分析:

  1. output GPIO configuration
  2. input GPIO configuration
  3. intern flash initialization
  4. create basic tasks
    Notification_Init – HostInterface_Init(HostInterface_TxInit,HostInterface_RxInit) – sensor_Init – GuiDriver_Init
  5. check for settings in flash at startup
  6. CLOCK_SYS_Init POWER_SYS_Init
  7. turn on regular battery readings

搜索OSA_TaskCreate
这里写图片描述

分析上图可知,启动任务HEXIWEAR_startup,开启了
power_Task
sensor_GetData
HostInterface_TxTask
HostInterface_RxTask
watch_TimeUpdateTask
watch_GetPacketsTask
watch_GuiUpdateTask
七个任务,执行完成后自动Destroy自己。

这里写图片描述
注:上图注释有误,其实不止四个Tasks,加上Watch的三个,应该是七个。

watch_TimeUpdateTask
watch_GetPacketsTask
watch_GuiUpdateTask
这三个任务,HEXIWEAR_startup—>GuiDriver_Init—>进入开机画面—>进入watch画面,后创建的。

power_Task
功耗管理任务,主要是负责HEXIWEAR的自动睡眠

HostInterface_TxTask
HostInterface_RxTask
与K40 的MCU接口接受任务,主要负责处理接受到的数据包

sensor_GetData
Sensor数据读取任务,负责循环读取各个sensor的数据



从上图中可以看出,除了上面的后四个任务,其余任务基本上都和GUI的各个界面一一对应。那这些其余的任务,肯定是跟着界面的跳动动态创建和销毁。参考我博客的GUI 篇,你可以知道界面如何跳转的。


开机默认界面Watch

也就是找watch_CreateTasks这个任务何时被创建。
HEXIWEAR_startup—>
GuiDriver_Init—>
GuiDriver_Navigation( GUI_NAVIGATION_SPLASH, NULL ); (直接开机画面)
GuiDriver_Navigation( GUI_NAVIGATION_WATCH, NULL ); (进入Watch界面)
—>

gui_status_t GuiDriver_Navigation(guiNavigationDir_t navigationDir, void *param)
{
    const guiScreen_t* ptrNewScreen;
    oled_transition_t transition;
    void *destroyParam = NULL;
    void *initParam = NULL;
    void *createParam = NULL;

    const guiNavigation_t* navigation = &guiDriver_display.guiItem->navigation;

    switch(navigationDir)
    {
        /**
         * splash screen (启动画面)
         */
        case GUI_NAVIGATION_SPLASH:
        {
            ptrNewScreen = &splashScreen;
            transition = OLED_TRANSITION_NONE;
            break;
        }

        /**
         * goto watch directly(直接进入watch 界面)
         */

         case GUI_NAVIGATION_WATCH:
         {
             ptrNewScreen = &watchScreen;
             transition = OLED_TRANSITION_NONE;
             break;
         }

......
    // update the current gui item
    guiDriver_display.guiItem = (guiScreen_t*)ptrNewScreen;

    // starting action for the new screen
    if( NULL != ptrNewScreen->initFunction )
    {
        ptrNewScreen->initFunction(initParam);
    }

    while (1)
    {
        statusOLED = OLED_DrawScreen(
                                        guiDriver_display.image,
                                        xCrd,
                                        yCrd,
                                        width,
                                        height,
                                        transition
                                    );
        if ( OLED_STATUS_SUCCESS == statusOLED )
        {
            break;
        }
    }

    if(haptic_CurrentStateGet() == hapticState_enable)
    {
        //OSA_TimeDelay(50);
        haptic_MutexUnlock();
    }

    if( OLED_STATUS_SUCCESS == statusOLED )
    {
      // post-load action for the new screen (就在这里创建了Watch的任务)
      if( NULL != ptrNewScreen->createTaskFunction )
      {
        ptrNewScreen->createTaskFunction(createParam);
      }

      return GUI_STATUS_SUCCESS;
    }

    else
    {
      return GUI_STATUS_ERROR;
    }
......

ptrNewScreen = &watchScreen;

// update the current gui item
guiDriver_display.guiItem = (guiScreen_t*)ptrNewScreen;

ptrNewScreen->initFunction(initParam);

ptrNewScreen->createTaskFunction(createParam);


如何快速的知道一个系统到底会创建多少个任务?

其实,每个任务的创建我们都会给其定义一个优先级,作为参数传进去。所以,只要找一下各个任务的的优先级的宏定义就好了。
HEXIWEAR的任务优先级定义在HEXIWEAR_info.h中。

/** tasks' priorities */
#define HEXIWEAR_STARTUP_PRIO ( 1 )
#define HEXIWEAR_KW40_INTF_TASK_OK_PRIO ( gHostInterfaceOkPriority_c )
#define HEXIWEAR_KW40_INTF_TASK_Tx_PRIO ( gHostInterfaceTxPriority_c )
#define HEXIWEAR_KW40_INTF_TASK_Rx_PRIO ( gHostInterfaceRxPriority_c )
#define HEXIWEAR_GUI_PRIO     ( 5 )
#define HEXIWEAR_APP_PRIO     ( 6 )
#define HEXIWEAR_SENSOR_PRIO  ( 7 )
#define HEXIWEAR_USB_TASK     ( USB_PRIO )

#define HEXIWEAR_TASK_SENSOR_TAG_PRIO     ( SENSOR_GET_DATA_PRIO )
#define HEXIWEAR_APP_WATCH_DATA_PRIO      ( WATCH_PRIO )
发布了51 篇原创文章 · 获赞 26 · 访问量 8万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章