如何使用嵌入式C启动ARM Cortex编程?
我熟悉8051C编程。现在我想学习ARM编程。我有带ARM Cortex M3处理器的STM32F103C8T6开发板,它是程序员和Keil编译器。我想用它做一些小项目,例如闪烁LED、SPI和I2C编程等。我对ARM架构知之甚少。许多人在博客上说,直接开始编程,而不是阅读架构或数百页的ARM数据表。我不明白这怎么可能 那么,我的第一步应该是什么如何使用嵌入式C启动ARM Cortex编程?,c,arm,embedded,C,Arm,Embedded,我熟悉8051C编程。现在我想学习ARM编程。我有带ARM Cortex M3处理器的STM32F103C8T6开发板,它是程序员和Keil编译器。我想用它做一些小项目,例如闪烁LED、SPI和I2C编程等。我对ARM架构知之甚少。许多人在博客上说,直接开始编程,而不是阅读架构或数百页的ARM数据表。我不明白这怎么可能 那么,我的第一步应该是什么 我应该阅读STM32F103C8T6或ARM Cortex M3用户手册的数据表吗 8051与ARM编程有很大区别。在8051中,我们不需要添加库/头
我去过那里,过了一段时间,我意识到最好从数据表开始,即使它是您的第一块板 数据表提供了电路板、引脚和基本通信的全面工作。这可能是乏味的,但它是值得的,当你开始编程时,你会意识到这一点 之后,您可以直接跳转到头文件,并查看基本功能的实现,这将提供有关优化技术、编程风格和最佳实践的许多见解 如果可能的话,找到更多为该板编写的代码(我在这里总是失败,如果你的板很少,那就很难了) 有了这一点,您应该准备好编写几乎所有的代码。从blinky(董事会的hello world)开始
根据我的经验,我想告诉你,如果需要时间,也没关系。要有耐心和毅力 作为一名C程序员,您不需要阅读CPU核心体系结构,尽管我建议您简要阅读一下CPU手册。知道有哪些寄存器和资源、数据缓存、指令缓存等,意味着您可以编写更高质量的C代码。然而,对于像8051这样糟糕的内核,这一点要重要得多 至于MCU外围硬件和内存,您确实需要阅读手册中的每一行,了解您打算使用的部件。这包括看门狗、时钟设置、MMU、中断处理等基础知识 然而,现在大多数用于MCU:s的工具链都带有某种形式的糖衣库。他们会给你一个工作项目,大部分事情都安排好了。这意味着你不必一下子就学会所有的东西,但随着项目的进行,你可以一点一点地学会。例如,要使某些指示灯闪烁,您应该能够做到这一点,而无需阅读手册中的GPIO部分 您可能最终不得不用高质量的代码替换预先制作的quick&dirty库。这是因为提供这些库的硅制造商在编写软件方面出了名的差劲。在某些情况下,它们会设法为您提供适当的MCU设置代码,但更多情况下,它们会为您提供低质量的代码 大概是MCU设置的样子。您可以使用该列表来验证从制造商处获得的信息是否有用,或者是否需要由专业嵌入式程序员重写。例如,ARM CMSIS可能足够好,也可能不够好,这取决于应用要求。它也有不同的风格,这取决于工具链。如果您使用现有的库代码来处理架构、启动和外围驱动程序问题,则有可能(即在不详细了解数据表和参考手册的情况下启动)。对于ARM Cortex-M和STM32,具体而言,可能包括(在不同的抽象和范围级别):
- ,
- ,
- ,
- 李>
interface jlink
transport select swd
interface hla
hla_layout stlink
hla_device_desc "ST-LINK/V2"
hla_vid_pid 0x0483 0x3748
openocd -f jlink.cfg -f target.cfg
@.cpu cortex-m0
@.cpu cortex-m3
.thumb
.thumb_func
.global _start
_start:
ldr r0,=0x20001000
mov sp,r0
bl notmain
b hang
.thumb_func
hang: b .
.thumb_func
.globl PUT32
PUT32:
str r1,[r0]
bx lr
.thumb_func
.globl GET32
GET32:
ldr r0,[r0]
bx lr
.thumb_func
.globl dummy
dummy:
bx lr
void PUT32 ( unsigned int, unsigned int );
unsigned int GET32 ( unsigned int );
void dummy ( unsigned int );
#define GPIOCBASE 0x40011000
#define RCCBASE 0x40021000
int notmain ( void )
{
unsigned int ra;
unsigned int rx;
ra=GET32(RCCBASE+0x18);
ra|=1<<4; //enable port c
PUT32(RCCBASE+0x18,ra);
//config
ra=GET32(GPIOCBASE+0x04);
ra&=~(3<<20); //PC13
ra|=1<<20; //PC13
ra&=~(3<<22); //PC13
ra|=0<<22; //PC13
PUT32(GPIOCBASE+0x04,ra);
for(rx=0;;rx++)
{
PUT32(GPIOCBASE+0x10,1<<(13+0));
for(ra=0;ra<400000;ra++) dummy(ra);
PUT32(GPIOCBASE+0x10,1<<(13+16));
for(ra=0;ra<400000;ra++) dummy(ra);
}
return(0);
}
for(x=0;x<0x80000;x++) continue;
MEMORY
{
ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > ram
.rodata : { *(.rodata*) } > ram
.bss : { *(.bss*) } > ram
}
arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 sram.s -o sram.o
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -mcpu=cortex-m0 -march=armv6-m -mthumb -c blinker01.c -o blinker01.o
arm-none-eabi-ld -o blinker01.elf -T sram.ld sram.o blinker01.o
arm-none-eabi-objdump -D blinker01.elf > blinker01.list
arm-none-eabi-objcopy blinker01.elf blinker01.bin -O binary
20000000 <_start>:
20000000: 4805 ldr r0, [pc, #20] ; (20000018 <dummy+0x4>)
20000002: 4685 mov sp, r0
20000004: f000 f80a bl 2000001c <notmain>
20000008: e7ff b.n 2000000a <hang>
2000000a <hang>:
2000000a: e7fe b.n 2000000a <hang>
2000000c <PUT32>:
openocd -f jlink.cfg -f target.cfg
Open On-Chip Debugger 0.10.0-dev-00325-g12e4a2a (2016-07-05-23:15)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
swd
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
none separate
cortex_m reset_config sysresetreq
Info : No device selected, using first device.
Info : J-Link ARM-OB STM32 compiled Jun 30 2009 11:14:15
Info : Hardware version: 7.00
Info : VTarget = 3.300 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x1ba01477
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
>
> halt
stm32f1x.cpu: target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000042 msp: 0x20001000
>
> load_image sram/blinker01.elf
144 bytes written at address 0x20000000
downloaded 144 bytes in 0.008081s (17.402 KiB/s)
> resume 0x20000000
>
@.cpu cortex-m0
@.cpu cortex-m3
.thumb
.thumb_func
.global _start
_start:
stacktop: .word 0x20001000
.word reset
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.thumb_func
reset:
bl notmain
b hang
.thumb_func
hang: b .
.thumb_func
.globl PUT32
PUT32:
str r1,[r0]
bx lr
.thumb_func
.globl GET32
GET32:
ldr r0,[r0]
bx lr
.thumb_func
.globl dummy
dummy:
bx lr
MEMORY
{
rom : ORIGIN = 0x08000000, LENGTH = 0x1000
ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > rom
.rodata : { *(.rodata*) } > rom
.bss : { *(.bss*) } > ram
}
for(rx=0;;rx++)
{
PUT32(GPIOCBASE+0x10,1<<(13+0));
for(ra=0;ra<200000;ra++) dummy(ra);
PUT32(GPIOCBASE+0x10,1<<(13+16));
for(ra=0;ra<200000;ra++) dummy(ra);
}
arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 flash.s -o flash.o
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -mcpu=cortex-m0 -march=armv6-m -mthumb -c blinker01.c -o blinker01.o
arm-none-eabi-ld -o blinker01.elf -T flash.ld flash.o blinker01.o
arm-none-eabi-objdump -D blinker01.elf > blinker01.list
arm-none-eabi-objcopy blinker01.elf blinker01.bin -O binary
Disassembly of section .text:
08000000 <_start>:
8000000: 20001000 andcs r1, r0, r0
8000004: 08000041 stmdaeq r0, {r0, r6}
8000008: 08000047 stmdaeq r0, {r0, r1, r2, r6}
800000c: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000010: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000014: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000018: 08000047 stmdaeq r0, {r0, r1, r2, r6}
800001c: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000020: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000024: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000028: 08000047 stmdaeq r0, {r0, r1, r2, r6}
800002c: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000030: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000034: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000038: 08000047 stmdaeq r0, {r0, r1, r2, r6}
800003c: 08000047 stmdaeq r0, {r0, r1, r2, r6}
08000040 <reset>:
8000040: f000 f808 bl 8000054 <notmain>
8000044: e7ff b.n 8000046 <hang>
08000046 <hang>:
8000046: e7fe b.n 8000046 <hang>
> halt
stm32f1x.cpu: target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x20000014 msp: 0x20000ff0
> flash write_image erase blinker01.elf
auto erase enabled
device id = 0x20036410
flash size = 64kbytes
wrote 1024 bytes from file blinker01.elf in 0.437904s (2.284 KiB/s)
>
stm32x device protected
failed erasing sectors 0 to 0
> reset