豹哥嵌入式講堂:ARM Cortex-M開發之文件詳解(8)- 鏡像文件(.bin/.hex/.s19)

来源:https://www.cnblogs.com/henjay724/archive/2018/01/26/8361693.html
-Advertisement-
Play Games

今天豹哥主要講的是工程開發最終的output文件,即image文件。image文件也叫鏡像文件,這個文件主要包含的是只有晶元能夠解釋執行的二進位機器碼數據。 ...



  大家好,我是豹哥,獵豹的豹,犀利哥的哥。今天豹哥給大家講的是嵌入式開發里的image文件(.bin, .hex, .s19)

  今天這節課是豹哥《ARM Cortex-M開發之文件詳解》主題系列的最後一節課(突然有點不捨,要告別的感覺,咳咳,讓豹哥整理下情緒先)。今天豹哥主要講的是工程開發最終的output文件,即image文件。image文件也叫鏡像文件,這個文件主要包含的是只有晶元能夠解釋執行的二進位機器碼數據,這些數據其實在前面介紹的relocatable、list、executable文件中出現過,在那些文件里我們還可以根據其他輔助信息來分析機器碼數據的實際意義,但在image文件里,我們已經完全無法看懂這些機器碼了。所以image文件主要是用來做大規模量產的。既要做大規模量產,由於各晶元廠家制定的標準不一,所以實際上image文件有很多種格式,今天我們主要講的是其中最具有代表性也應用最廣泛的3種image文件格式。

一、通用鏡像文件bin

  第一種格式叫binary,以.bin為文件尾碼,這種格式是一種通用image格式,其完全是機器碼裸數據的集合,沒有其他任何多餘信息,這個數據可以直接被編程器/下載器下載到晶元內部非易失性存儲器里,不需要任何額外的數據轉換,所見即所得。由於是純二進位編碼的文件,所以普通text編輯器無法正確查看這個文件,需要用專用的十六進位編輯器(比如Hex Editor HxD)才能正常打開。以本系列創建的demo工程的demo.bin文件為例,用HxD打開可見如下數據(僅截取前後部分顯示,demo.bin共6780 bytes)。

offset(h)
00000000: 00 20 00 10 41 00 00 00 DB 18 00 00 CB 19 00 00
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 07 1A 00 00
00000030: 00 00 00 00 00 00 00 00 1D 1A 00 00 1F 1A 00 00
00000040: 72 B6 0E 48 0E 49 88 60 00 22 00 23 00 24 00 25
...
00001A30: 01 23 00 24 13 E0 0A 68 09 1D 1A 42 02 D0 4D 46
00001A40: 6D 1E 52 19 14 60 12 1D 00 1F 04 28 FA D2 15 00
00001A50: 86 07 01 D5 14 80 AD 1C 18 40 00 D0 2C 70 08 68
00001A60: 09 1D 00 28 E7 D1 08 00 70 BC 70 47 C1 FF FF FF
00001A70: 08 02 00 00 14 20 00 10 00 00 00 00 -- -- -- --

  有細心的朋友可能會疑問,打開bin文件看數據都是按連續地址排列的,如果在應用設計中,我們在linker文件里給各個段分配的地址不是連續的,這在bin文件里是怎麼處理的?為瞭解決這個問題,bin文件會在非有效地址區域插入無效位元組以保證有效地址處都是正確的數據,這在IDE里或相關轉換工具里都會有相應option,可以讓用戶設置填充位元組pattern(比如0x00,0xFF等)。
  好,現在讓我們嘗試分析一下這個bin文件,我們都知道ARM Cortex-M架構里,image bin文件前8個位元組應該是初始SP和PC的值,從前面map文件里我們知道SP=0x10002000,PC=0x00000041,來檢查一下bin文件里是不是這樣,前4個位元組分別是 00 20 00 10、看起來好像跟0x10002000數據是吻合的,但是這個數據排列方式看起來好像有點彆扭,怎麼回事?嵌入式老司機這時應該要莞爾一笑,是的,ARM Coretx-M預設採用的Little-Endian(小端)模式,即低位位元組排放在記憶體的低地址端,高位位元組排放在記憶體的高地址端。數據查看地址顯示都是從低到高的(從左到右),所以SP的最低位元組應該顯示在最左邊(最低地址),而不是像查看0x10002000那樣最低位元組在最右邊,這跟人的閱讀習慣是有點不吻合。
  PS: 既有小端模式,那麼與其對應的也有大端模式(Big-Endian)-高位位元組排放在記憶體的低地址端,低位位元組排放在記憶體的高地址端。註意大端小端僅是針對以32bit為單元的數據排列方式差異,對於n個32bit數據,其都是統一的排列。

