嵌入式编程中,需要预先设置好的东西比较多,在初学嵌入式时,经常发现在看完某方面文档后,仍然编写出的程序达不到预定效果,在学习更多知识后才会了解,原来还有一些特殊方面需要提前设置好。因此,本文作为裸机程序编写第一篇,介绍一下之后使用的程序模板。这个模板力求精简,发挥最基础的作用。主要包含以下文件:
github地址:https://github.com/EleVenPerfect/S3C2440/tree/master/none-OS/
1.head.s
head.s是整个程序的最最前面的程序,它以汇编语言编写,负责设置堆栈、设置系统时钟、设置内存、关闭看门狗等作用,在最后它引导程序进入main函数,开始执行main中的程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| @****************************************************************************** @ File:head.S @ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行 @****************************************************************************** .extern main .text .global _start _start: Reset: ldr sp, =4096 @ 设置栈指针,以下都是C函数,调用前需要设好栈 bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启 // bl是位置无关码,相当于:PCnew = PC + 偏移 // PCnew = (4+8) + 0x28 = 0x34 //ldr pc, =disable_watch_dog /* 这样写将出错 */ bl clock_init @ 设置MPLL,改变FCLK、HCLK、PCLK bl memsetup @ 设置存储控制器以使用SDRAM bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中 ldr pc, =on_sdram @ 跳到SDRAM中继续执行 on_sdram: ldr sp, =0x34000000 @ 设置栈指针 ldr lr, =halt_loop @ 设置返回地址 ldr pc, =main @ 调用main函数 halt_loop: b halt_loop
|
2.init.c
在head.s中,我们看到,有直接跳转函数的代码,这部分在init.c内,是以c语言编写的负责实际完成关闭看门狗、设置内存、设置系统时钟、将程序复制到内存的。至于为什么不在head.s中实现,因为很多操作相对复杂,用C更便捷吧。它的源码较长,可以在我的github上查看。
需要注意的是,我的内存初始化代码适用于TQ2440开发板的内存,对于不同的内存芯片,需要修改参数。
3.mian.c
通常学习过编程的人都知道,main.c是整个程序的开始,这个模板也不例外,在完成最初级的设置后,程序跳转到main.c开始执行用户代码。
4.Makefile
Makefile是这个项目的负责编译控制的文件,在gcc下,通过使用Makefile可以使用make命令直接将程序编译成开发板需要的镜像文件。
同时,可以自定义其他指令,如模板文件中,定义了make clean命令,负责删除编译生成的文件,便于重新编译。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| objs := head.o init.o serial.o main.o
000.bin: $(objs) arm-linux-ld -Ttext 0x000000 -o timer_elf $^ arm-linux-objcopy -O binary -S timer_elf $@ arm-linux-objdump -D -m arm timer_elf > timer.dis %.o:%.c arm-linux-gcc -Wall -nostdlib -O2 -c -o $@ $<
%.o:%.S arm-linux-gcc -Wall -nostdlib -O2 -c -o $@ $<
clean: rm -f timer.bin timer_elf timer.dis *.o
|
同时,可以自定义其他指令,如模板文件中,定义了make clean命令,负责删除编译生成的文件,便于重新编译。
5.S3C2440.h
S3C2440.h文件负责定义S3C2440处理器的各个寄存器地址,这样在编程中就不需要查看某个寄存器的地址,直接使用名称来表示。
还有为方便调试,预先编写好的串口程序,可作为程序的调试工具。在程序出现问题是,可通过串口打印数据判断错误原因。
欢迎关注我的公众号,和我一起学习嵌入式知识。