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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1261|回復: 0
打印 上一主題 下一主題
收起左側

STM32單片機外部存儲器的使用資料

[復制鏈接]
跳轉到指定樓層
樓主
ID:609322 發表于 2023-12-4 09:35 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
STM32外部存儲器使用資料,很有參考價值
最近在學習一些gui方面的操作,并且是要跑os的;突然就發現自己的硬件平臺的內部SRAM資源不夠用了(硬件平臺:戰艦V2,stm32f103ze、外擴SRAM:1M);怎么破,那只能把外部的SRAM給用起來,不用就是浪費啊,要知道SRAM可是不便宜啊;
         然后就開始借鑒了配套例程:外部SRAM的使用;通過fsmc來控制實現,外部sram可以正常使用了,但是我想嘗試下其他的方法來使用外部的SRAM:
1、  不使用attribute關鍵字來實現變量等在外部的分配,讓編譯器自己來完全支配,這樣我們就不用計算我們指定的地址是否會重合等問題;
2、  讓內部的64K SRAM、外部的1M SRAM都能用,而且讓編譯器自己處理使用;
3、  完全不使用內部的SRAM,只使用外部的SRAM

上網上查閱一些資料后,發現這個需要在2010年就有了,而且當時網友遇到的問題,我在實驗中也遇到了,關鍵是前面的帖子,也沒有很明確或是清晰的給出解釋,有的帖子給的方法是可以實現要求的,但是沒有說為什么這樣可以,所以我自己一邊實驗一邊驗證,下面把自己遇到的問題和現象做一個記錄:
1、  按照網友的方法來配置,讓編譯器自動處理SRAM的使用
(1)       實驗前提,例程采用配套例程的:37外部SRAM實驗;外部SRAM的初始化使用system_stm32f10x.c官方提供的fsmc初始化;
(2)       工程配置
開啟system_stm32f10x.c中的fsmc初始化外部SRAM函數;
配置工程中SRAM的分配,注意:SRAM部分有兩塊,兩個√
注意去掉main文件中的testsram[]的屬性定義
(3)       實驗結果,程序正常執行;
鏈接加載控制文件內容:
工程的map文件,如果對map文件不熟悉的可以自行查閱資料
是不是很明顯:一大堆的變量和數據段都分配在了內部的SRAM,只有一個.bss段分配到了外部的SRAM 0x68000000地址處,為什么會這樣,因為內部放不下了啊,另外咱們的testsram數組是沒有初始化的,你試一下在定義時就初始化,看看地址有什么變化;要理解這里的原理,就需要對分散加載文件有深入的了解了,自行查找;

2、  完全不使用內部SRAM,只使用外部SRAM
(1)       工程配置和上面的實驗一致,只修改一個部分,去掉內部SRAM的配置
(2)       編譯測試
編譯是沒有任何問題的,下載驗證吧,程序跑不起來,失敗了;
在線jlink調試一下:
看到了吧,死在這里和,硬件fault了;先不解釋為什么;
(3)       解決問題的過程
之前在網上搜到一些建議,但是我還是選擇了,先用jlink調試一下看看;
             我在用jlink在線調試操作過程是:
             第一步:單步調試,看一下是哪里進入了硬件fault;我在void SystemInit (void)函數中增加了一些調試
            
目的是看一下,這的fsmc對外部的SRAM的操作是否正確,結果是正確的,說明官方的fsmc初始化沒有問題,此時外部的SRAM已經可以正常使用了;
第二步:繼續單步調試,發現是在這個地方進入了硬件fault了:static void SetSysClockTo72(void)函數的退出時
到這里你在執行單步一次,就會進入硬件fault,可以確定了是在函數返回時進入硬件fault,這里先不解釋原因;

第三步:我借鑒了一下網友的建議,如下:
         工程配置不用改動任何地方,還是只配置外部SRAM作為唯一的選擇,注意這里和 的配置是不一樣的,它的同時配置了外部和內部SRAM,如果這樣那他所做的操作就有些多余了,不用修改啟動文件就可以啊,就和我上面第1中的工程配置一樣啊,編譯器自己就可以處理了,不用你在修改啟動文件啊,這也是該貼下面很多網友說不用修改啟動文件中的