offset(h)
// 小端
00000000: 00 20 00 10 41 00 00 00 
// 大端
00000000: 10 00 20 00 00 00 00 41 

  從上面對bin文件的分析,我們知道bin文件是不含地址信息的,也就是說bin文件數據應該被放在什麼地址處,我們僅從bin文件本身是無法得知的。所以在使用編程器/下載器下載bin文件時,用戶必須指定起始下載地址。由於bin文件的這種局限性,下麵兩種帶地址信息的image格式應運而生。

二、Intel鏡像文件標準hex

  第二種格式叫Intel hex,以.hex為文件尾碼,這種格式是Intel公司推行的一種image格式標準,其不僅含有機器碼裸數據還含有地址信息等額外信息,與bin文件不同的是,hex文件可以直接通用普通text編輯器打開查看,hex文件採用的ASCII編碼,hex文件內的機器碼數據不可以直接被下載進晶元內部,需要在幀數據解析的過程中進行轉換。
  由於hex文件並不是純機器碼文件,還含有其他額外信息,那麼hex文件就需要按某種約定格式進行數據組織,數據組織方式叫幀格式,hex文件是由n幀數據組成的。

2.1 hex幀格式

  要想解析hex文件,必須要先瞭解其幀格式,hex每幀都由下表列出的6部分組成:

幀段名 Start code Byte count Address Record type Data Checksum
幀段內容 固定前導碼':',十六進位0x3A 機器碼數據長度 機器碼數據存儲地址 幀類型"00"-"05",有6種幀 機器碼數據 校驗和
幀段長度(bytes) 1 1*2 2*2 1*2 (0-255)*2 1*2

  編程器/下載器在解析hex文件時,先找到幀前導碼,然後找到幀類型,如果該幀為數據幀,再根據幀機器碼長度,將該幀機器碼數據全部讀出放到緩存里,在做完幀和校驗後,如果沒有錯誤,最後根據幀機器碼存儲地址將幀機器碼數據下載到晶元指定存儲器地址處,至此一幀處理結束,進入下一幀,直到所有幀全部處理完。需要註意的是由於hex文件是ASCII編碼,所以相比bin文件長度至少大2倍以上,demo.hex文件大小有19,106 bytes,後面我們會截取部分hex文件進行分析。
  關於checksum的計算方法,其是將Byte count、Address、Record type、Data四個段內所有byte全部相加得到sum,截取sum的LSB(最低位元組),再對該LSB取其補碼(預設該LSB為負數的低8bit數據位(註意8bit中沒有符號位),其反碼為原碼各bit取反,其補碼為反碼+1)得到checksum。比如LSB是0xA5,其反碼為0x5A,補碼為0x5B,則checksum為0x5B。

2.2 hex幀類型

  前面說到一共有6種類型的幀,其中最重要也是數量最多的幀是數據幀,除了數據幀之外還有其他5種幀,下麵來統一介紹:

幀類型碼 幀類型 幀描述 幀舉例
"00" 數據幀 以16bit地址描述開始的最大255個位元組有效機器碼的數據幀 含11bytes機器碼從0x0010地址處開始的數據幀:0B0010006164647265737320676170A7
"01" 文件結尾幀 用於表明hex文件的結尾 統一的文件結尾幀:00000001FF
"02" 拓展段地址幀 多用於80x86架構晶元,ARM Cortex-M架構不用 :020000021200EA
"03" 起始段地址幀 多用於80x86架構晶元,ARM Cortex-M架構不用 :0400000300003800C1
"04" 拓展線性地址幀 用於32bit地址存儲空間晶元,與數據幀配合使用,指引編程器將數據下載到正確地址 標明拓展地址為0xFFFF的幀:02000004FFFFFC
"05" 起始程式地址(PC)幀 指示調試器,程式初始PC地址,方便線上調試 標明起始PC為0x000000CD的幀:04000005000000CD2A

2.3 解析hex文件

  在瞭解hex文件幀數據格式之後,讓我們開始嘗試解析demo.hex文件(僅截取前後部分,與前面截取的bin文件內容對應著一起分析)

