一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

RT-Thread自動(dòng)初始化機(jī)制

RT-Thread 操作系統(tǒng) ? 來源:RT-Thread 操作系統(tǒng) ? 作者:RT-Thread 操作系統(tǒng) ? 2022-06-17 08:52 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

??在分析之前首先查閱 RT-Thread 的官方文檔 [RT-Thread 自動(dòng)初始化機(jī)制](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/basic/basic?id=rt-thread-自動(dòng)初始化機(jī)制),根據(jù)官方文檔的講述在 RTT 源碼中一共使用了 6 中順序的初始化,本文以其中的一個(gè) INIT_APP_EXPORT(fn) 為例進(jìn)行自動(dòng)初始化的原理分析,其他順序的初始化的原理與之一致。

初始化順序 接口 描述
1 INIT_BOARD_EXPORT(fn) 非常早期的初始化,此時(shí)調(diào)度器還未啟動(dòng)
2 INIT_PREV_EXPORT(fn) 主要是用于純軟件的初始化、沒有太多依賴的函數(shù)
3 INIT_DEVICE_EXPORT(fn) 外設(shè)驅(qū)動(dòng)初始化相關(guān),比如網(wǎng)卡設(shè)備
4 INIT_COMPONENT_EXPORT(fn) 組件初始化,比如文件系統(tǒng)或者 LWIP
5 INIT_ENV_EXPORT(fn) 系統(tǒng)環(huán)境初始化,比如掛載文件系統(tǒng)
6 INIT_APP_EXPORT(fn) 應(yīng)用初始化,比如 GUI 應(yīng)用

1 知識(shí)點(diǎn)補(bǔ)充

1.1 __attribute__ 關(guān)鍵字