__initial_sp    EQU     0x20000000 + Stack_Size 也可以正常運行;如果你按照下面的工程配置,再不添加啟動文件中的__initial_sp    EQU     0x20000000 + Stack_Size設置,你試一下可以正常運行嗎?答案是:不能;
         工程配置不變:
         
         修改啟動文件startup_stm32f10x_hd.s中的關于棧的位置定義:等價于強制把復位后的棧指針指向內部的SRAM位置處

好了,其它一切不變,編譯下載吧

第四步:下載驗證
成功運行程序
Sct文件內容:完全是把數據段放在了外部的SRAM中;
Map文件內容:所有數據段都在了外部SRAM上面;

到這里,你會有疑問吧,那我們剛才設置啟動文件中__initial_sp    EQU     0x20000000 + Stack_Size的目的是啥啊,為啥在配置不變情況下,不加程序就不正常,加了就可以正常運行;后面解釋,先附張圖,自己先分析一下


這里分享一個巧合事件:
我在2、完全不使用內部SRAM,只使用外部SRAM   ->  (3)解決問題的過程  -> 第三步 中給出的結論:如果你按照我的工程配置,只啟用外部sram配置選項,然后你又不設置啟動文件中棧指針的設置,程序是不會正常啟動的;
有的朋友可能在實驗中會出現,即按照只使用外部sram配置,且不添加啟動文件設置,程序也正常啟動了,會說我的結論是錯的,其實結論是對的,你這個配置下能正常運行程序,完全是個巧合,下面給出巧合呈現方法:
         第一步:按照下面的配置、下載、運行程序,系統正常運行,沒有任何問題
         

                       第二步:你為了推翻我的結論,在工程配置不變的情況下,只修改了啟動文件的配置,刪除了對棧指針的設置
接下來編譯、燒寫程序,進行驗證(注意這個過程前提是,你的平臺還在上次的程序下正常上電運行,這里直接按照第二步的設置編譯后,用jlink下載驗證,為了說明問題我把兩次的程序作了小處理,說明確實是連個不同的程序;上面的LCD上顯示是"WarShip ZG008",這里我們顯示是 "WarShip ZG009")
程序正常運行了,你的結論是錯的,別急:此時你把平臺的電源斷掉,在上電看看,程序能正常運行嗎,不能吧;
原因我還沒有深究,預估是,當你的平臺正常運行下,你用jilink在線下載程序時,外設的配置還會保持之前的狀態,至少fsmc的配置沒有改變,仍然可以操作外部的sram,所以你刪除了啟動文件的配置后,下載程序仍正常運行,斷電后在上電,就不行了;這里只是我的猜測,還沒有驗證;

到這里,大家是否明白了,這一切的設置,是不是都離不開一個東西:sp

3、  上面實驗現象分析
第一步:要清楚,cm3的內核是在上電后進入復位中斷處理,但是復位中斷的pc值可不是存儲在0x0000 0000 地址,而是下一個4字節的位置,0x0000 0000存儲的是sp的棧指針;
第二步:通過調試,你可以看到,程序進入上電復位中斷后,先跳轉到SystemInit()函數,調試截圖如下:
LDR     R0, =SystemInit
    BLX     R0   
當單步執行 BLX  r0后,注意觀察左邊寄存器的變化,以及上面的匯編語句:
看到了:R13的sp值改變了,因為發生了函數調用,需要保存上下文環境,所有有PUSH的操作,切記,這里對棧進行了操作,即入棧,那么當你從systeminit()函數返回時,就要涉及到出站,這點很重要,這就是你進入硬件fault的根源;

第三步:分析上面工程配置1中的設置,
這種配置,你只改變了SRAM的配置,讓外部和內部的都啟用,讓編譯器自己解決分配問題;通過map文件你可以很清楚:編譯器把大部分的數據段都還是放在了內部SRAM中,包括主要的__initial_sp棧頂指針,只把一個很大的內部sram放不下的main.c中定義的testsram[]放在了外部sram;
此時,堆棧指針在內部sram中,所以在復位中斷中的函數調用引發的入棧、出棧可以完全正常運行;

