我目前正在使用TI EK-LM4F120XL板。该板包含Cortex-M4F cpu。我使用以下链:
ARM GCC无EABI https://launchpad.net/gcc-arm-embedded/4.8/4.8-2014-q2-update
以下调试器:
OpenOCD http://openocd.sourceforge.net/
问题是我需要使用-Os标志来防止奇怪的行为。例如,使用TI提供的代码:
默认链接描述文件:
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
SECTIONS
{
.text :
{
_text = .;
KEEP(*(.isr_vector))
*(.text*)
*(.rodata*)
_etext = .;
} > FLASH
.data : AT(ADDR(.text) + SIZEOF(.text))
{
_data = .;
*(vtable)
*(.data*)
_edata = .;
} > SRAM
.bss :
{
_bss = .;
*(.bss*)
*(COMMON)
_ebss = .;
} > SRAM
}
startup_gcc.c文件:pastbin, because the file is large
一个非常简单的闪光灯:
int
main(void)
{
volatile unsigned long ulLoop;
//
// Enable the GPIO port that is used for the on-board LED.
//
SYSCTL_RCGC2_R = SYSCTL_RCGC2_GPIOF;
//
// Do a dummy read to insert a few cycles after enabling the peripheral.
//
ulLoop = SYSCTL_RCGC2_R;
//
// Enable the GPIO pin for the LED (PF3). Set the direction as output, and
// enable the GPIO pin for digital function.
//
GPIO_PORTF_DIR_R = 0x08;
GPIO_PORTF_DEN_R = 0x08;
//
// Loop forever.
//
while(1)
{
//
// Turn on the LED.
//
GPIO_PORTF_DATA_R |= 0x08;
//
// Delay for a bit.
//
for(ulLoop = 0; ulLoop < 200000; ulLoop++)
{
}
//
// Turn off the LED.
//
GPIO_PORTF_DATA_R &= ~(0x08);
//
// Delay for a bit.
//
for(ulLoop = 0; ulLoop < 200000; ulLoop++)
{
}
}
}
没有什么特别的,所有默认代码都是由TI创建的。编译和链接命令:
~/gcc-arm-none-eabi/bin/arm-none-eabi-gcc blink.c startup_gcc.c -g -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Os -MD -std=c99 -Wall -pedantic -DPART_LM4F120H5QR -c -I/home/jacko/git/jackoOS/stellaris-exe -DTARGET_IS_BLIZZARD_RA1
~/gcc-arm-none-eabi/bin/arm-none-eabi-ld -T blink.ld --entry ResetISR -o a.out startup_gcc.o blink.o --gc-sections
如您所见,编译命令包含-Os参数。如果我将这个添加到命令一切正常,但如果我删除它,寄存器7开始行为非常奇怪:
(gdb) monitor reg
===== arm v7m registers
(0) r0 (/32): 0x00000000
...
(7) r7 (/32): 0x200000F0
...
(13) sp (/32): 0x200000F0
...
(17) msp (/32): 0x200000F0
...
===== Cortex-M DWT registers
...
(36) dwt_3_function (/32)
(gdb) cont
...
(gdb) monitor reg
===== arm v7m registers
...
(7) r7 (/32): 0x200000E0
...
(13) sp (/32): 0x200000E0
...
(17) msp (/32): 0x200000E0
(18) psp (/32): 0x00000000
...
===== Cortex-M DWT registers
...
(36) dwt_3_function (/32)
(可以找到完整转储here)
R7与SP具有相同的值(MSP =活动SP)!为什么会这样做?
如果我尝试用:
写入R7MOV R7, R0
程序崩溃成了一个严重的错误。
那么,为什么这些-Os旗帜如此重要?为什么R7在没有它的情况下表现得如此奇怪?
答案 0 :(得分:3)
GCC在拇指模式下使用R7作为FP。尝试&#34; -fomit-frame-pointer&#34;如果您没有使用任何优化标志来避免该行为。