??1. 關(guān)鍵字__attribute__ 是 GNU C 實(shí)現(xiàn)的編譯屬性設(shè)置機(jī)制,也就是通過給函數(shù)或者變量聲明屬性值,以便讓[編譯器](https://so.csdn.net/so/search?q=編譯器&spm=1001.2101.3001.7020)能夠?qū)σ幾g的程序進(jìn)行優(yōu)化處理。

??2. 關(guān)鍵字 __attribute__((section(x))) 是告訴編譯器,將作用的函數(shù)或數(shù)據(jù)放入指定名為 ”x” 輸入段中。 舉個(gè)例子,看下面一段代碼:

int a __attribute__(section(“var”)) = 0;

??定義了一個(gè)整形變量 a,然后將其賦值為0,而中間的 __attribute__(section(“var”)) 語(yǔ)句的作用是將變量 a 放入指定的段 var 中。而如果不指定變量所處的段的話,編譯器就會(huì)隨機(jī)將其分配在內(nèi)存中。

??3. __attribute__((used)) 的含義是即使它們沒有被引用,也留在目標(biāo)文件中,也就是告訴編譯器,我聲明的這個(gè)符號(hào)是需要保留的。

1.2 函數(shù)指針

1.2.1 簡(jiǎn)單的函數(shù)指針的運(yùn)用

??使用簡(jiǎn)單的函數(shù)指針的示例如下

#include 
/* 定義了一個(gè)指針變量p,該變量指向某種函數(shù),這種函數(shù)有兩個(gè)int類型參數(shù),返回一個(gè)int類型的值*/
/* 只有第一句我們還無法使用這個(gè)指針,因?yàn)槲覀冞€未對(duì)它進(jìn)行賦值 */
int (*p)(int, int);

/* 定義了一個(gè)求和函數(shù) */
int add(int a, int b)
{
    return a + b;
}

int main(void)
{
	int sum = 0;
   	
	p = add;  // 將函數(shù) add() 的地址賦值給變量 p 

	printf("add  = %08X\n", *((unsigned int *)add));
	printf("*add = %08X\n", *((unsigned int *)*add));
	printf("&add = %08X\n", *((unsigned int *)&add));
	printf("p    = %08X\n", *((unsigned int *)p));
	printf("*p   = %08X\n", *((unsigned int *)*p));
	printf("&p   = %08X\n", *((unsigned int *)&p));
   	
	sum = (*p)(1, 2);
   	//sum = p(1, 2);    // 這兩種寫法都可以
   	
	printf("sum = %d\n", sum);
        	
	return 0;
}


/* 運(yùn)行結(jié)果 */
add  = 0xE5894855
*add = 0xE5894855
&add = 0xE5894855
p    = 0xE5894855
*p   = 0xE5894855
&p   = 0x0040052D   // 變量p的地址與函數(shù)指針值
sum = 3

??從上面的結(jié)果看來,我們應(yīng)該把函數(shù)名,當(dāng)成指針看待。最常見的函數(shù)調(diào)用方式:fnc1(); 只是 (*fnc1)(); 簡(jiǎn)寫形式而已。我們之所以可以 fnc1(); 這樣調(diào)用函數(shù),只是編譯器幫我們做了調(diào)整。對(duì)于函數(shù)名 fnc1 來說,不管是 *fnc1 還是 fnc1 還是 &fnc1,編譯器都認(rèn)為他是函數(shù)指針。

1.2.2 使用 typedef 定義的函數(shù)指針

??使用 typedef 定義的函數(shù)指針的示例如下

#include 
/* typedef 的功能是定義新的類型,就是定義了一種 pFunc 的類型 */
/* pFunc 這種類型為指向某種函數(shù)的指針,這種函數(shù)以兩個(gè)int類型為參數(shù)并返回int類型 */
typedef int (*pFunc)(int, int);

/* 定義了一個(gè)求和函數(shù) */
int add(int a, int b)
{
	return a + b;
}

int main(void)
{
	int sum = 0;
   	
	pFunc p = add; // 使用 pFunc 這種類型定義了變量p,將函數(shù) add() 的地址賦值給變量 p

	printf("add  = 0x%08X\n", *((unsigned int *)add));
	printf("*add = 0x%08X\n", *((unsigned int *)*add));
	printf("&add = 0x%08X\n", *((unsigned int *)&add));
	printf("p    = 0x%08X\n", *((unsigned int *)p));
	printf("*p   = 0x%08X\n", *((unsigned int *)*p));
	printf("&p   = 0x%08X\n", *((unsigned int *)&p));
	sum = (*p)(1, 2);
	//sum = p(1, 2);  // 這兩種寫法都可以
	printf("sum = %d\n", sum);
        	
	return 0;
}


/* 運(yùn)行結(jié)果 */
add  = 0xE5894855
*add = 0xE5894855
&add = 0xE5894855
p    = 0xE5894855
*p   = 0xE5894855
&p   = 0x0040052D
sum = 3

1.3 鏈接腳本解析

??摘抄 RT-Thread 鏈接腳本中和本文有關(guān)的內(nèi)容如下所示

/* section information for initial. */
. = ALIGN(4);              /* 按照四字節(jié)對(duì)齊 */
__rt_init_start = .;       /* 開始一個(gè) "片段" */
KEEP(*(SORT(.rti_fn*)))    /* 告訴鏈接器保留 ".rti_fn*" 的段,并將其排序 */
__rt_init_end = .;         /* 結(jié)束一個(gè) "片段" */

??其中 SORT 關(guān)鍵字的含義是鏈接器會(huì)在把文件和 section 放到 輸出文件中之前按名字順序重新排列它們。

??該鏈接腳本部分定義了申明各種自動(dòng)初始化函數(shù)在進(jìn)行鏈接時(shí)的排列順序,因?yàn)?RT-Thread 源碼中一共定義了六種實(shí)現(xiàn)自動(dòng)初始化功能的宏接口,詳見本文最開始的表格,所以也就可以解釋為什么 INIT_BOARD_EXPORT(fn) 在自動(dòng)初始化的最開始,而 INIT_APP_EXPORT(fn) 在自動(dòng)初始化的結(jié)尾,就是因?yàn)?SORT 關(guān)鍵字在起作用。

2 自動(dòng)初始化原理分析

??RT-Thread 源碼中一共有六種不同順序的自動(dòng)初始化宏定義,如下所示

/* rt-thread/include/rtdef.h */
#define INIT_BOARD_EXPORT(fn)           INIT_EXPORT(fn, "1")
#define INIT_PREV_EXPORT(fn)            INIT_EXPORT(fn, "2")
#define INIT_DEVICE_EXPORT(fn)          INIT_EXPORT(fn, "3")
#define INIT_COMPONENT_EXPORT(fn)       INIT_EXPORT(fn, "4")
#define INIT_ENV_EXPORT(fn)             INIT_EXPORT(fn, "5")
#define INIT_APP_EXPORT(fn)             INIT_EXPORT(fn, "6")

