久久精品99久久_亚洲一区二区综合_狠狠色伊人亚洲综合成人_亚洲综合爱爱久久网

你好!歡迎來到深圳市穎特新科技有限公司!
語言
當前位置:首頁 >> 品牌中心 >> ST/意法 >> KEIL環境下如何讓代碼在 RAM中運行

KEIL環境下如何讓代碼在 RAM中運行

關鍵字:KEILNucleoSTM32 作者: 來源: 發布時間:2019-01-03  瀏覽:236

前言
經常遇到有人使用KEIL時需要將部分或者全部程序代碼放到RAM中運行的問題,現將其總結在本文中。通過STM32F411Nucleo的一個例子來介紹幾種讓程序在RAM中運行的方法。

我們先從ToggleLED函數在Flash中執行亮滅開始。下面是ToggleLED函數和它的調用情況。在main函數的while(1)里調用ToggleLED。

void ToggleLED(void)
{ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); /* Insert a 100ms delay */
HAL_Delay(100);
}

int main(void)
{ …… /*##-3- Toggle PA05 IO in an infinite loop ######*/
while (1) { ToggleLED(); }
}

編譯環境的Linker的配置見下圖:
Flash起始地址:0x08000000
RAM起始地址:0x20000000

1

編譯后從map文件可以看到,ToggleLED以及其中調用到的HAL_GPIO_TogglePin和HAL_Delay函數的地址都在FLASH中。

2
將翻轉LED的程序放到SRAM中執行
方法一:通過#pragma arm section code = “RAMCODE ”和#pragma arm section。參考Example1代碼。
這種方式,可以同時將多個函數放到指定的section。具體方法如下:
1. 修改.sct文件,自定義一個叫做RAMCODE的section,放在RW_IRAM1執行區域,地址范圍0x20000000~0x20020000。

LR_IROM1 0x08000000 0x00080000 { ; load region size_region
ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
} RW_IRAM1 0x20000000 0x00020000 { ; RW data
*.o(RAMCODE)
.ANY (+RW +ZI)
}
}

2. 在工程中使用前面修改的.sct文件

3

3.以#pragma arm section code = “RAMCODE” 開頭,以#pragma arm section結尾。將所有需要放到RAMCODE section的函數包括進來。編譯時,編譯器會自動將這些函數放到RAMCODE所在0x20000000開始的區域。

#pragma arm section code = "RAMCODE"
void ToggleLED(void)
{ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); /* Insert a 100ms delay */
HAL_Delay(100);
}

void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{ /* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->ODR ^= GPIO_Pin;
}

uint32_t HAL_GetTick(void)
{ return tick;
}

void HAL_Delay(__IO uint32_t Delay)
{ uint32_t tickstart = 0;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay)
{
}
}
#pragma arm section

4.從map文件里,可以看到這四個函數都已經被放到了SRAM中。

4

方法二:通過__attribute__((section(“name ”)))
在KEIL中可以通過__attribute__((at(address)))的方式將變量放到指定的位置。
通過__attribute__((section(“name ”)))的方式將變量或者函數放到指定的位置。

下面我們來看看如何通過這種方式將程序放到SRAM中執行。
1.同樣,我們需要修改.sct文件,自定義一個叫做RAMCODE的section,并在工程選項的linker頁面中,選擇定義好的.sct文件。(見方法一中的第1,2步)

LR_IROM1 0x08000000 0x00080000 { ; load region size_region ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00020000 { ; RW data
*.o(RAMCODE)
.ANY (+RW +ZI)
}
}

2.在需要放到RAM中的函數前,用__attribute__((section("RAMCODE")))聲明該函數放在RAMCODE section中。注意,該函數中調用到的所有函數也要放到RAMCODE section中。

__attribute__((section("RAMCODE")))
void ToggleLED(void)
{ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); /* Insert a 100ms delay */
HAL_Delay(100);
}

__attribute__((section("RAMCODE")))
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{ /* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->ODR ^= GPIO_Pin;
}

__attribute__((section("RAMCODE")))
__weak uint32_t HAL_GetTick(void)
{ return uwTick; }

__attribute__((section("RAMCODE")))
__weak void HAL_Delay(__IO uint32_t Delay)
{ uint32_t tickstart = 0;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay)
{ }
}

3.從編譯后的map文件可以看出,ToggleLED以及它調用到的所有函數都被到了RAM中。

00

方法二可以覆蓋方法一,也就是說如果你同時用方法一和方法二對同一個函數的執行區域做了說明。最終起作用的是方法二。還是通過上面提到的代碼來說明。
修改.sct文件。將SRAM分為兩個執行區RW_IRAM1和RW_IRAM2。Section RAMCODE1,RAMCODE2分別位于0x20000000開始,和0x20010000開始的兩個64KB的區域。

LR_IROM1 0x08000000 0x00080000 { ; load region size_region ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}

RW_IRAM1 0x20000000 0x00010000 { ; RW data
*.o(RAMCODE1)
.ANY (+RW +ZI)
}

RW_IRAM2 0x20010000 0x00010000 {
*.o(RAMCODE2) }
}

2.在代碼中, HAL_GetTick被放在了#pragma的作用域內被聲明放在RAMCODE1 section,同時又用__attribute__( ( section ( "RAMCODE2" ) ) ) 將其放在RAMCODE2的section內。

#pragma arm section code = "RAMCODE1"
void ToggleLED(void)
{ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
/* Insert a 100ms delay */
HAL_Delay(100); }

