日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

单片机如何从上电复位执行到main函数?

發(fā)布時(shí)間:2023/11/27 生活经验 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单片机如何从上电复位执行到main函数? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

1、啟動(dòng)文件

2、系統(tǒng)初始化過程

3、全局變量的初始化


從事嵌入式開發(fā)的伙伴可能會(huì)思考過一個(gè)問題,我們一般都是使用芯片廠商提供的驅(qū)動(dòng)庫和初始化文件,直接從main函數(shù)開始寫程序,那么系統(tǒng)上電之后,程序怎么引導(dǎo)進(jìn)main函數(shù)執(zhí)行的呢?還有,系統(tǒng)上電之后RAM的數(shù)據(jù)是隨機(jī)的,那么定義的全局變量的初始值又是怎么實(shí)現(xiàn)的呢?

下面我將帶著這兩個(gè)問題,以Cortex-M架構(gòu)為例,采用IAR EWARM作為編譯工具鏈,從系統(tǒng)上電之后執(zhí)行的第一條代碼開始,梳理系統(tǒng)的啟動(dòng)過程,了解編譯器在此期間所做的工作。其他的工具鏈,如Keil和GCC在系統(tǒng)初始化過程所做的工作也是相似的,但具體的實(shí)現(xiàn)有所差異。

1、啟動(dòng)文件

芯片廠商提供的啟動(dòng)文件,一般是采用匯編語言編寫,少數(shù)用C語言。在啟動(dòng)文件中一般至少存在下面兩個(gè)部分內(nèi)容:

1、向量表

2、默認(rèn)的中斷和異常處理程序

向量表實(shí)際上是一個(gè)數(shù)組,放置在存儲(chǔ)器的零地址,每個(gè)元素存儲(chǔ)的是各個(gè)中斷或異常處理程序的入口地址。以STM32F107芯片基于IAR工具的啟動(dòng)文件為例:

文件的開頭定義了一個(gè)名為__vector_table的全局符號(hào),“DATA”的作用是在代碼段中定義一個(gè)數(shù)據(jù)區(qū),用作向量表。數(shù)據(jù)區(qū)的內(nèi)容是使用DCD指令定義的32位寬度常量,除了第一個(gè)sfe(CSTACK)比較特殊以為,其他的常量都是異常和中斷服務(wù)程序的地址(在編譯時(shí)函數(shù)名會(huì)被替換成函數(shù)的入口地址)。sfe(CSTACK)是IAR匯編器段操作,用于獲取段(section)的結(jié)束地址,在這里意欲何為呢?

實(shí)際上這是獲取堆棧基地址的操作。IAR在鏈接器腳本(*.icf)文件中定義堆棧,實(shí)際是定義了一個(gè)名為“CSTACK”的空閑塊(block),如下圖的腳本命令所示。所謂的塊就是保留一段連續(xù)的地址空間,用來作為堆?;蛘叨?。當(dāng)然,塊也可以是用內(nèi)容的,例如可以用來管理段,但不在今天的討論范圍。

我們知道Cortex-M架構(gòu)的堆棧模型是滿減棧,堆棧從高地址向低地址增長,因此堆棧的基地址是CSTACK的結(jié)束地址。

向量表的第一個(gè)元素是?;愤@是由Cortex-M架構(gòu)定義的。系統(tǒng)上電后硬件自動(dòng)從向量表中獲取,并設(shè)置主堆棧指針MSP,而不是像其他ARM架構(gòu),堆棧指針需要通過軟件來設(shè)置。

向量表中第二個(gè)元素是復(fù)位異常(Reset_Handler)的入口地址。系統(tǒng)上電后,硬件自動(dòng)從__vector_table + 4的位置讀取,并從讀取到的地址開始執(zhí)行。系統(tǒng)上電后CPU執(zhí)行的第一條是Reset_Handler函數(shù)的第一條語句。