第四步:分析上面工程2中的配置
         
       這里分兩種情況,工程配置不變下,是否設置啟動文件的__initial_sp    EQU     0x20000000 + Stack_Size;
(1)       不修改啟動文件中的棧的設置
此時通過編譯后的map和調試文件可以知道:
當調用LDR     R0, =SystemInit
          BLX     R0         
            后會發生入棧的push操作,注意觀察此時的R13的數值:0x680F 4AF8;已經指向了外部的sram;
此處發生了push入棧操作,但是重點是此時我們還沒有對外部sram進行操作啊,試問你這個入棧能成功嗎,不能,那么里面的數值是函數返回后的下一條PC值嗎,肯定不是,是個垃圾值;然后,你調用pop操作,將一個垃圾值給了PC,那只能進入硬件fault了;

那我們找到了問題的根源,那咋改進呢:首先要明白一點,開發板硬件上電復位前,我們是無法完成STM32對外部SRAM的配置,只能上電后進行配置了才可以使用。也就是說,只有正常的硬件復位序列完成后,我們可以在Reset_Handler(復位中斷服務程序)中完成對SRAM的配置,但是在這之前,局部變量和函數調用用到的Stack棧空間,我們都得使用STM32內部SRAM,明白了這點,很重要;
(2)       修改啟動文件,設置 __initial_sp    EQU     0x20000000 + Stack_Size
此時,我們分析編譯后的map、調試信息:
注意觀察:此時的map中數據段信息,沒有__initial_sp的值;我們在看一下,調試時的信息:
很清晰:此時發生函數調用時,我們使用的棧指向了內部的sram控件,R13 = 0x2000 0400;所以當發生push、pop操作時,數據都是正確的,PC也可以得到正確的數值,從而按流程執行;
            所以我們在啟動文件中添加的那一條:__initial_sp    EQU     0x20000000 + Stack_Size很重要,就是強制把棧定義在了內部的sram中了,雖然通過map文件我們可以看到,在外部的sram中我們也分配了heap、stack的空間,但是我們的sp指針沒有指向他們,其實這里還有很多擴展的空間;

到這里,分析完了,外部sram的用法,以及為什么會出現這種現象,其中涉及到map文件的解析;以及分散加載。Sct的知識,沒有做仔細分析,合理安排、設計分散加載文件可以讓你的工程的鏈接、加載更加符合你的設計要求,所以在工程設置中,IDE才允許我們設置使用自己定義的.sct文件;有時間,后面再細分析;


以上圖文的Word格式文檔下載(內容和本網頁上的一模一樣,方便大家保存):
12 STM32的外部SRAM使用的總結.docx (1.78 MB, 下載次數: 3)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲三级在线观看 | 亚洲精品乱码久久久久久按摩观 | 国产精品69久久久久水密桃 | 国产激情在线 | 亚洲午夜视频在线观看 | 国产一区二区av | 亚洲成人免费 | 亚洲一区精品视频 | 欧美视频二区 | 特级做a爰片毛片免费看108 | 欧美激情一区二区三区 | www.黄色在线观看 | 久久久久久久久久久久一区二区 | 国产午夜精品一区二区三区嫩草 | 欧美激情一区二区 | 中文字幕第十一页 | 欧美一区二区三区四区在线 | 国产精品69毛片高清亚洲 | 久久中文视频 | 久久精品毛片 | 99成人 | 一级黄色日本片 | 亚洲精品视频在线播放 | 亚洲欧美视频一区 | 少妇淫片aaaaa毛片叫床爽 | 国产一区二区在线播放 | 中文字幕av在线 | 99久久精品免费看国产小宝寻花 | 欧美性视频在线播放 | 国产欧美日韩一区二区三区 | 亚洲 欧美 另类 综合 偷拍 | 国产精品视频久久 | 国产精品久久久久久久久久 | 中文字幕亚洲一区二区va在线 | 91久久精品日日躁夜夜躁欧美 | 日本电影一区二区 | 亚洲精品福利在线 | 在线中文字幕av | 国产日韩欧美一区 | 亚洲va欧美va天堂v国产综合 | 欧美极品在线视频 |