久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6777|回復: 1
收起左側

通過LST和HEX文件分析CortexM3的復位啟動過程

[復制鏈接]
ID:104497 發表于 2016-4-27 21:21 | 顯示全部樓層 |閱讀模式
      從匯編編程的角度上看,STM32從復位到主程序的過程要比MCS稍顯復雜,一個比較主要的原因是CortexM3用很多偽指令來描述啟動過程,會讓我這樣的菜鳥感到云遮霧罩。
      說到底,CortexM3也好,MCS51也罷,啟動過程都是大同小異的,無非是PC指針初始化,執行完用戶的復位程序之后取出主程序地址,跳到主程序上。
      對于MCS51來說,這個過程非常好理解:
                    ORG        0000H
                    LJMP        Reset
                    ORG        0003H
                    ;配置各個中斷服務程序的入口
                      ………………
                    ORG        0100H
Reset:
                     ………………
                   ;初始化及主程序段
     51單片機復位,PC=0000H指向首地址,取指令和操作數,轉0100H執行初始化及主程序,先定義堆棧指針SP,然后再干別的。
      這個過程說明MCS51程序存儲器是這樣分區的:
復位入口        0000H-0002H。放置越過中斷向量程序段,直達主程序段的跳轉指令。
中斷向量        0003H-00BBH。放置中斷服務程序向量。有些增強型51單片機的中斷向量已經用到了00BBH。
復位程序        從最后一個中斷向量操作數之后的地址開始。通常是先配置堆棧指針SP。
主程序段        主程序代碼區。
      但對于CortexM3來說,它的復位過程有點兒特殊:如果BOOT0配置成從FLASH區啟動,那首先是PC=0x08000000,先把這個地址開始的4個字節數值賦值給主棧指針MSP,然后再把0x08000004開始的4個字節賦值給PC,轉到復位程序。
      實際上,復位時PC=0x00000000,但BOOT0=0時,0x00000000會被映射到0x08000000上,所以說PC是從0x08000000開始也是可以的。
      CortexM3程序存儲器分區是如下:
MSP賦值        0x08000000—0x08000003。當PC指向這個數據塊時,4字節數自動賦值給MSP。
復位入口        0x08000004—0x08000007。4個字節,放置復位程序的入口地址。
中斷向量        在0x08000007之后,每個向量的入口地址可以定義。每個中斷向量地址可以浮動。
復位程序        從最后一個中斷向量操作數之后的地址開始。
主程序段        主程序代碼區。
      歸結起來,兩者跳轉的方式有所不同,MCS51是通過入口放置指令,而CortexM3則是通過入口處放置地址來實現跳轉。
      為了深入探究一下CortexM3的復位機制,我編一個簡單的程序,力圖通過HEX和LST文件理清脈絡。
環境如下:
IDE:Keil 4.12
硬件:STM32F103VCT6,BOOT0=0
程序:匯編語言

LST程序如下:
(1)        初始化程序Initialization.LST
00000000 20005000    MSP_Top  EQU  0x20005000
00000000                                          THUMB
00000000                                          AREA     Reset, Data, ReadOnly
00000000                                          EXPORT   __Vectors
00000000                                          EXPORT   __Vectors_End
00000000                                          EXPORT   __Vectors_Size
00000000                      __Vectors
00000000 20005000                         DCD     MSP_Top
00000004 00000000                         DCD     Reset_Handler
00000008 00 00 00
               00 00 00
               00 00                                  SPACE            0x8
00000010                     __Vectors_End
00000010 00000010                         __Vectors_Size      EQU   __Vectors_End - __Vectors
00000010                                         AREA     |.text|, Code, Readonly
00000000                     Reset_Handler        PROC
00000000                                         EXPORT   Reset_Handler           [WEAK]
00000000                                         IMPORT   Main
00000000 4800                                LDR      R0,=Main
00000002 4700                                BX       R0
00000004                                         ENDP
00000004                                         ALIGN
00000004                                         END
      主棧配置到SRAM區0x20005000,暫時未定義主棧大小。暫時未定義其它中斷向量。
(2)        主程序Main.LST
                                     INCLUDE  Stm32F103REG.h
00000000                     Main     PROC
00000000                                        EXPORT    Main
00000000 4801                               LDR       R0,=RCC_CR
00000002 6801                               LDR       R1,[R0]
00000004 E7FE                               B         Main
00000006                                        ENDP
00000006                                        END
      Stm32F103REG.h是自行編制的寄存器定義程序。
上述程序編譯之后打開工程HEX文件和兩個程序段的LST文件并整理一下,刪除一些不重要的數據,結果如下:
(3)工程HEX文件
:020000040800F2
:100000000050002011000008000000000000000067
:10001000004800471900000801480168FCE700009B
:04002000001002408A
:0400000508000019D6
:00000001FF
看起來有些亂七八糟,整理一下。

