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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6630|回復: 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 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美激情国产精品 | 欧美激情视频一区二区三区在线播放 | 97av在线| 亚洲97 | 国产精品福利网 | 国产成人精品999在线观看 | 每日更新av | 久久av网 | 亚州毛片 | 国产一区二区三区精品久久久 | 免费观看av网站 | 欧美日韩中文在线观看 | 亚洲精品视频一区二区三区 | 亚洲性视频网站 | 欧美一级片在线观看 | 日韩一区二区av | 久久99精品久久久久久噜噜 | 黄片毛片在线观看 | 久久精品国产精品青草 | 中文字幕成人av | 99在线国产 | 亚洲韩国精品 | 91视频在线 | 亚洲精品久久久久中文字幕二区 | 国产精品视频一区二区三区不卡 | 久久久91精品国产一区二区三区 | 亚洲三级av | 精品一区二区三区在线播放 | 狠狠操网站 | 亚洲三区在线观看 | 日韩精品在线一区二区 | 国产亚洲精品美女久久久久久久久久 | 亚洲综合二区 | 隔壁老王国产在线精品 | 狠狠草视频 | 日本天堂视频在线观看 | 日本黄视频在线观看 | 国产色在线 | 亚洲高清在线免费观看 | 国产日韩欧美中文字幕 | 国产丝袜一区二区三区免费视频 |