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 }
原文地址:https://www.cnblogs.com/st-home/p/13263279.html