void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{ /* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->ODR ^= GPIO_Pin;
}

__attribute__( ( section ( "RAMCODE2" ) ) )
uint32_t HAL_GetTick(void)
{ return tick; }

void HAL_Delay(__IO uint32_t Delay)
{ uint32_t tickstart = 0;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay) { }
}
#pragma arm section

3.編譯完成后,我們看看map文件中HAL_GetTick被放到了哪個section。

5

從map里可以看到,最終HAL_GetTick被放在了RAMCODE2 section中。

**如何將整個程序放到SRAM中執行
前面介紹了將一個或多個程序放到指定地址執行的方法。如果需要放到指定地址的程序比較多,我們還可以將這些需要放到指定地址的程序集中放到一個或幾個C文件中,然后在.sct文件中將這些C文件生成的目標文件放到指定地址。
在這里,我們將嘗試將整個程序放到SRAM中執行。復位后程序從FLASH啟動,之后將從SRAM執行所有的程序。下面是具體的步驟。
1.將中斷向量表和中斷處理程序放到SRAM中
新建一個startup_stm32f411xe_ram.s文件,放到0x20000000開始的位置(在.sct文件中修改)。注意這里是新建,而不是直接將原來的文件放到SRAM中,為什么呢?大家可以思考一下。在startup_stm32f411xe_ram.s里定義新的SECTION,叫做RESET_ram(還有其他的修改,請對照參考代碼)。在后面的.sct中將把RESET_ram這個section放到SRAM開始的位置上(見第3步)。

Vector Table Mapped to Address 0 at Reset
AREA RESET_ram, DATA, READONLY
EXPORT __Vectors_ram
EXPORT __Vectors_End_ram
EXPORT __Vectors_Size_ram
__Vectors_ram DCD 0 ; Top of Stack
DCD 0 ; Reset Handler
DCD NMI_Handler ; NMI Handler
……

2.在SystemInit中將中斷向量表的偏移地址設置為0x20000000。使能VECT_TAB_SRAM。

#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif

3.修改.sct文件,將運行時需要的所有目標文件都放到SRAM執行區中。這里中斷向量表有同樣的兩份,一份在0x08000000開始的位置,一份在0x20000000開始的位置。

LR_IROM1 0x08000000 0x00080000 { ; load region size_region
ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00020000 { ; RW data
*.o (RESET_ram, +First)
startup_stm32f411xe_ram.o(+RO)
main.o(+RO +RW)
stm32f4xx_it.o(+RO +RW)
stm32f4xx_hal.o(+RO +RW)
stm32f4xx_hal_gpio.o(+RO +RW)
stm32f4xx_hal_rcc.o(+RO +RW)
stm32f4xx_hal_cortex.o(+RO +RW)
.ANY (+RW +ZI)
}
}

4. 編譯完成后,從map文件或者跟蹤調試的結果都可以看到。系統復位以后,從main函數開始,所有的程序都在RAM中運行了。
另外,如果你的程序中有用到ARM底層的庫,可以在.sct文件中加入*armlib*(+RO)來將所有用到的庫文件放到SRAM中。

STM32/STM8 意法半導體/ST/STM

編輯:admin  最后修改時間:2019-01-03

聯系方式

0755-82591179

郵箱:ivy@yingtexin.net

地址:深圳市南山區桃源街道平山社區平山一路2號南山云谷創業園二期11棟410-411

Copyright © 2014-2026 穎特新科技有限公司 All Rights Reserved.  粵ICP備14043402號-4

久久精品99久久_亚洲一区二区综合_狠狠色伊人亚洲综合成人_亚洲综合爱爱久久网
精品一区二区三区无码视频| 91精品999| 在线播放 亚洲| 污污的视频免费| 欧美大片在线播放| 福利视频一区二区三区四区| 福利在线小视频| www.亚洲视频.com| 青青青在线视频播放| 台湾无码一区二区| www插插插无码视频网站| 国产成人艳妇aa视频在线| 日本中文字幕在线视频观看 | 国产高清av片| 一级片免费在线观看视频| 黄色a级三级三级三级| 成人午夜免费剧场| 日本精品免费在线观看| 久久久精品高清| 日本一道在线观看| 狠狠操精品视频| 17c国产在线| 国产www免费| 啊啊啊国产视频| 国产精品12p| 青青视频在线播放| 欧美特黄aaa| 国产av天堂无码一区二区三区| 中文字幕乱码人妻综合二区三区| 五月天视频在线观看| 成人午夜免费在线| 男人的天堂最新网址| av在线播放亚洲| 免费涩涩18网站入口| 欧洲精品在线播放| а 天堂 在线| 哪个网站能看毛片| 精品一区二区三区无码视频| 亚洲欧洲日本精品| 欧美男女爱爱视频| 国产成人强伦免费视频网站| 精品一卡二卡三卡| 黄色成人在线免费观看| 污视频免费在线观看网站| 国产乱淫av片杨贵妃| 中文字幕剧情在线观看| av免费中文字幕| av在线免费观看国产| 中文字幕黄色大片| 国产成人美女视频| 午夜久久久精品| 麻豆av免费在线| 免费av观看网址| 久久这里只有精品18| 91免费网站视频| 99中文字幕在线| 午夜精品免费看| 亚洲视频一二三四| 色婷婷成人在线| 黄色小视频免费网站| 特级丰满少妇一级| 亚洲美女爱爱视频| 亚洲欧美日韩一二三区| 熟妇熟女乱妇乱女网站| 中文字幕亚洲乱码| 午夜激情影院在线观看| 99视频在线观看视频| 国产盗摄视频在线观看| 亚洲一区 在线播放| 路边理发店露脸熟妇泻火| 精品国产无码在线| 国产女主播自拍| 成年人网站免费视频| 777米奇影视第四色| 韩国日本在线视频| 日本在线播放一区二区| 黄色一级片网址| 日韩中字在线观看| 成人羞羞国产免费网站| 欧美国产日韩另类| 亚洲中文字幕无码一区二区三区 | 人妻无码久久一区二区三区免费| 2019日韩中文字幕mv| 青青青在线视频播放| 一本久道中文无码字幕av| 国产又黄又猛又粗| 日韩a级黄色片| 日批视频在线免费看| 91香蕉视频污版| 日本不卡一区在线| 国产爆乳无码一区二区麻豆| 噜噜噜久久亚洲精品国产品麻豆| 999精品视频在线| 日韩不卡视频一区二区| 免费毛片小视频| www.99r| 99视频精品全部免费看| 欧美xxxxx在线视频| 欧美与动交zoz0z| 亚洲熟妇av一区二区三区| 黄色网址在线免费看| 凹凸国产熟女精品视频| 国产成年人在线观看| 日本精品一区二区三区四区| 国产又大又长又粗又黄| 日韩欧美精品在线观看视频| 日本久久高清视频| 性欧美videossex精品| 免费特级黄色片| 日本网站在线看| 免费看污黄网站| 日本十八禁视频无遮挡| 操bbb操bbb| 中文字幕免费高清在线| 日韩在线第三页| 日韩小视频在线播放| 国产一区二区三区播放| 亚洲一区二区三区观看| 成人精品视频一区二区| 黄色一级片播放| 999久久欧美人妻一区二区| 中文字幕12页| 亚洲视频一二三四| 国产小视频精品| 一路向西2在线观看| 日本老熟妇毛茸茸| 久草在在线视频| 一区二区xxx| 日日躁夜夜躁aaaabbbb| 五月婷婷六月丁香激情| a在线观看免费视频| 在线免费观看视频黄| 中文字幕22页| 日本福利视频导航| 天天爱天天做天天操| 日韩中文在线字幕| 男人草女人视频| 国产黄色片免费在线观看| 800av在线免费观看| www.国产亚洲| 国产午夜大地久久| 国内外免费激情视频| 毛葺葺老太做受视频| 鲁一鲁一鲁一鲁一av| 成人免费黄色av| 日本成人在线不卡| 亚洲 欧美 日韩 国产综合 在线 | 97人人爽人人| 免费看污污视频| 亚洲国产精品无码av| wwwxxx黄色片| 一级做a爱视频| av网站手机在线观看| 午夜欧美福利视频| 国产高潮呻吟久久久| 可以在线看的av网站| 伊人网在线综合| 日本精品福利视频| 黄色片久久久久| 男人天堂成人网| 日韩免费高清在线| 欧美一二三不卡| 在线看的黄色网址| 无码人妻精品一区二区三区99v| 成人免费在线网| 成人亚洲免费视频| 不卡影院一区二区| 日韩欧美精品免费| 中文字幕第22页| 亚洲自偷自拍熟女另类| 国产人妻互换一区二区| 日本三级黄色网址| 日本阿v视频在线观看| 97超碰成人在线| 黄色片视频在线播放| 国产一二三区在线播放| 中文字幕12页| 亚洲高清免费在线观看| 国产福利视频在线播放| av在线免费观看国产| 天堂v在线视频| 久热在线视频观看| 天堂网在线免费观看| 人妻有码中文字幕| 777av视频| 亚洲熟妇无码一区二区三区| 日本特级黄色大片| 在线观看视频黄色| 一级黄色大片儿| 人人爽人人爽av| 亚洲欧美天堂在线| 九九久久久久久| 黄色三级视频在线播放| 性鲍视频在线观看| 男女激烈动态图| 成人在线观看毛片| 精品国产一区二区三区在线| 欧美一级黄色录像片| av影院在线播放| 中文字幕人妻熟女人妻洋洋|