2.1 自動(dòng)初始化宏定義解析

??查看 RT-Thread 的源碼中自動(dòng)初始化宏定義,以 INIT_APP_EXPORT(fn) 為例進(jìn)行分析, INIT_APP_EXPORT(fn) 的定義如下。其中宏定義中 ## 連接符號(hào)由兩個(gè)井號(hào)組成,其功能是在帶參數(shù)的宏定義中將兩個(gè)子串(token)聯(lián)接起來。

/* rt-thread/include/rtdef.h */
#define INIT_APP_EXPORT(fn) INIT_EXPORT(fn, "6")    
   #define INIT_EXPORT(fn, level) RT_USED const init_fn_t __rt_init_##fn RT_SECTION(".rti_fn." level) = fn

??其中里面的宏定義如下

#define RT_USED  __attribute__((used))
typedef int (*init_fn_t)(void);  /* init_fn_t 為函數(shù)指針 */ 
#define RT_SECTION(x)  __attribute__((section(x)))

??以文件 rt-thread/components/finsh/shell.c 中 Finsh 控制臺(tái)初始化函數(shù) INIT_APP_EXPORT(finsh_system_init)為例,參照上面的宏定義規(guī)則分布展開和最終結(jié)果如下

INIT_APP_EXPORT(finsh_system_init)
   |-> INIT_EXPORT(finsh_system_init, "6")
       |-> RT_USED const init_fn_t __rt_init_finsh_system_init RT_SECTION(".rti_fn." "6") = finsh_system_init
           |-> __attribute__((used)) const init_fn_t __rt_init_finsh_system_init __attribute__((section(".rti_fn.6"))) = finsh_system_init

??結(jié)合第1小節(jié)的補(bǔ)充知識(shí),上述宏定義展開的最終結(jié)果的含義為:定一個(gè)一個(gè) init_fn_t 類型的函數(shù)指針變量 __rt_init_finsh_system_init ,將 finsh_system_init() 函數(shù)的地址賦值給了定義的變量, 并且將該變量放到了指定的段 ".rti_fn.6" 中。

??所以說只要在代碼中使用 INIT_APP_EXPORT(fn) 申明的初始化函數(shù)最終都會(huì)定義在指定的段 ".rti_fn.6" 中。

2.2 組件初始化調(diào)用解析

??參考官方文檔 [RT-Thread 啟動(dòng)流程](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/basic/basic?id=rt-thread-啟動(dòng)流程),在調(diào)度器的啟動(dòng)函數(shù)執(zhí)行時(shí),會(huì)調(diào)用 rt_components_init() 函數(shù)對(duì)申明的各種初始化函數(shù)進(jìn)行調(diào)用,RT-Thread 的啟動(dòng)流程如下圖所示。

poYBAGECCgiAaInbAAEs3dd2mrs534.png

??函數(shù) rt_components_init() 的源碼如下所示,因?yàn)闆]有定義宏 RT_DEBUG_INIT,所以直接將和宏 RT_DEBUG_INIT 有關(guān)的代碼省略掉

/* rt-thread/src/components.c */
void rt_components_init(void)
{
#if RT_DEBUG_INIT
   ... ...  /* 省略掉與分析無關(guān)的代碼 */
#else
   volatile const init_fn_t *fn_ptr;
   for (fn_ptr = &__rt_init_rti_board_end; fn_ptr < &__rt_init_rti_end; fn_ptr ++)
   {
       (*fn_ptr)();
   }
#endif /* RT_DEBUG_INIT */
}

??其中 __rt_init_rti_board_end 和 __rt_init_rti_end 表示不同的段。在系統(tǒng)源碼中又定義了幾個(gè)空函數(shù)來申明了一些段,如下所示。

/* rt-thread/src/components.c */
/* 宏定義展開后段名為 ".rti_fn.0" ,函數(shù)指針變量為 __rt_init_rti_start */
static int rti_start(void)
{
   return 0;
}
INIT_EXPORT(rti_start, "0");         
   
/* 宏定義展開后段名為 ".rti_fn.0.end" ,函數(shù)指針變量為 __rt_init_rti_board_start */
static int rti_board_start(void)
{
   return 0;
}
INIT_EXPORT(rti_board_start, "0.end");  