上面的THUMB命令表示接下來的代碼采用THUMB模式(Cortex-M只支持Thumb-2指令集);SECTION用于定義一個(gè)段,段名為“.ResetHandler”,段的類型是代碼(CODE);REODER指示用給定的名稱開啟一個(gè)新的段;ROOT指示鏈接器,當(dāng)段內(nèi)的符號(hào)沒有被引用,鏈接器也不可以丟棄這個(gè)段。

PUBWEAK是弱定義,如果用戶在其他位置編寫了中斷處理函數(shù),在連接時(shí)實(shí)際鏈接用戶所編寫的,啟動(dòng)文件中用匯編寫的服務(wù)函數(shù)會(huì)忽略。之所以要在啟動(dòng)文件中以弱定義的方式編寫全部的異常和中斷服務(wù)函數(shù),是為了防止用戶在沒有編寫服務(wù)函數(shù)的情況下開啟并觸發(fā)了中斷,導(dǎo)致系統(tǒng)的不確定。

2、系統(tǒng)初始化過程

在EWARM的工程Options > Debugger > Setup中將“Run to”勾選取消,這樣在進(jìn)入調(diào)試之后就會(huì)停第一條要執(zhí)行的代碼的位置:

進(jìn)入調(diào)試之后會(huì)停在啟動(dòng)文件Reset_Handler函數(shù)第一條匯編指令位置:

此時(shí),通過寄存器觀察窗口查看SP的值為0x20009820。通過鏈接時(shí)生成的map文件,查看CSTACK的地址范圍,0x20009820正好是CSTACK的結(jié)束地址。有了MSP,C代碼就能運(yùn)行了。

SystemInit函數(shù)是芯片廠商根據(jù)ARM的CMSIS標(biāo)準(zhǔn)提供的一個(gè)系統(tǒng)基礎(chǔ)配置函數(shù),配置基礎(chǔ)的時(shí)鐘系統(tǒng)和向量表重定位等。這里的LDR是偽指令,它將SystemInit函數(shù)的地址加載到寄存器R0,實(shí)際上是通過PC偏移尋址來獲取SystemInit的地址。

從上面的圖可以發(fā)現(xiàn)一個(gè)問題,在反匯編窗口可以觀察到SystemInit的地址是0x20000150,但加載到R0寄存器后卻是0x20000151。這是因?yàn)樵谑褂锰D(zhuǎn)指令更新PC時(shí),需要置PC的LSB為1,以表示THUMB模式,由于Cortex-M不支持ARM模式,因此LSB總是1。

執(zhí)行完芯片廠商提供的SystemInit函數(shù)之后,跳轉(zhuǎn)到__iar_program_start,這是IAR編譯器提供的初始化代碼的入口。

__iar_program_start首先會(huì)執(zhí)行兩個(gè)函數(shù):__iar_init_core和__iar_init_vfp,可以完成一些CPU和FPU相關(guān)的初始化操作,在某些ARM架構(gòu)打包好的運(yùn)行時(shí)庫會(huì)有這兩個(gè)函數(shù),用戶也可以重寫這兩個(gè)函數(shù)來自己實(shí)現(xiàn)一些相關(guān)的操作。

之后,跳轉(zhuǎn)到__cmain函數(shù)執(zhí)行。在__cmain中調(diào)用了一個(gè)__low_level_init函數(shù),該函數(shù)專門用于提供給用戶編寫一個(gè)初階的初始化操作,它在全局變量初始化之前執(zhí)行,例如可用在__low_level_init中初始化SDRAM,這樣就可以將全局變量定義到SDRAM中使用。

__low_level_init可以在任意的C文件中編寫,注意它的返回值,如果返回0,后續(xù)就會(huì)跳過變量初始化操作,正常一般都是返回1。

3、全局變量的初始化

此后進(jìn)入到__iar_data_init3函數(shù),在這里會(huì)完成所有具有初始值的全局/靜態(tài)變量的賦值,以及零初始化全局/靜態(tài)變量的清零操作,分別調(diào)用__iar_copy_init3和__iar_zero_init3,將保存在ROM區(qū)由鏈接器生成的變量初始值復(fù)制到變量的地址。注意,新的EWARM版本默認(rèn)變量初始化操作可能會(huì)采用壓縮算法,實(shí)際變量初始化調(diào)用的函數(shù)可能有區(qū)別。

