乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      ARM Cortex-M底層技術(十三)手把手教你寫分散加載

       SocFans 2020-11-18

      ARM Cortex-M底層技術(十三)手把手教你寫分散加載

          還記得之前教大家寫的啟動代碼嗎?木看過滴,出門左轉,第四篇【編寫自己的啟動代碼】,當然僅僅能編寫自己的啟動代碼怎么夠,說了辣么多分散加載的東東,是時候檢驗一下我們的水平了,合上書,來出題考試了~【自己編寫分散加載】。

          來司機們,將裝B進行到底~

                         

      首先,看看我們之前第四篇文章里面的簡易版分散加載

           如下,之前按著沒講,前面羅里吧嗦的扯了辣么多分散加載,大家現(xiàn)在再回頭看下這個分散加載,估計都看的明白了吧~

      load_rom 0x00000000 0x00080000{vector_rom 0x00000000 0x400{*( vector_table, +first)}execute_rom 0x400 FIXED 0x0007FC00{*( InRoot$$Sections ).any( +ro )}execute_data 0x20000000 0x00010000   {.any ( +rw +zi )}ARM_LIB_HEAP  +0 empty 0x400 {}ARM_LIB_STACK 0x20020000  empty -400 {}
      }

          這里還是簡單扯幾點:

      • 沒有使用預處理器,比較Low逼;

      • 就一個加載域、兩個RO運行域(一個項鏈表運行域,一個根域)、一個RW+ZI運行域以及堆+棧的分配;

      • 第三,參考以上兩點~~~~

      深入理解“FIXED”關鍵字

          但是其實這里還是有一些技能點的~比如:根域的FIXED屬性,你若把這個FIXED屬性去掉,試試會發(fā)生什么????            沒錯,鏈接器罷工了,16個錯,看一下,主要是加載域和運行域的地址不匹配導致的錯誤;

              原因是這樣的:

      1. 任何MCU的分散加載必須有一個根區(qū),這點我們在之前講過;

      2. 根區(qū)是指加載域和運行域相同的地址的區(qū)(因為根區(qū)里面要放置C Library&分散加載相關代碼,而分散加載本身不能被分散加載,所以根區(qū)的加載域與運行域必須相同);

      3. 程序的入口地址必須在根區(qū)中,因為程序的入口顯然不能被分散加載,所以必須在根區(qū)中;

      4. 如果運行域基址與加載域基址相同則默認可以看做根區(qū)(這點很好理解,參考第二點,根區(qū)就是運行域與加載域相同的區(qū));

      5. 加載域后續(xù)的執(zhí)行域指定“+0”偏移,則這些執(zhí)行域默認都為根區(qū)(因為地址上是連續(xù)的,基址又與加載域基址相同);

      6. 如果基址不相同,則需要使用FIXED關鍵字指定根區(qū);

      7. FIXED關鍵字只能用于指定執(zhí)行域,作用是確保執(zhí)行域與加載域地址相同。

          可能說了這么多還是比較費解,下面我們做一些實驗來驗證以上的羅里吧嗦看不懂的廢話,做一下實驗就都懂了:

      實驗一:

          把所有不能被分散加載的代碼內容放到與加載域地址相同的執(zhí)行域里面去,如下:

      1. load_rom 0x00000000 0x00080000
      2. {
      3. vector_rom 0x00000000 0x2000
      4. {
      5. *( vector_table, +first)
      6. *( InRoot$$Sections )
      7. }
      8. execute_rom 0x2000 0x0007D000
      9. {
      10. .any( +ro )
      11. }
      12. execute_data 0x20000000 0x00010000
      13. {
      14. .any ( +rw +zi )
      15. }
      16. ARM_LIB_HEAP +0 empty 0x400 {}
      17. ARM_LIB_STACK 0x20020000 empty -400 {}
      18. }
      • vector_rom顯然是起始地址與加載域相同的執(zhí)行域,默認的根區(qū);

      • 不能被分散加載的有:分散加載本身、部分C Library代碼(注意不是全部,具體是哪些不行小編我也沒研究辣么深入)、程序入口等;

      • 把包含程序入口的Vector_table以及包含分散加載的InRoot$$Sections標號放人與加載域地址相同的執(zhí)行域中,把不能被分散加載的部分與可以被分散加載的部分分開;

      編譯&鏈接,OK,有興趣的可以自己試一下。

      實驗二:

      看如下分散加載,先說結果,也可以完全正常的編譯&鏈接運行的,至于為什么,前面寫過的:

      1. load_rom 0x00000000 0x00080000
      2. {
      3. vector_rom 0x00000000 0x400
      4. {
      5. *( vector_table, +first)
      6. }
      7. execute_rom +0
      8. {
      9. *( InRoot$$Sections )
      10. .any( +ro )
      11. }
      12. execute_data 0x20000000 0x00010000
      13. {
      14. .any ( +rw +zi )
      15. }
      16. ARM_LIB_HEAP +0 empty 0x400 {}
      17. ARM_LIB_STACK 0x20020000 empty -400 {}
      18. }

      當然還有最開始的直接加FIXED關鍵字的版本也是OK的。

      然后我們來搞一個可以裝逼版本的分散加載:

          說是裝逼其實也很簡單,就是把預處理器用起來,在分散加載文件的頂格寫下如下語句:

          #! armcc -E

          調用預處理器,然后開始使用預處理器耍流氓:

          把之前直接賦值的地址數(shù)據替代掉,如:

      #define m_interrupts_start             0x00000000#define m_interrupts_size              0x00000400

          然后分散加載就變成以下這個樣子:

      1. #! armcc -E
      2. #if (defined(__ram_vector_table__))
      3. #define __ram_vector_table_size__ 0x00000400
      4. #else
      5. #define __ram_vector_table_size__ 0x00000000
      6. #endif
      7. #define m_interrupts_start 0x00000000
      8. #define m_interrupts_size 0x00000400
      9. #define m_text_start 0x00000400
      10. #define m_text_size 0x0007FC00
      11. #define m_interrupts_ram_start 0x20000000
      12. #define m_interrupts_ram_size __ram_vector_table_size__
      13. #define m_data_start (m_interrupts_ram_start + m_interrupts_ram_size)
      14. #define m_data_size (0x00028000 - m_interrupts_ram_size)
      15. #define m_usb_sram_start 0x40100000
      16. #define m_usb_sram_size 0x00002000
      17. /* USB BDT size */
      18. #define usb_bdt_size 0x0
      19. /* Sizes */
      20. #if (defined(__stack_size__))
      21. #define Stack_Size __stack_size__
      22. #else
      23. #define Stack_Size 0x0400
      24. #endif
      25. #if (defined(__heap_size__))
      26. #define Heap_Size __heap_size__
      27. #else
      28. #define Heap_Size 0x0400
      29. #endif
      30. LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; load region size_region
      31. VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address
      32. * (RESET,+FIRST)
      33. }
      34. ER_m_text m_text_start FIXED m_text_size { ; load address = execution address
      35. * (InRoot$$Sections)
      36. .ANY (+RO)
      37. }
      38. #if (defined(__ram_vector_table__))
      39. VECTOR_RAM m_interrupts_ram_start EMPTY m_interrupts_ram_size {
      40. }
      41. #else
      42. VECTOR_RAM m_interrupts_start EMPTY 0 {
      43. }
      44. #endif
      45. RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data
      46. .ANY (+RW +ZI)
      47. }
      48. ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up
      49. }
      50. ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down
      51. }
      52. }
      53. LR_m_usb_bdt m_usb_sram_start usb_bdt_size {
      54. ER_m_usb_bdt m_usb_sram_start UNINIT usb_bdt_size {
      55. * (m_usb_bdt)
      56. }
      57. }
      58. LR_m_usb_ram (m_usb_sram_start + usb_bdt_size) (m_usb_sram_size - usb_bdt_size) {
      59. ER_m_usb_ram (m_usb_sram_start + usb_bdt_size) UNINIT (m_usb_sram_size - usb_bdt_size) {
      60. * (m_usb_global)
      61. }
      62. }

          如上,比較專業(yè)的分散加載寫法(不是我寫的,小編我人懶,于是Copy了原廠的,不過跟我們之前寫的簡易分散加載結構是一樣的,要點我們基本都講到了,這里主要區(qū)別只是使用了預處理器的功能)

          分散加載的部分暫時寫到這里,一共寫了6-7篇文章,當然還有很多內容沒有覆蓋到,以后我們碰到了再詳細寫幾篇提高篇的內容,大部分基本原理講清楚了,把這些內容消化掉,足夠應付大多數(shù)應用了。

          下面的文章我們會進入下一個大的專題,就是調試技術,也會有多篇文章,詳細介紹深入的調試技巧。

        本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多