/* 宏定義展開后段名為 ".rti_fn.1.end" ,函數(shù)指針變量為 __rt_init_rti_board_end */
static int rti_board_end(void)
{
   return 0;
}
INIT_EXPORT(rti_board_end, "1.end");    

/* 宏定義展開后段名為 ".rti_fn.6.end" ,函數(shù)指針變量為 __rt_init_rti_end */
static int rti_end(void)
{
   return 0;
}
INIT_EXPORT(rti_end, "6.end");     

??上面幾個(gè)函數(shù)的導(dǎo)出,再加上6個(gè)自動(dòng)初始化宏定義的導(dǎo)出,結(jié)合 1.3 小節(jié)連接腳本的分析,可以得到各個(gè)段名 和 對(duì)應(yīng)的函數(shù)指針 / 宏的名字 及 前后順序如下表所示。

section 名 函數(shù)指針 / 宏
.rti_fn.0 __rt_init_rti_start
.rti_fn.0.end __rt_init_rti_board_start
.rti_fn.1 INIT_BOARD_EXPORT(fn)
.rti_fn.1.end __rt_init_rti_board_end
.rti_fn.2 INIT_PREV_EXPORT(fn)
.rti_fn.3 INIT_DEVICE_EXPORT(fn)
.rti_fn.4 INIT_COMPONENT_EXPORT(fn)
.rti_fn.5 INIT_ENV_EXPORT(fn)

.rti_fn.6

.rti_fn.6.end

INIT_APP_EXPORT(fn)

__rt_init_rti_end

??我們可以通過編譯生成的 map 文件對(duì)上述的分析進(jìn)行驗(yàn)證,map 文件通常位于工程的 Debug 目錄下,在 map 文件中搜索 .rti_fn* 可以找到如下所示的內(nèi)容??梢钥吹浇?jīng)過排序后的各個(gè)自動(dòng)初始化的段和對(duì)應(yīng)的函數(shù)指針,我們前面分析的 Finsh 自動(dòng)初始化的函數(shù)指針 __rt_init_finsh_system_init 就位于段 ".rti_fn.6" 中。并且從里面我們還可以看出每個(gè)函數(shù)指針都占 4 個(gè)字節(jié)的空間,因?yàn)樵?32 位的系統(tǒng)中無論什么樣的指針都占 4 個(gè)字節(jié)的空間。

*(SORT(.rti_fn*))
.rti_fn.0      0x08075220        0x4 ./rt-thread/src/components.o
               0x08075220                __rt_init_rti_start
.rti_fn.0.end  0x08075224        0x4 ./rt-thread/src/components.o
               0x08075224                __rt_init_rti_board_start
.rti_fn.1      0x08075228        0x4 ./rt-thread/components/utilities/ulog/ulog.o
               0x08075228                __rt_init_ulog_init
.rti_fn.1      0x0807522c        0x4 ./drivers/drv_clk.o
               0x0807522c                __rt_init_clock_information
.rti_fn.1      0x08075230        0x4 ./drivers/drv_spi.o
               0x08075230                __rt_init_rt_hw_spi_init
.rti_fn.1      0x08075234        0x4 ./drivers/drv_wdt.o
               0x08075234                __rt_init_rt_wdt_init
.rti_fn.1      0x08075238        0x4 ./applications/peripheral/src/hn_psram.o
               0x08075238                __rt_init_rt_hw_psram_init
.rti_fn.1.end  0x0807523c        0x4 ./rt-thread/src/components.o
               0x0807523c                __rt_init_rti_board_end
.rti_fn.2      0x08075240        0x4 ./rt-thread/components/utilities/ulog/backend/console_be.o
               0x08075240                __rt_init_ulog_console_backend_init
.rti_fn.2      0x08075244        0x4 ./rt-thread/components/utilities/ulog/ulog.o
               0x08075244                __rt_init_ulog_async_init
.rti_fn.2      0x08075248        0x4 ./rt-thread/components/net/lwip-2.0.3/src/arch/sys_arch.o
               0x08075248                __rt_init_lwip_system_init
.rti_fn.2      0x0807524c        0x4 ./rt-thread/components/drivers/src/workqueue.o
               0x0807524c                __rt_init_rt_work_sys_workqueue_init
.rti_fn.2      0x08075250        0x4 ./rt-thread/components/dfs/src/dfs.o
               0x08075250                __rt_init_dfs_init
.rti_fn.3      0x08075254        0x4 ./drivers/drv_rtc.o
               0x08075254                __rt_init_rt_hw_rtc_init
