声明
讲解stm32c8t6点灯程序从c语言到bin烧录文件的整体流程。
第一部分,比较重要,说清楚被开发工具隐藏的c语言到bin文件流程,包括交叉编译器、c语言预处理,编译,汇编,链接,各个阶段生成的文件。
第二部分,将生成的bin反向推理中断向量,代码编反汇编。
第三部分,通过bootloader+app讲解中断偏移等内容
第一部分
在window下使用交叉编译工具
- 安装
https://developer.arm.com/downloads/-/gnu-rm
- 配置环境变量,配置到windows环境
D:\Program Files (x86)\GNU Arm Embedded Toolchain\10 2021.10\bin
- 由于windows执行makefile比较困难,需要一步一步编译每个.c文件,再做链接,要么就要写shell脚本,比较麻烦。现在只举一些例子。以下是点灯程序,包含main.c:对应的c文件,以及startup.s:对应的汇编启动代码,还有link.ld链接脚本。
main.c
// 寄存器地址(STM32F103 固定)
#define RCC_BASE 0x40021000
#define GPIOA_BASE 0x40010800
#define RCC_APB2ENR *(volatile unsigned int *)(RCC_BASE + 0x18)
#define GPIOA_CRL *(volatile unsigned int *)(GPIOA_BASE + 0x00)
#define GPIOA_ODR *(volatile unsigned int *)(GPIOA_BASE + 0x0C)
void main(void)
{
// 1. 使能 GPIOA 时钟
RCC_APB2ENR |= 1 << 2;
// 2. 配置 PA0 推挽输出
GPIOA_CRL &= ~(0xF << 0);
GPIOA_CRL |= (0x3 << 0);
// 3. 点灯 PA0
GPIOA_ODR |= 1 << 0;
// 死循环
while(1);
}
startup.s
.equ _estack, 0x20005000
.section .isr_vector
.global _vector_table
_vector_table:
.word _estack
.word Reset_Handler
.word 0
.word 0
.word 0
.word 0
.word 0
.section .text.Reset_Handler
Reset_Handler:
bl main
b .
link.ld
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
RAM (rw) : ORIGIN = 0x20000000, LENGTH = 20K
}
SECTIONS
{
.text :
{
*(.isr_vector)
*(.text)
} > FLASH
.data :
{
*(.data)
} > RAM AT > FLASH
}
将上面的三个文件放到同一个目录下,依次执行以下shell命令
1.将startup.s汇编文件编译成目标文件
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -c startup.s -o startup.o
2.将main.c编译成目标文件
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -c main.c -o main.o
3.使用链接文件链接生成elf文件
arm-none-eabi-ld startup.o main.o -T link.ld -o main.elf
4.elf文件转成hex文件,elf文件转成bin文件
arm-none-eabi-objcopy -O ihex main.elf main.hex
arm-none-eabi-objcopy -O binary main.elf main.bin
步骤解析:
1.将汇编文件编程成目标文件过程。
2.main.c编译成目标文件,这个步骤依赖的头文件,如果是stdio.h这种已经有的会放在arm-none-eabi\include目录下,编译器会自己引进来。如果是自己写的比如,iic.c和iic.h,main.c引入了iic.h,这时候就需要添加**-T ./**命令。把对应目录下的头文件引进来。