1. 前言
對(duì)于 Cortex-M 內(nèi)核的微控制器,它們都可以支持在 RAM 中執(zhí)行程序,有些非 ARM 的微控制器是不支持的。
在內(nèi)部 SRAM 執(zhí)行程序,有基于以下幾方面的原因:
- 1、所使用的設(shè)備可能具有OTP(One-time Programmable,一次性可編程)ROM區(qū)域,還沒(méi)有確定最終代碼之前,還不會(huì)把程序編程到芯片中;
- 2、有些MCU內(nèi)部?jī)?nèi)部可能沒(méi)有Flash,可能會(huì)使用到外部的存儲(chǔ)器。但是在軟件開(kāi)發(fā)階段可以下載到SRAM進(jìn)行開(kāi)發(fā)測(cè)試;
- 3、對(duì)于特定的測(cè)試場(chǎng)合,F(xiàn)lash已經(jīng)燒錄了程序,但是不想擦除。這時(shí)可以把測(cè)試程序下載到SRAM運(yùn)行;
- 4、對(duì)于有些Flash被鎖定的芯片,可以把代碼下載到SRAM,然后進(jìn)行解鎖;
- 5、Flash寫(xiě)入需要先擦除,所以SRAM的寫(xiě)入速度要比Flash快很多,如果程序很大的話,在開(kāi)發(fā)階段直接在SRAM運(yùn)行可以提高效率。
對(duì)于程序下載到內(nèi)部SRAM運(yùn)行,有多種方法:
- 1、配置boot引腳,然后下載代碼到SRAM,使程序從SRAM啟動(dòng)
- 2、不修改boot引腳啟動(dòng)模式,借助仿真器,進(jìn)入仿真模式,然后強(qiáng)制更改 PC SP 指針,從SRAM位置取值開(kāi)始運(yùn)行
- 3、程序下載到內(nèi)部Flash或者外部的SD卡、SPI Flash等存儲(chǔ)設(shè)備,然后上電之后把代碼搬運(yùn)到SRAM運(yùn)行(類似代碼的重定位)
下面只介紹前面兩種方式。
首先在修改程序在SRAM運(yùn)行之前,要先準(zhǔn)備好一份可以正常在Flash運(yùn)行的程序。
2. 修改散列文件
散列文件,就是鏈接腳本,指導(dǎo)鏈接器如何對(duì)程序進(jìn)行鏈接的。
我們要讓代碼在SRAM運(yùn)行,首先就要修改散列文件,讓程序鏈接地址修改在內(nèi)部SRAM空間。
我們打開(kāi)Keil的配置界面,然后使用我們自己修改的散列文件。
修改后的散列文件內(nèi)容如下:
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x20000000 0x00010000 { ; load region size_region
ER_IROM1 0x20000000 0x00010000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20010000 0x00010000 { ; RW data
.ANY (+RW +ZI)
}
}
我使用的MCU型號(hào)是 STM32F407ZG ,IARM1 的 SRAM 大小有 0x20000 ,即 128KB。我這里分配的代碼區(qū)域(ER_IROM1)大小是 0x10000(64KB),然后可讀可寫(xiě)的數(shù)據(jù)區(qū)域大小是0x10000(64KB),也就是把他們平均分了。
在實(shí)際的項(xiàng)目開(kāi)發(fā)中,可根據(jù)實(shí)際情況改寫(xiě)分配。
3. 修改中斷向量表基地址
默認(rèn)的中斷向量表基地址是指向 0x08000000 的地址處的,現(xiàn)在我們已經(jīng)更改了鏈接地址,把程序鏈接到內(nèi)部SRAM 0x20000000 區(qū)域了。
如果發(fā)生中斷,CPU還是跳到0x08000000開(kāi)始的地址處執(zhí)行中斷服務(wù)函數(shù)的話,那么肯定是程序崩潰,因?yàn)楝F(xiàn)在0x08000000處的地址已經(jīng)沒(méi)有代碼了。
要想正常使用中斷的話,就必須修改中斷向量表的基地址指向0x20000000地址處。
修改中斷向量表基地址,只要修改 SCB->VTOR 寄存器的值就行。
具體代碼,在 system_stm3f4xx.c 的 SystemInit 函數(shù)就有。如下:
void SystemInit(void)
{
/* 部分代碼省略 ........ */
/* Configure the Vector Table location add offset address */
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
SCB->VTOR = FMC_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}
我們只要定義這個(gè) VECT_TAB_SRAM 宏,就可以修改中斷向量表的基地址指向 0x20000000 的地址處了。
這個(gè)宏可以直接在Keil的配置界面 C/C++ 選項(xiàng)里面的宏定義那里填寫(xiě),當(dāng)然直接在 system_stm3f4xx.c 這個(gè)文件前面自己手動(dòng)寫(xiě)一下也可以。
4. 修改下載算法的配置
為了把代碼下載到SRAM中,還需要修改Jlink的下載算法配置,只要其實(shí)就是更改下載的地址改為 SRAM 的地址。
對(duì)于上面的配置簡(jiǎn)單解釋如下:
- 1、由于是下載到SRAM,SRAM寫(xiě)入是不需要擦除的,所以勾選 DO not Erase 即可
- 2、“Programming Algorithm”一欄的配置,由于沒(méi)有內(nèi)置的SRAM下載算法,所以下載算法選擇的還是原來(lái)的Flash下載算法。但是下面的起始地址和大小需要更改,就改為我們?cè)谏⒘形募x代碼區(qū)域的起始地址和大小。
- 2、“RAM for Algorithm”一欄是指“編程算法”(Programming Algorithm)可使用的 RAM 空間,下載程序到 FLASH 時(shí)運(yùn)行的編程算法需要使用 RAM 空間,在默認(rèn)配置中它的首地址為 0x20000000,即內(nèi)部 SRAM 的首地址。但是現(xiàn)在我們修改了0x20000000開(kāi)始處存放的是代碼,所以這里的起始地址要修改了散列文件設(shè)置的 RW 區(qū)域的起始地址,即 0x20010000 。然后大小默認(rèn)不用改。
5. 修改boot啟動(dòng)模式
配置到這里,其實(shí)我們這時(shí)如果更改Boot的啟動(dòng)引腳,配置為內(nèi)部SRAM啟動(dòng),然后點(diǎn)擊下載按鈕,程序就可以正常跑了的。
但是如果不修改boot啟動(dòng)模式,然后從SRAM啟動(dòng)的話,也可以借助仿真器配置,進(jìn)入仿真調(diào)試模式,然后通過(guò)仿真器配置強(qiáng)制 PC SP 指針從 0x20000000 開(kāi)始處取值,這樣也能讓程序正常從SRAM運(yùn)行。
6. 通過(guò)仿真器配置修改 PC SP 的值
修改boot模式的目的,其實(shí)就是讓MCU上電之后,可以從正確的地址處獲取到 PC SP 指針的初始值,這樣代碼才可以正常開(kāi)始運(yùn)行。
讓 PC SP 獲取到正確的值,有兩種方式:
- 修改Boot啟動(dòng)模式,讓程序從內(nèi)部SRAM啟動(dòng)
- 不修改啟動(dòng)模式,然后通過(guò)仿真器配置,進(jìn)入仿真模式,強(qiáng)制修改 PC SP 的值。
下面介紹下怎么通過(guò)仿真器配置,讓代碼在SRAM運(yùn)行。
首先我們自己編寫(xiě)一份 .ini 的調(diào)試配置文件,強(qiáng)制 PC SP 指針的地址值。內(nèi)容如下:
/***********************************************************/
/* Debug_RAM.ini: Initialization File for Debugging from Internal RAM */
/******************************************************/
/* This file is part of the uVision/ARM development tools. */
/* Copyright (c) 2005-2014 Keil Software. All rights reserved.*/
/* This software may only be used under the terms of a valid, current */
/* end user licence from KEIL for a compatible version of KEIL software */
/*development tools. Nothing else gives you the right to use this software ?*/
/***************************************************/
FUNC void Setup (void) {
SP = _RDWORD(0x20000000); // 設(shè)置棧指針 SP,把 0x20000000 地址中的內(nèi)容賦值到 SP。
PC = _RDWORD(0x20000004); // 設(shè)置程序指針 PC,把 0x20000004 地址中的內(nèi)容賦值到 PC。
// XPSR = 0x01000000; // 設(shè)置狀態(tài)寄存器指針 xPSR
_WDWORD(0xE000ED08, 0x20000000); // Setup Vector Table Offset Register
}
LOAD %L INCREMENTAL // 下載 axf 文件到 RAM
Setup(); //調(diào)用上面定義的 setup 函數(shù)設(shè)置運(yùn)行環(huán)境
g, main //跳轉(zhuǎn)到 main 函數(shù)
然后配置Keil的選項(xiàng),如下:
這樣,通過(guò)這種方式,不需要修改boot引腳的啟動(dòng)模式,點(diǎn)擊 debug 調(diào)式按鈕,也一樣可以正常在SRAM運(yùn)行。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-728011.html
缺點(diǎn)就是下載程序必須是點(diǎn)擊進(jìn)入調(diào)試界面,不能通過(guò)下載程序的按鈕下載程序。因?yàn)檫@種方式是通過(guò)仿真器的配置強(qiáng)制設(shè)置 PC SP 指向正確的地址的。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-728011.html
到了這里,關(guān)于基于MDK-Keil環(huán)境如何把STM32程序直接下載到SRAM運(yùn)行的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!