:100000000020001041000000DB180000CB190000A8
:1000100000000000000000000000000000000000E0
:10002000000000000000000000000000071A0000AF
:1000300000000000000000001D1A00001F1A000050
:1000400072B60E480E498860002200230024002565
....
:101A30000123002413E00A68091D1A4202D04D4612
:101A40006D1E52191460121D001F0428FAD21500D1
:101A5000860701D51480AD1C184000D02C70086892
:101A6000091D0028E7D1080070BC7047C1FFFFFFC7
:0C1A70000802000014200010000000001C
:0400000500000041B6
:00000001FF

  hex文件前5幀均為數據幀,每幀包含16bytes機器碼數據,幀數據地址分別為0x0000, 0x0010, 0x0020, 0x0030, 0x0040,可見幀數據是連續的,並且5幀機器碼數據共80bytes與bin文件前80bytes是一致的。
  再來看最後7幀數據里的前5個數據幀,除最後一幀數據只包含12bytes數據外,其餘數據幀均含有16bytes數據,5幀數據一共76bytes,幀數據地址從0x1A30 - 0x1A70。顯然這與bin文件最後76bytes也是吻合的。
  倒數第二幀是起始程式地址幀,其標明的程式起始PC是0x00000041,這與bin文件里第二個32bit數據(起始PC)是一致的。
  倒數第一幀顯然是標準文件結尾幀。

三、Motorola鏡像文件標準S-Record

  第三種格式叫Motorola S-Record,以.s19或.srec為文件尾碼,這種格式是Motorola公司推行的一種image格式標準,其與Intel hex文件比較類似,都是ASCII編碼的文件,可以通過普通text編輯器打開查看,其也由幀數據組成,只是幀格式與Intel hex有差別,還是按照介紹Intel hex文件那樣先來看S-Record文件的幀格式。

3.1 S-Record幀格式

  S-Record每幀由下表列出的6部分組成:

幀段名 Start code Record type Byte count Address Data Checksum
幀段內容 固定前導碼'S',十六進位0x53 幀類型'0'-'9',有10種幀 幀數據長度(包含後續段地址、數據、校驗和) 機器碼數據存儲地址 機器碼數據 校驗和
幀段長度(bytes) 1 1 1*2 (2-4)*2 (0-255)*2 1*2

  編程器/下載器在解析S-Record文件時,先找到幀前導碼,然後找到幀類型,如果該幀為數據幀,再根據幀長度,將該幀機器碼數據全部讀出放到緩存里,在做完幀和校驗後,如果沒有錯誤,最後根據幀機器碼存儲地址將幀機器碼數據下載到晶元指定存儲器地址處,至此一幀處理結束,進入下一幀,直到所有幀全部處理完。
  關於checksum的計算方法,其是將Byte count、Address、Data三個段內所有byte全部相加得到sum,截取sum的LSB(最低位元組),再對該LSB取其反碼(預設該LSB為負數的低8bit數據位(註意8bit中沒有符號位),其反碼為原碼各bit取反)得到checksum。比如LSB是0xA5,其反碼為0x5A,則checksum為0x5A。

3.2 S-Record幀類型

  前面說到一共有10種類型的幀,其中最重要也是數量最多的幀是數據幀,數據幀按地址長度可分為16bit、24bit、32bit地址長度數據幀,除了數據幀,還有其他種類幀,下麵來統一介紹:

幀類型碼 幀類型 幀描述 幀舉例
'0' 文件起始幀 用於表明S-Record文件的開始 標明文件名為HDR的文件起始幀S00600004844521B
'1' 數據幀x16地址 以16bit地址描述開始的最大255個位元組有效機器碼的數據幀 含14bytes機器碼從0x0038地址處開始的數據幀S111003848656C6C6F20776F726C642E0A0042
'2' 數據幀x24地址 以24bit地址描述開始的最大255個位元組有效機器碼的數據幀 含4bytes機器碼從0x100000地址處開始的數據幀S2081000000400FA05E5
'3' 數據幀x32地址 以32bit地址描述開始的最大255個位元組有效機器碼的數據幀 含4bytes機器碼從0x13000160地址處開始的數據幀S309130001600400FA057F
'4' N/A 未定義 N/A
'5' 數據幀總數幀x16 用16bit count記錄數據幀總幀數的總數幀 標明總數據幀為4幀的總數幀S5030004F8
'6' 數據幀總數幀x24 用24bit count記錄數據幀總幀數的總數幀 標明總數據幀為80000幀的總數幀S604080000F3
'7' 起始程式地址(PC)幀x32 含32bit起始PC的幀 標明起始PC為0x10000000的幀S70510000000EA
'8' 起始程式地址(PC)幀x24 含24bit起始PC的幀 標明起始PC為0x100000的幀S804100000EB
'9' 起始程式地址(PC)幀x16 含16bit起始PC的幀 標明起始PC為0x0000的幀S9030000FC

