基于STM32从零写操作系统系列---使用C语言
作者:互联网
如有不详细的描述、错误或疑问,欢迎留言!!!
目的
C语言,相对于汇编有更好的可读性,便于维护等优点。下面实验将使用C语言实现点亮LED灯。C语言与硬件是紧密连在一起的,结合芯片中的flash和sram,简单了解C语言。
要求
1.有一定的C语言基础
2.了解编译链接脚本
3.了解stm32F103的硬件结构
,代码中有详细注释!
分析
1.首先了解硬件,如图
FLASH,就是存放.bin文件的地方。SRAM,用于存放程序的堆栈,全局变量。
2.了解链接脚本,如图:
- MEMORY,用于定义存储器范围。 AT>rom,表示将对应的SECTION放置到rom中,即Flash中。 _data_start / _data_end,用于说明data段在flash中的位置,方便程序将data段从flash中复制到sram中。为什么要复制data段到sram中呢?由于flash定义为rx属性,即只读、可执行。data段的属性是rwx,即可读写、可执行。所以如果data段放在flash中,程序运行时,给全局变量赋值就会产生异常。 _ram_data_start,表示data段将复制到sram中的什么位置。 ADDR(),表示获得SECTION的运行地址vma,如ADDR(.data),表示data段的运行地址0x20000400;即,data段将在sram中运行。所以当程序被下载到flash后,程序开始运行时首先要将data段移动到sram中0x20000400地址处,这样程序运行时才不会出错。 LOADADDR(),表示获得SECTION的加载地址lma,如LOADADDR(.rodata),表示rodata段的加载地址。即,表示rodata段在flash中的地址。 SIZEOF(),用于求SECTION的大小 整个SECTIONS,可以看做是程序在flash中的布局,其中.bss不占用flash空间,它是由程序中开始运行时,在sram中开辟空间并初始化为0。 各个SECTION,如.vectors.text.rodata.data.bss,分别存放不同类型的数据。
3.如何复制data段到sram,如图:
4.初始化bss段,如图:
5.用C语言编写的led程序,主要是了解C语言中的全局变量,局部变量放在哪里。如图:
6.从反汇编.list文件中可以看到,上面这些数据放在什么地方,如图:
7.led.h头文件定义了寄存器,如图:
本质就是C语言中的指针操作,volatile作用是确保本条指令不会因编译器的优化而省略。如代码“RCC_APB2ENR |= 0x00000010;”,表示向寄存器的第4位(从0位开始计数)写1。
小结
本章主要了解硬件与软件之间关系,如,程序有多个section,他们有的放在flash中,有的放在sram中;程序有运行地址vma和加载地址lma,所以下载程序时要将程序下载到对应的加载地址上的,程序运行时需要将程序放到正确的运行地址上。源代码已分享,可自行下载编译调试,通过调试程序,观察程序如何在flash和sram上运行。如,通过gdb的调试指令,可以查看局部变量h的值。