.rti_fn.4      0x08075258        0x4 ./rt-thread/components/net/sal_socket/src/sal_socket.o
               0x08075258                __rt_init_sal_init
.rti_fn.4      0x0807525c        0x4 ./rt-thread/components/libc/pthreads/pthread.o
               0x0807525c                __rt_init_pthread_system_init
.rti_fn.4      0x08075260        0x4 ./rt-thread/components/libc/compilers/gcc/newlib/libc.o
               0x08075260                __rt_init_libc_system_init
.rti_fn.4      0x08075264        0x4 ./rt-thread/components/libc/compilers/common/time.o
               0x08075264                __rt_init__rt_clock_time_system_init
.rti_fn.4      0x08075268        0x4 ./rt-thread/components/dfs/filesystems/elmfat/dfs_elm.o
               0x08075268                __rt_init_elm_init
.rti_fn.4      0x0807526c        0x4 ./packages/ppp_device-v1.1.0/class/ppp_device_ec20.o
               0x0807526c                __rt_init_ppp_ec20_register
.rti_fn.4      0x08075270        0x4 ./applications/peripheral/src/hn_spi_flash.o
               0x08075270                __rt_init_hn_spi_flash_init
.rti_fn.6      0x08075274        0x4 ./rt-thread/components/finsh/shell.o
               0x08075274                __rt_init_finsh_system_init
.rti_fn.6      0x08075278        0x4 ./packages/ppp_device-v1.1.0/samples/ppp_sample.o
               0x08075278                __rt_init_ppp_sample_start
.rti_fn.6      0x0807527c        0x4 ./applications/user/src/hn_pvd_detect.o
               0x0807527c                __rt_init_pvd_detect_init
.rti_fn.6      0x08075280        0x4 ./applications/user/src/hn_smtp.o
               0x08075280                __rt_init_hn_smtp_init
.rti_fn.6      0x08075284        0x8 ./applications/peripheral/src/hn_spi_flash.o
               0x08075284                __rt_init_hn_spi_flash_filesystem_init
               0x08075288                __rt_init_hn_easyflash_init
.rti_fn.6.end  0x0807528c        0x4 ./rt-thread/src/components.o
               0x0807528c                __rt_init_rti_end
               0x08075290                __rt_init_end = .
               0x08075290                . = ALIGN (0x4)
               [!provide]                PROVIDE (__ctors_start__, .)

??再結(jié)合上面的 rt_components_init() 函數(shù)中的具體實(shí)現(xiàn)源碼分析,我們可以看到函數(shù)指針在 for 循環(huán)的開始指向了 __rt_init_rti_board_end,也就是指向了函數(shù) rti_board_end(),該函數(shù)沒有任何操作直接返回了0。

??當(dāng)滿足條件fn_ptr < &__rt_init_rti_end 時(shí),fn_ptr每次循環(huán)自加1,根據(jù)生成的 map 文件可以看出下一次就指向了 __rt_init_ulog_console_backend_init ,也就是指向了函數(shù) ulog_console_backend_init() ,該函數(shù)對(duì) ulog輸出到控制臺(tái)進(jìn)行了初始化。

??每次循環(huán)過程中fn_ptr自加1,然后執(zhí)行對(duì)應(yīng)的初始化函數(shù),一直到 fn_ptr 自加后等于 &__rt_init_rti_end時(shí)循環(huán)結(jié)束,在這個(gè)過程中就執(zhí)行了各種自動(dòng)初始化的代碼,完成了自動(dòng)初始化的任務(wù)。

volatile const init_fn_t *fn_ptr;
for (fn_ptr = &__rt_init_rti_board_end; fn_ptr < &__rt_init_rti_end; fn_ptr ++)
{
	(*fn_ptr)();
}

??為什么fn_ptr = &__rt_init_rti_board_end 這個(gè)地方要使用取地址 & 符號(hào)呢?因?yàn)?fn_ptr是一個(gè)指向函數(shù)指針的指針,根據(jù)本文 2.1 小節(jié)的分析 __rt_init_rti_board_end 是一個(gè)函數(shù)指針變量,也就是說 fn_ptr 最開始指向的是函數(shù)指針變量 __rt_init_rti_board_end 的地址,根據(jù) map 文件也就是 0x0807523c,指針每次循環(huán)自加1也就是加上4個(gè)字節(jié)的大小,就指向了下一個(gè)位置 0x08075240,(*fn_ptr)(); 也就是把該位置的內(nèi)容取出來也就是相當(dāng)于 __rt_init_ulog_console_backend_init();。