3.3 解析S-Record文件

  在瞭解S-Record文件幀數據格式之後,讓我們開始嘗試解析demo.s19文件(僅截取前後部分,與前面截取的bin文件內容對應著一起分析)

S00B000064656D6F2E73313944
S11300000020001041000000DB180000CB190000A4
S113001000000000000000000000000000000000DC
S1130020000000000000000000000000071A0000AB
S113003000000000000000001D1A00001F1A00004C
S113004072B60E480E498860002200230024002561
....
S1131A300123002413E00A68091D1A4202D04D460E
S1131A406D1E52191460121D001F0428FAD21500CD
S1131A50860701D51480AD1C184000D02C7008688E
S1131A60091D0028E7D1080070BC7047C1FFFFFFC3
S10F1A7008020000142000100000000018
S9030041BB

  S-Record文件第一幀是文件起始幀,幀數據64656D6F2E733139對應ASCII為demo.s19,即該文件名。
  第2-6幀均為16bit地址的數據幀,每幀包含16bytes機器碼數據,幀數據地址分別為0x0000, 0x0010, 0x0020, 0x0030, 0x0040,可見幀數據是連續的,並且5幀機器碼數據共80bytes與bin文件前80bytes是一致的。
  再來看最後6幀數據里的前5個數據幀,除最後一幀數據只包含12bytes數據外,其餘數據幀均含有16bytes數據,5幀數據一共76bytes,幀數據地址從0x1A30 - 0x1A70。顯然這與bin文件最後76bytes也是吻合的。
  倒數第一幀是起始程式地址幀,其標明的程式起始PC是0x0041,這與bin文件里第二個32bit數據(起始PC)是一致的。

番外一、一些image文件輔助小工具

SRecordizer:專用S19文件編輯器,可根據修改自動更新checksum,詳見網頁https://srecordizer.codeplex.com/
SRecord項目:各種image文件格式互轉的小工具合集,詳見網頁http://srecord.sourceforge.net/

  至此,嵌入式開發里的image文件(.bin, .hex, .s19)文件豹哥便介紹完畢了,掌聲在哪裡~~~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 【先上一張效果圖】: 一、原理: 其實原理很簡單: 1.手機投屏到電腦; 2.截取投屏畫面的題目部分,進行識別,得到題目和三個答案; 3.將答案按照一定的演算法,進行搜索,得出推薦答案; 4.添加了一些其他輔助功能,比如:瀏覽器搜索結果展示、關鍵字高亮、瀏覽器可點擊等; 二、二營長,把我的義大利... ...
  • 最近花時間弄了一個關於fireasy使用的demo,已放到 github 上供大家研究,https://github.com/faib920/zero 該 demo 演示瞭如何使用 fireasy 創建一個後臺的管理系統。解決方案包含 asp.net mvc5 和 asp.net core 兩個示例 ...
  • 演示產品源碼下載地址:http://www.jinhusns.com ...
  • 演示產品源碼下載地址:http://www.jinhusns.com ...
  • 1. 前言 在 "如何使用Fluent Design System" 這篇文章里已經簡單介紹過Reveal的用法,這篇再詳細介紹其它內容。 自Windows 8 放棄Aero後,群眾對毛玻璃回歸的呼聲一致都很大。Fluent Design System帶來了新的透明背景Acrylic,提供更好的性能 ...
  • 為了幫助大家更深刻地認識Dora.Interception,並更好地將它應用到你的項目中,我們通過如下幾個簡單的實例來演示幾個常見的AOP應用在Dora.Interception下的實現。對於下麵演示的實例,它們僅僅是具有指導性質的應用,所以我會儘可能地簡化,如果大家需要將相應的應用場景移植到具體的... ...
  • 本例子主要是使用由中央氣象局網站(http://www.nmc.gov.cn)提供的JSON API,其實現思路如下: 1、訪問獲取省份(包含直轄市、自治區等,以下簡稱省份)的網址(http://www.nmc.gov.cn/f/rest/province),返回對應的省份名稱(name)、代碼(c ...
  • "上一篇文章" 介紹了S3c2440的中斷體繫結構,今天我們來分析一下GNU uC/OS II在S3c2440上中斷的實現。 首先找到IRQ的中斷的向量,位於 2440init.S : OK ,我們通過名字找到了這個函數: ~~~~ OS_CPU_IRQ_ISR: STMFD SP!, {R1 R3 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...