• RT-thread 用宏进行自动初始化


      摘要:rt-thread 有一个机制是在main函数在运行已经将外设和组件自动用宏INIT_EXPORT(fn, level)初始化外设,接下来就要分析一下原理并模仿这种自动化初始化机制自己实现。

      实现原理:1.将初始化函数注册到自定义的段中,然后分层级自动初始化设备

           2.$sub$$main $supur$$main  在main运行之前实现自动初始。  

    具体实现可以参考文章:https://www.cnblogs.com/King-Gentleman/p/4570559.html

    在这里贴一下自己实现的代码(MDK):

      1 #include "init.h"
      2 #if 0
      3 static init_func_t *init_list_begin;
      4 static init_func_t *init_list_end;
      5 
      6 void sys_init(void)
      7 {
      8     init_func_t *index;
      9 #if defined(__CC_ARM) || defined(__CLANG_ARM) 
     10     extern const int INIT_LIST$$Base;   
     11     extern const int INIT_LIST$$Limit;
     12     init_list_begin = (init_func_t *)&INIT_LIST$$Base;   //获得段起始地址
     13     init_list_end   = (init_func_t *)&INIT_LIST$$Limit;  //获得结束段地址
     14 #elif defined(__ICCARM__)                      /* IAR ARMCC Complier */
     15 
     16 #elif defined(__GNUC__)                        /* GNUC Complier */
     17 
     18 #endif
     19     for(index = init_list_begin; index < init_list_end; index++)
     20     {
     21         index->_init_func();
     22     }
     23 }
     24 #else
     25 
     26 
     27 
     28 
     29 #ifdef RT_USING_COMPONENTS_INIT
     30 /*
     31  * Components Initialization will initialize some driver and components as following
     32  * order:
     33  * rti_start         --> 0
     34  * rti_board_start   --> 0.end
     35  * BOARD_EXPORT      --> 1
     36  * rti_board_end     --> 1.end
     37  *
     38  * DEVICE_EXPORT     --> 2
     39  * COMPONENT_EXPORT  --> 3
     40  * FS_EXPORT         --> 4
     41  * ENV_EXPORT        --> 5
     42  * APP_EXPORT        --> 6
     43  *
     44  * rti_end           --> 6.end
     45  *
     46  * These automatically initialization, the driver or component initial function must
     47  * be defined with:
     48  * INIT_BOARD_EXPORT(fn);
     49  * INIT_DEVICE_EXPORT(fn);
     50  * ...
     51  * INIT_APP_EXPORT(fn);
     52  * etc.
     53  */
     54 static int rti_start(void)
     55 {
     56     return 0;
     57 }
     58 INIT_EXPORT(rti_start, "0");
     59 
     60 static int rti_board_start(void)
     61 {
     62     return 0;
     63 }
     64 INIT_EXPORT(rti_board_start, "0.end");
     65 
     66 static int rti_board_end(void)
     67 {
     68     return 0;
     69 }
     70 INIT_EXPORT(rti_board_end, "1.end");
     71 
     72 static int rti_end(void)
     73 {
     74     return 0;
     75 }
     76 INIT_EXPORT(rti_end, "6.end");
     77 
     78 /**
     79  * RT-Thread Components Initialization for board
     80  */
     81 void components_board_init(void)
     82 {
     83 #if RT_DEBUG_INIT
     84     int result;
     85     const struct rt_init_desc *desc;
     86     Printk(RT_DEBUG_INIT,("do components board initialization.
    "));
     87     for (desc = &__rt_init_desc_rti_board_start; desc < &__rt_init_desc_rti_board_end; desc ++)
     88     {     
     89         result = desc->fn();
     90         Printk(RT_DEBUG_INIT,(" %s init..,return code:%d 
    ", desc->fn_name,result)); 
     91     }
     92 #else
     93     volatile const init_fn_t *fn_ptr;
     94 
     95     for (fn_ptr = &__rt_init_rti_board_start; fn_ptr < &__rt_init_rti_board_end; fn_ptr++)
     96     {
     97         (*fn_ptr)();
     98     }
     99 #endif
    100 }
    101 
    102 /**
    103  * Thread Components Initialization
    104  */
    105 void components_init(void)
    106 {
    107 #if RT_DEBUG_INIT
    108     int result;
    109     const struct rt_init_desc *desc;
    110 
    111     Printk(RT_DEBUG_INIT,("do components initialization.
    "));
    112     for (desc = &__rt_init_desc_rti_board_end; desc < &__rt_init_desc_rti_end; desc ++)
    113     {
    114         result = desc->fn();
    115         Printk(RT_DEBUG_INIT,("%s init..,return code:%d 
    ", desc->fn_name,result));
    116     }
    117 #else
    118     volatile const init_fn_t *fn_ptr;
    119 
    120     for (fn_ptr = &__rt_init_rti_board_end; fn_ptr < &__rt_init_rti_end; fn_ptr ++)
    121     {
    122         (*fn_ptr)();
    123     }
    124 #endif
    125 }
    126 #endif   /* RT_USING_COMPONENTS_INIT */
    127 
    128 #endif
     1 typedef int (*init_fn_t)(void);
     2 
     3 #if RT_DEBUG_INIT
     4     struct rt_init_desc
     5     {
     6         const char* fn_name;
     7         const init_fn_t fn;
     8     };
     9     #define INIT_EXPORT(fn, level)                                                       
    10         const char __rti_##fn##_name[] = #fn;                                            
    11         RT_USED const struct rt_init_desc __rt_init_desc_##fn SECTION(".init_fn." level) = 
    12         { __rti_##fn##_name, fn};
    13 #else
    14     #define INIT_EXPORT(fn, level)                                                       
    15         RT_USED const init_fn_t __rt_init_##fn SECTION(".rti_fn." level) = fn
    16 #endif
    17 
    18 
    19 /* board init routines will be called in board_init() function */
    20 #define INIT_BOARD_EXPORT(fn)           INIT_EXPORT(fn, "1")
    21 
    22 /* pre/device/component/env/app init routines will be called in init_thread */
    23 /* components pre-initialization (pure software initilization) */
    24 #define INIT_PREV_EXPORT(fn)            INIT_EXPORT(fn, "2")
    25 /* device initialization */
    26 #define INIT_DEVICE_EXPORT(fn)          INIT_EXPORT(fn, "3")
    27 /* components initialization (dfs, lwip, ...) */
    28 #define INIT_COMPONENT_EXPORT(fn)       INIT_EXPORT(fn, "4")
    29 /* environment initialization (mount disk, ...) */
    30 #define INIT_ENV_EXPORT(fn)             INIT_EXPORT(fn, "5")
    31 /* appliation initialization (gui application etc ...) */
    32 #define INIT_APP_EXPORT(fn)             INIT_EXPORT(fn, "6")
    33 
    34 
    35 
    36 void components_board_init(void);
    37 void components_init(void);
     1 void show_version(void)
     2 {
     3     Printk(SYSTERM_INFO_DEBUG,("
     \ | /
    "));
     4     Printk(SYSTERM_INFO_DEBUG,("- ST -     Thread Operating System
    "));
     5     Printk(SYSTERM_INFO_DEBUG,(" / | \     %s.%s.%d build %s
    ",
     6                PCB_VERSION, SW_VERSION, APP_OPTIONS, __DATE__));
     7     Printk(SYSTERM_INFO_DEBUG,(" 2020 - 2020 Copyright by ST team
    "));
     8 }
     9 
    10 
    11 int hw_board_init(void)
    12 {
    13     __set_PRIMASK(0);
    14     SystemCoreClockUpdate();
    15     __set_PRIMASK(1);
    16 
    17     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
    18 
    19     /* all usart initlization */
    20     usart_Initialize_all();
    21     
    22 #ifdef LOGDEBUG_TTL_USART_INDEX
    23     usart_Initialize(LOGDEBUG_TTL_USART_INDEX,LogUsartRcvCB);
    24 #endif   
    25     
    26     /* show Thread version */
    27      show_version();
    28 
    29     TimerInitialize(CYCLE_TASK_TIMER_INDEX,CycleTask);
    30     
    31 
    32 
    33     
    34     components_board_init();
    35     
    36     return ARM_EOK;
    37 }
    38 
    39 
    40  void main_thread_entry( void )
    41  {
    42      extern int main(void);
    43      extern int $Super$$main(void);
    44     
    45      components_init();
    46      
    47      $Super$$main();    /* 代指main函数 */
    48      
    49      
    50  }
    51 
    52 int application_init(void)
    53 {
    54     bool bRet = false;    
    55     static    TaskHandle_t xGeneralTaskHandle = NULL;
    56     if(NULL == xGeneralTaskHandle)
    57     {
    58         bRet = xTaskCreate((TaskFunction_t)main_thread_entry,(const char*)"main task",configMINIMAL_STACK_SIZE * 10,NULL,(UBaseType_t)1,(TaskHandle_t*)&xGeneralTaskHandle);
    59         if(bRet != NULL)
    60         {
    61             
    62         }
    63     }
    64     return bRet;
    65 }
    66 
    67 int thread_startup(void)
    68 {
    69      /* board level initialization
    70      * NOTE: please initialize heap inside board initialization.
    71      */
    72      hw_board_init();
    73 
    74     /* create init_thread */
    75      application_init();
    76 
    77     /* start scheduler */
    78      vTaskStartScheduler();
    79 
    80     /* never reach here */
    81     return 0;
    82 }
    83 
    84 /* re-define main function */
    85 int $Sub$$main(void)      /* 相当于补丁,在main函数之前运行的函数 */
    86 {
    87     thread_startup();
    88     return 0;
    89 }
  • 相关阅读:
    Android Activity中获取当前焦点的控件,自动化输入EditText
    Java Android 二进制文件读写
    Delphi 动态数组、静态数组、TBytes 的区别
    IIS日志分析工具-Log Parser
    信息安全等级保护三级系统基线要求判分标准之应用安全
    通过TCPView工具查看foxmail用exchange方式连接exchange时用什么端口
    Windows2008R2操作系统日志清理
    批量IP自动netcat脚本
    批量IP自动ping脚本
    批量移动AD用户到指定OU
  • 原文地址:https://www.cnblogs.com/st-home/p/13263279.html
Copyright © 2020-2023  润新知