當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 嵌入式云IOT技術(shù)圈
[導(dǎo)讀]前面移植了RT-Thread Nano,其實(shí)準(zhǔn)確來(lái)說(shuō)那不叫移植,那叫做部署,因?yàn)橐浦驳墓ぷ鞴俜揭呀?jīng)幫我們做好了。 文章鏈接:小熊派移植RT-Thread Nano 1、引發(fā)思考-相關(guān)資料檢索 在之前的文章提到過(guò),RT-Thread已經(jīng)提前在main函數(shù)以前就把跟硬件配置、系統(tǒng)初始化、啟

前面移植了RT-Thread Nano,其實(shí)準(zhǔn)確來(lái)說(shuō)那不叫移植,那叫做部署,因?yàn)橐浦驳墓ぷ鞴俜揭呀?jīng)幫我們做好了。


文章鏈接:小熊派移植RT-Thread Nano

1、引發(fā)思考-相關(guān)資料檢索

在之前的文章提到過(guò),RT-Thread已經(jīng)提前在main函數(shù)以前就把跟硬件配置、系統(tǒng)初始化、啟動(dòng)調(diào)度器等相關(guān)的都做好了,所以我們后來(lái)看到的main函數(shù)非常簡(jiǎn)潔,真是讓人感覺(jué)神清氣爽,有繼續(xù)往下寫代碼的欲望,如下:

main.c

int main(void)
{
while(1)
{
rt_kprintf("Hello RTT_NANO\n");
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
rt_thread_mdelay(500);
}
}

那具體RT-Thread又是如何實(shí)現(xiàn)在main函數(shù)執(zhí)行之前就把所有初始化硬件、時(shí)鐘的工作都做了呢?跟隨官方文檔的RT-Thread代碼啟動(dòng)流程:

跟代碼,最后發(fā)現(xiàn)如下代碼:

/* re-define main function */
int $Sub$$main(void)
{
rtthread_startup();
return 0;
}

/* the system main thread */
void main_thread_entry(void *parameter)
{
extern int main(void);
extern int $Super$$main(void);

/* RT-Thread components initialization */
rt_components_init();

/* invoke system main function */
#if defined(__CC_ARM) || defined(__CLANG_ARM)
$Super$$main(); /* for ARMCC. */
#elif defined(__ICCARM__) || defined(__GNUC__)
main();
#endif
}

平時(shí)工作開(kāi)發(fā)中沒(méi)用到這樣的語(yǔ)法,于是只能搜索文檔來(lái)看看到底是如何實(shí)現(xiàn)的,果然在Keil幫助手冊(cè)中找到了答案:

從文檔中得知,Keil MDK編譯器用$Sub$$$Super$$這兩個(gè)符號(hào)來(lái)擴(kuò)展了 main 函數(shù),這使得使用$Sub$$main可以在main函數(shù)執(zhí)行之前就預(yù)先執(zhí)行$Sub$$main函數(shù),所以在$Sub$$main函數(shù)里就可以完成一些基本的硬件、時(shí)鐘初始化功能,做完這些工作以后,還是得跳轉(zhuǎn)到main函數(shù)去執(zhí)行往后邏輯的呀,這就需要通過(guò)調(diào)用$Super$$main來(lái)實(shí)現(xiàn)了。(注:在Keil MDK編譯器中是這樣的情況,但在IAR以及GCC環(huán)境下有差別,這里不做分析,等后面用到再說(shuō))。

既然main函數(shù)之前能這么用,是不是換個(gè)函數(shù)也能這么用呢?這引發(fā)我的好奇,于是繼續(xù)查找文檔,在armlink_user_guide手冊(cè)中找到:

接下來(lái)開(kāi)始做實(shí)驗(yàn),然后我用stm32cubeMX生成一個(gè)基本裸機(jī)工程,下載到小熊派上來(lái)驗(yàn)證是否正確。

2、小熊派上進(jìn)行實(shí)踐

2.1 基本功能配置

配置外部時(shí)鐘、調(diào)試串口、調(diào)試接口以及LED


最后生成代碼。

2.2 編寫代碼進(jìn)行驗(yàn)證

首先添加一個(gè)串口重定向函數(shù),后面才能使用printf

int fputc(int ch,FILE *file)
{
return HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,1000);
}

接下來(lái)結(jié)合文檔模仿RT-Thread寫出以下函數(shù):

void $Sub$$main(void)
{
extern int main(void);
extern int $Super$$main(void);
//初始化HAL
HAL_Init();
//初始化系統(tǒng)時(shí)鐘
SystemClock_Config();
//初始化GPIO
MX_GPIO_Init();
//初始化串口
MX_USART1_UART_Init();
printf("初始化已完成\n");
//點(diǎn)燈
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
//回到真正的main函數(shù)里
$Super$$main();
}

main函數(shù)如下:

int main(void)
{
//延時(shí)2s
HAL_Delay(2000);
printf("回到main函數(shù)中\(zhòng)n");
while(1)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_Delay(500);
}
}

將程序編譯后下載到小熊派開(kāi)發(fā)板中,然后打開(kāi)串口調(diào)試助手可以看到:

由此可見(jiàn),這是一個(gè)很有逼格的技能,以后可以在支持這種擴(kuò)展符號(hào)的編譯器下將這種技能應(yīng)用起來(lái),從而簡(jiǎn)化代碼,接下來(lái)我們?cè)偻厦孢@個(gè)程序里添加功能:添加Function函數(shù)和在它之前運(yùn)行的$Sub$$Function,然后在main函數(shù)里調(diào)用Function函數(shù):

void $Sub$$Function(void)
{
extern void Function(void);
extern void $Super$$Function(void);
printf("在Function函數(shù)之前調(diào)用$Sub$$Function\n");
$Super$$Function();
}

void Function(void)
{
printf("執(zhí)行Function函數(shù)\n");
}

int main(void)
{
//延時(shí)2s
HAL_Delay(2000);
printf("回到main函數(shù)中\(zhòng)n");
//調(diào)用Function函數(shù)
Function();
while(1)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_Delay(500);
}
}

然后編譯后將程序下載到小熊派開(kāi)發(fā)板后,通過(guò)串口調(diào)試助手看到:

至此,我們已經(jīng)完全弄明白RT-Thread是如何實(shí)現(xiàn)在main函數(shù)執(zhí)行之前就把初始化硬件、系統(tǒng)初始化、啟動(dòng)調(diào)度器等工作都完成了的基本原理。

3、案例下載

公眾號(hào)后臺(tái)回復(fù):main擴(kuò)展 即可獲取本節(jié)案例的下載鏈接。

往期精彩

什么?C/C++面試過(guò)不了?因?yàn)槟氵€沒(méi)看過(guò)這個(gè)!

MCU SPI屏也能跑這么炫酷的特效?來(lái),移植起來(lái)秀一秀

推薦三個(gè)我工作中經(jīng)常使用的驅(qū)動(dòng)大全wiki(建議收藏并轉(zhuǎn)發(fā)讓更多人知道!)

會(huì)C/C++就可以開(kāi)發(fā)Linux/Android應(yīng)用程序?替代傳統(tǒng)串口屏的Yoxios了解一下!

覺(jué)得本次分享的文章對(duì)您有幫助,隨手點(diǎn)[在看]并轉(zhuǎn)發(fā)分享,也是對(duì)我的支持。

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