3 總結(jié)

??為什么 RT-Thread 要采用這種復(fù)雜的方式來進(jìn)行自動(dòng)初始化操作呢?我認(rèn)為是 RT-Thread 采用和 Linux 一樣的機(jī)制,為了實(shí)現(xiàn)驅(qū)動(dòng)和應(yīng)用的分層將驅(qū)動(dòng)的初始化操作在 main() 函數(shù)之前就進(jìn)行初始化后注冊(cè)好,等到運(yùn)行到 main() 函數(shù)后,用戶只需要關(guān)心應(yīng)用層的額代碼即可,如果不采用這種方式而是采用裸機(jī)寫法的方式在main() 函數(shù)的最開始進(jìn)行初始化,就需要執(zhí)行很多驅(qū)動(dòng)層的初始化代碼,就不能很好的實(shí)現(xiàn)驅(qū)動(dòng)和應(yīng)用的分層,也就不能很好的實(shí)現(xiàn)應(yīng)用層只需關(guān)系應(yīng)用層的邏輯而不用關(guān)系驅(qū)動(dòng)和硬件初始化的分層思想了。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 初始化
    +關(guān)注

    關(guān)注

    0

    文章

    50

    瀏覽量

    12119
  • RT-Thread
    +關(guān)注

    關(guān)注

    32

    文章

    1412

    瀏覽量

    41995
  • 函數(shù)指針
    +關(guān)注

    關(guān)注

    2

    文章

    57

    瀏覽量

    3977
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    RT-Thread自動(dòng)初始化詳解

    我們知道,在寫裸機(jī)程序時(shí),當(dāng)我們完成硬件初始化后,就需要在主函數(shù)中進(jìn)行調(diào)用。當(dāng)我們使用RT-Thread后,完全不需要這樣做了,我們可以將硬件等自動(dòng)初始化
    的頭像 發(fā)表于 06-25 21:38 ?1.2w次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>自動(dòng)</b><b class='flag-5'>初始化</b>詳解

    價(jià)值89元的嵌入式RT-Thread設(shè)計(jì)書籍僅需5積分免費(fèi)帶回家?。ㄊ致裏o!限20人)

    內(nèi)存分布263.4 RT-Thread自動(dòng)初始化機(jī)制283.5 RT-Thread內(nèi)核對(duì)象模型293.5.1 靜態(tài)對(duì)象和動(dòng)態(tài)對(duì)象293.5.
    發(fā)表于 03-18 16:08

    RT-Thread 內(nèi)核基礎(chǔ)介紹

    sensor_enable 存放在 RO 段中。RT-Thread 自動(dòng)初始化機(jī)制自動(dòng)初始化
    發(fā)表于 05-24 18:49

    RT-Thread內(nèi)核簡(jiǎn)介

    STM32 程序的內(nèi)存分布6、RT-Thread 自動(dòng)初始化機(jī)制8、RT-Thread 內(nèi)核對(duì)象模型靜態(tài)對(duì)象和動(dòng)態(tài)對(duì)
    發(fā)表于 08-06 07:44

    為什么RT-Thread要采用這種復(fù)雜的方式來進(jìn)行自動(dòng)初始化操作呢

    在分析之前首先查閱 RT-Thread 的官方文檔RT-Thread 自動(dòng)初始化機(jī)制,根據(jù)官方文檔的講述在 RTT 源碼中一共使用了 6 中
    發(fā)表于 04-06 17:49

    RT-Thread自動(dòng)初始化機(jī)制簡(jiǎn)介

    RT-Thread 的時(shí)鐘管理以時(shí)鐘節(jié)拍為基礎(chǔ),時(shí)鐘節(jié)拍是 RT-Thread 操作系統(tǒng)中最小的RT-Thread 自動(dòng)初始化
    發(fā)表于 04-06 18:08

    RT-Thread系統(tǒng)自動(dòng)初始化機(jī)制簡(jiǎn)介

    RT-Thread 自動(dòng)初始化機(jī)制1、自動(dòng)初始化機(jī)制
    發(fā)表于 04-12 17:43

    【原創(chuàng)精選】RT-Thread征文精選技術(shù)文章合集

    。RT-Thread自動(dòng)初始化詳解GD32 RISC-V系列 BSP框架制作與移植GD32407V-START開發(fā)板的BSP框架制作與移植基于Select/Poll實(shí)現(xiàn)并發(fā)服務(wù)器(一)基于Select
    發(fā)表于 07-26 14:56

    RT-Thread自動(dòng)初始化原理分析

    ;}這里我們直接就可以使用 printf 進(jìn)行打印,而沒有進(jìn)行一些其它的初始化,參考這個(gè)思路引出了 RT-Thread自動(dòng)初始化機(jī)制
    發(fā)表于 12-05 14:17

    一文詳解RT-Thread自動(dòng)初始化

    在學(xué)RT-Thread時(shí),經(jīng)常能聽到這個(gè)詞:自動(dòng)初始化。用起來也非常容易,一個(gè)宏就解決了,但是原理是什么呢?
    的頭像 發(fā)表于 07-21 10:17 ?8147次閱讀
    一文詳解<b class='flag-5'>RT-Thread</b><b class='flag-5'>自動(dòng)</b><b class='flag-5'>初始化</b>

    RT-Thread啟動(dòng)過程分析RT-Thread自動(dòng)初始化機(jī)制分析

    如上圖所示,通過對(duì)源碼的跟蹤發(fā)現(xiàn),這些INIT_XXX_EXPORT的宏定義,最終都是調(diào)用了INIT_EXPORT這個(gè)宏定義,而這個(gè)宏定義,就是把該初始化函數(shù)放在自定義的rti_fn符號(hào)段里面,源碼在rtdef.h頭文件里面,如下圖所示。
    的頭像 發(fā)表于 01-13 16:45 ?4256次閱讀
    <b class='flag-5'>RT-Thread</b>啟動(dòng)過程分析<b class='flag-5'>RT-Thread</b><b class='flag-5'>自動(dòng)</b><b class='flag-5'>初始化</b><b class='flag-5'>機(jī)制</b>分析

    RT-Thread學(xué)習(xí)筆記 --(3)RT-Thread自動(dòng)初始化機(jī)制分析

    相信不少工程師在閱讀RT-Thread相關(guān)源代碼的時(shí)候,都會(huì)經(jīng)??吹饺缦聢D所示的宏定義,按照宏定義的命名來理解,這些宏定義似乎都是對(duì)一些...
    發(fā)表于 01-25 18:55 ?1次下載
    <b class='flag-5'>RT-Thread</b>學(xué)習(xí)筆記 --(3)<b class='flag-5'>RT-Thread</b><b class='flag-5'>自動(dòng)</b><b class='flag-5'>初始化</b><b class='flag-5'>機(jī)制</b>分析

    RT-Thread全球技術(shù)大會(huì):如何使用組件以及自動(dòng)初始化流程

    RT-Thread全球技術(shù)大會(huì):如何使用組件和自動(dòng)初始化流程 ? ? ? ? ? 審核編輯:彭靜
    的頭像 發(fā)表于 05-27 15:16 ?1229次閱讀
    <b class='flag-5'>RT-Thread</b>全球技術(shù)大會(huì):如何使用組件以及<b class='flag-5'>自動(dòng)</b><b class='flag-5'>初始化</b>流程

    rt-thread線程棧初始化參數(shù)分析

    RT-Thread 在線程初始化的代碼內(nèi)有一段初始化線程堆棧的代碼
    的頭像 發(fā)表于 08-14 16:50 ?2229次閱讀
    <b class='flag-5'>rt-thread</b>線程棧<b class='flag-5'>初始化</b>參數(shù)分析

    RT-Thread使用經(jīng)驗(yàn)分享:鏈表未初始化造成死機(jī)

    最近在開發(fā)調(diào)試基于RT-Thread 的驅(qū)動(dòng)時(shí),遇到一個(gè)比較奇怪的死機(jī)問題,后來經(jīng)過一步步排查,終于發(fā)現(xiàn)是驅(qū)動(dòng)的鏈表節(jié)點(diǎn)沒有初始化造成的死機(jī)
    的頭像 發(fā)表于 10-08 14:49 ?1514次閱讀
    <b class='flag-5'>RT-Thread</b>使用經(jīng)驗(yàn)分享:鏈表未<b class='flag-5'>初始化</b>造成死機(jī)