c - 嵌入式 ARM 和 C 运行时

标签 c linker arm bare-metal

我正在 ARM1176JZ-F 处理器 (RPi B+) 上试验裸机编程,同时尝试了解 C 运行时的作用。

我正在使用 arm-none-eabi-gcc 工具链交叉编译我的基本内核(归结为只是在寄存器和内存中移入和移出一些位),使用以下标志:

arm-none-eabi-gcc -O2 -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s -nostartfiles foo.c

我在使用代码中的自动变量时遇到一些问题,需要一些指导!

首先,我不确定运行时库和“启动”例程之间的关系,它们是否相同,“-nostartfiles”实际上不链接运行时,或者这些例程只是一部分运行时库的工作?

其次,我不确定运行时如何与自动变量相关,我注意到,虽然不会导致编译错误,但无法正常工作!

非常感谢任何指导!

编辑:请参阅下面的代码片段。如果 |gpioBase| 程序似乎无法运行(但可以正常编译)和|计时器|变量在主功能 block 中声明。

/*
* armc1.c
*
* flash PWR/ACT LEDs on RPi B+
*
**/

#include <stdint.h>

//variables declared outside function block, no runtime support = no automatic variables!
volatile uint32_t* gpioBase; //BCM2835 gpio base
volatile uint32_t time; //timer

int main(void) {
  gpioBase = (uint32_t*)(0x20200000UL); //BCM2835 gpio physical address
  //set outputs
  gpioBase[3] = (1<<15); //GPFSEL3 @ 0x2020000C = 0b0..001..0, GPIO35 as output
  gpioBase[4] = (1<<21); //GPFSEL4 @ 0x20200010 = 0b0..001..0, GPIO47 as output
  //infinite loop, no OS
  while(1) {
    gpioBase[8] = (1<<3); //GPSET1-SET35 @ 0x20200020 = 1, GPIO35 on
    gpioBase[8] = (1<<15); //GPSET1-SET47 @ 0x20200020 = 1, GPIO47 on
    for(time = 0;time < 500000;time++); //waste time
    gpioBase[11] = (1<<3); //GPCLR1-CLR35 @ 0x2020002C = 1, GPIO35 off
    gpioBase[11] = (1<<15); //GPCLR1-CLR47 @ 0x2020002C = 1, GPIO47 off
    for(time = 0;time < 500000;time++); //waste time
  }
}

最佳答案

谢谢大家的回复!

正如 artless noise & scaletos 所指出的,我确实需要做一些汇编才能使代码正常工作。所需要的只是设置堆栈的一点入口点魔术和链接描述文件的一点帮助来清除 .bss 部分。

关于c - 嵌入式 ARM 和 C 运行时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29994740/

相关文章:

c - 是否可以在 CUDA 中使用推力库将推力::device_vector 和推力::fill 用于 2D 数组

c++ - 矩阵乘以它的转置返回零矩阵?

c - C 中的随机图

gcc - GNU gcc/ld - 使用在同一目标文件中定义的调用者和被调用者包装对符号的调用

c - 从C中同一目录中的另一个文件调用函数

c++ - 使用活跃的 NEON 标志编译代码几乎没有任何改进(甚至恶化)

c - Overeager struct packing warnings with `__attribute__((packed))` ?

c++ - 在不需要的宏使用上强制出现 C++ 错误

在 Linux 上使用 Redis 编译 C 代码

c - 如何编译和链接示例代码以获得二进制文件?