在全局變量未初始化之前,通過watch窗口可以看到,變量的值都是隨機(jī)數(shù)。

在__iar_data_init3執(zhí)行完成后,全部變量的初值賦值已經(jīng)完成。

在__cmain函數(shù)的最后,跳轉(zhuǎn)到用戶的main函數(shù),最終開始用戶的代碼執(zhí)行。

了解了編譯器所提供的初始化過程和處理器架構(gòu),我們可以根據(jù)自己的需求定制系統(tǒng)的初始化。

例如,在進(jìn)入__iar_program_start之前,就可以執(zhí)行必要的硬件初始化操作,可以用匯編寫,也可以用C寫。還可以手動(dòng)控制變量的初始化操作,自己實(shí)現(xiàn)變量的初始化。甚至,完全不采用IAR編譯器提供的初始化操作,自己從復(fù)位序列引導(dǎo)至main函數(shù)那也是可以的。

總結(jié)

以上是生活随笔為你收集整理的单片机如何从上电复位执行到main函数?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 3d动漫精品啪啪一区二区下载 | 美女诱惑av | 亚洲天堂2014 | 中文字幕一区在线播放 | 操夜夜操 | 亚洲熟妇丰满大屁股熟妇 | 精品久久久久久一区二区里番 | av网址导航 | 成人一区二区在线 | 神马午夜麻豆 | 你懂的在线视频网站 | 亚洲交性网| 福利视频免费看 | 91新网站 | 36d大奶 | 亚洲黄色第一页 | 亚洲小视频在线 | 三度诱惑免费版电影在线观看 | 日韩免费视频 | 天天干天天做天天操 | 免费观看一级视频 | 激情视频免费观看 | 国产啊v在线观看 | 91麻豆精品国产91久久久无需广告 | 色爽视频| 制服一区| 久色91 | 天堂素人约啪 | 久热网 | 午夜影视大全 | 影音先锋人妻啪啪av资源网站 | 国产无遮挡又黄又爽免费网站 | 日本免费一区二区三区视频 | 欧美在线视频a | 手机在线看片日韩 | 91在线亚洲 | 久久久高清视频 | 麻豆av一区二区三区久久 | 99re超碰| 中文字幕亚洲精品在线观看 | 日本女人毛茸茸 | 久久精品一区二区国产 | 日韩欧美一 | 日韩在线无 | 日本欧美韩国国产精品 | 极品尤物在线观看 | 欧美日韩一区二区不卡 | 久久久久久久99 | 欧美亚洲色图视频 | 色小说在线观看 | 亚洲男人第一天堂 | 偷拍亚洲另类 | 午夜av网站 | 美女国产视频 | 日本成人一区二区三区 | 国产又粗又猛又黄又爽 | 91av在线免费 | 一区二区中文在线 | 亚洲视频在线免费 | 日韩欧美亚洲天堂 | 国产丝袜视频 | 99av在线 | 开心黄色网 | 精品视频一区二区 | 欧美一区亚洲一区 | 91免费看国产 | 在线观看视频www | 羞羞的视频网站 | 毛片在线免费观看网址 | 久久成人乱码欧美精品一区二区 | 97av在线播放 | 永久免费精品影视网站 | 日本激情视频在线 | 久久成人综合网 | 国产-第1页-浮力影院 | 丝袜+亚洲+另类+欧美+变态 | 久久久国产精华液 | 日日狠狠 | 欧美影视一区二区三区 | 波多野结衣视频一区二区 | 亚洲日本网站 | 国产嫩草av | 亚洲伊人精品 | 91操操| 99国产在线视频 | 天堂网av中文字幕 | 国产人成无码视频在线观看 | 免费无毒av | 99久久影院 | 国产精品入口66mio | 黄瓜视频污在线观看 | 日韩欧美亚洲在线 | 女优中文字幕 | 欧美不卡一区 | 成人国产片女人爽到高潮 | 色妻av| 香蕉视频黄污 | 97精品在线视频 | 国语一区二区 |