數據長度    地址偏移   數據類型                    數據塊                                                                 校驗和
1byte          2bytes      1byte                          n bytes                                                                1byte
02              00 00         04                08 00                                                                                 F2
10                  00 00            00                00 50 00 20 11 00 00 08 00 00 00 00 00 00 00 00             67
10                  00 10            00                00 48 00 47 19 00 00 08 01 48 01 68 FC E7 00 00             9B
04                  00 20            00                00 10 02 40                                                                          8A
04                  00 00            05                08 00 00 19                                                                          D6
00                  00 00            01                                                                                                          FF

     數據長度好理解,是說本行中數據塊有幾個字節。
     地址偏移是指當前行第一個數據相對于基址的位置。
     查了一下資料,數據類型可分為5種類型:
00=這一行的數據塊里全是數據;
01=HEX文件結束符,所在行數據塊為空;
02=數據塊里的數據是擴展段地址;
03=數據塊里的數據是段地址;
04=數據塊里的數據是線性地址高位;
05=數據塊里的數據是線性地址。
      看起來,數據類型可分為三大類:數據類(00)、地址類(02~05)和編譯標識類(01)

      第一行數據類型為04,說明后面的0800和地址偏移0000構成了一個基址0x08000000,這是STM32F103 FLASH區的首址,后序行的數據存儲地址都可以根據這個基址加偏移量計算出來。
      第二行數據類型為00,偏移量為0000,也就是說,數據塊的第一個00被存放在地址0x08000000中,這就是單片機復位時從FLASH區啟動的首址。
      按照前面的說明,首址之后的4個字節應當是準備賦給MSP的值,也就是程序指定的0x20005000,可現在卻是00 50 00 20,看了半天恍然大悟,突然想起CortexM3數據格式是所謂的小端模式Little-endian,所以這4個字節的32位數據得按字節倒過來讀成20 00 50 00。但當數據類型為地址類時,數據塊數據就可以正著讀了,哈哈。
      00 50 00 20之后又是一個地址,倒過來是08 00 00 11,這就是復位程序入口地址。其后的數據是8個字節的00,這就是SPACE 0x8的功勞了。 按照流程,復位地址賦值給PC之后會從地址0x08000011開始運行,0x08000011單元的數據是48,對照一下Initialization.LST,對應的是它的第一條可執行語句'LDR  R0,=Main',只不過這條指令的代碼48 00也存儲成了小端模式。
      以此類推,逐一閱讀后面的數據,過程就出來了,Main的段地址是第三行的那個大紅圈里的數據0x08000019,從它以后就是Main的指令代碼了。但這里有一個問題,Main.LST表明‘B  Main’指令的代碼是E7 FE,可HEX里卻是E7 FC,這又是怎么回事兒呢?不知道哪位前輩能告訴我。
     還有一個問題:從0x08000020開始的數據明顯是RCC_CR的地址,它怎么會出現在這兒呢?

      用匯編寫STM32程序是苦中有樂,有人說我這是自找麻煩,但我不這么認為。與使用固件庫編程相比,無論是面向寄存器編程還是直接用匯編,編程難度都要大很多,但是,程序透明度也比前者大得多,絕對不會出現神龍見首不見尾的感覺,尤其是對于我這種不太會C語言的硬件工程師就更是如此。


評分

參與人數 2黑幣 +60 收起 理由
51黑ele + 10 很給力!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:115111 發表于 2016-4-27 23:05 | 顯示全部樓層
好文章啊結合51單片機談stm32單片機的啟動過程,讓我們這些51的學習者也能進入stm32的世界,期待樓主的更多文章
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产一级免费视频 | 四虎8848精品成人免费网站 | 欧美一区二区三区成人 | 在线黄色av | 深夜福利视频在线观看 | 夜夜嗨av一区二区三区网页 | 亚洲视频免费观看 | 手机看片1024日韩 | 黄色成人在线视频 | 九九国产视频 | 国产区免费 | 国产免费一区 | 日韩中文字幕视频 | 日韩一区二区在线视频 | 免费av观看 | 日本免费视频 | 国产精品高潮呻吟久久 | 91片黄在线观看 | 亚洲天堂中文字幕 | 欧美视频免费 | 亚洲欧美成人 | 成人黄色录像 | 日韩亚洲天堂 | 久久都是精品 | 日本黄色录像 | 99热综合 | 日韩精品无 | 国产精品国产三级国产专区52 | 黄色激情视频在线观看 | 亚洲高清视频在线 | 成人在线观看免费爱爱 | 欧美日韩国 | 亚洲午夜视频 | 欧美日韩一区二区三区视频 | 久久久久国产精品夜夜夜夜夜 | 亚洲福利视频一区 | 在线成人免费视频 | 久久久久久久91 | 国产精品视频一区二区三区 | 男男成人高潮片免费网站 | 狠狠干狠狠插 |