第1个裸板程序(S3C2440)

第一个程序只能是汇编,以前写单片机程序,用到 IAR、MDK等,一上来就写main()函数,那是编译器帮你封装好了。

目标:点亮LED1

有两种方法:(1)只写一个汇编文件makefile
(2)写一个汇编文件作为启动文件,再写个c文件,和makefile

裸机开发步骤
1. 查看原理图
2. 查看数据手册
3. 写程序

1.查看原理图
第1个裸板程序(S3C2440)_第1张图片

第1个裸板程序(S3C2440)_第2张图片
由原理图得知,LED1连接S3C2440的GPF4引脚。当GPF4设置为输出模式,且输出低电平时,LED1被点亮。

2.查看数据手册
第1个裸板程序(S3C2440)_第3张图片
需要配置GPFCON寄存器和GPFDAT寄存器。
注意,这些寄存器和R0–R12、SP、LR、PC、CPSR不同。
R0–R12、SP、LR、PC、CPSR属于内部寄存器,CPU可以直接访问。
类似于GPFCON等寄存器,CPU只能通过寻址的方式访问(这些寄存器和内存是统一编址的)。
所以,要使LED1点亮,1、要往地址为0x56000050的地方存放0x100,设置GPF4位输出模式。2、往地址为0x56000054的地方存放0,设置GPF4输出低电平。

3.写程序

(1)只写一个汇编文件makefile

/*
 *文件名:led_on.S
 *功能:点亮LED
 */


.text
.global _start

_start:

	ldr r0, =0x56000050
	ldr r1, =0x100
	str r1, [r0]				/* 要往地址为0x56000050的地方存放0x100,设置GPF4位输出模式 */

	ldr r0, =0x56000054
	ldr r1, =0
	str r1, [r0]					/* 往地址为0x56000054的地方存放0,设置GPF4输出低电平 */


halt:			/* 死循环 */
	b halt

makefile文件

all:
	arm-linux-gcc -c -o led_on.o led_on.S
	arm-linux-ld -Ttext 0 led_on.o -o led_on.elf
	arm-linux-objcopy -O binary -S led_on.elf led_on.bin
	arm-linux-objdump -D led_on.elf > led_on.dis
clean:
	rm *.bin *.o *.elf

分析:
.text .global 是arm-gcc编译器的关键词。
.text部分是处理器开始执行代码的地方,指定了后续编译出来的内容放在代码段【可执行】。
.global关键字用来让一个符号对链接器可见,可以供其他链接对象模块使用;告诉编译器后续跟的是一个全局可见的名字【变量/函数名】
.global _start让_start符号成为可见的标识符,这样链接器就知道跳转到程序中的什么地方并开始执行程序。

makefile文件的作用就是把arm-linux-gcc的编译、汇编、链接等命令组合起来,在linux系统中,不用挨个执行编译、汇编、链接命令,只需输入make即可。

(2)写一个汇编文件作为启动文件,再写个c文件,和makefile

/*
 *文件名:start.S
 *功能:设置栈、跳转到c文件中的main()函数执行。
 */
 
.text
.global _start

_start:

	ldr sp, =4096			/* NAND启动 */
	
	bl main					/* 跳转到main()执行 */
	
halt:
	b halt						/* 死循环 */

c文件

int main(void)
{
	unsigned int *pGPFCON = (unsigned int *)0x56000050;
	unsigned int *pGPFDAT = (unsigned int *)0x56000054;
	
	*pGPFCON = 0x400;		/* led 配置为输出模式 */
	*pGPFDAT = 0;			/* led 设置为点亮状态 */
	
	return 0;
}

makefile文件

all:
	arm-linux-gcc -c -o led.o led.c
	arm-linux-gcc -c -o start.o start.S
	arm-linux-ld -Ttext 0 start.o led.o -o led.elf
	arm-linux-objcopy -O binary -S led.elf led.bin
	arm-linux-objdump -D led.elf > led.dis
clean:
	rm *.bin *.o *.elf *.dis

分析:
start.S中设置堆栈、跳转到main()函数执行。

  1. 为什么设置堆栈? 答:因为C函数要用。
  2. 怎么使用栈? 答:a.保存局部变量 b.保存lr等寄存器
  3. 为什么要设置栈地址为4096?
    答:先从S3C2440的启动方式说起
    S3C2440启动流程:
    Nor启动
    Nor Flash的基地址为0,片内RAM地址为0x4000 0000;
    CPU读出Nor上第1个指令(前4字节),执行;
    CPU继续读出其它指令执行。
    Nand启动
    片内4k RAM基地址为0,Nor Flash不可访问;
    2440硬件把Nand前4K内容复制到片内的RAM,然后CPU从0地址取出第1条指令执行。

一般把堆栈放在片内RAM中。
若设置为Nand启动,片内RAM的基地址为0,把堆栈地址设置为片内4k RAM的最大地址4096,堆栈从4096开始往低地址方向存储,即sp = sp - 4;
若设置为Nor启动,片内RAM的基地址为0x4000 0000,则把堆栈地址设置为片内4k RAM的最大地址0x4000 0000+4096,堆栈开始往低地址方向存储,即sp = sp - 4;

编译,烧录
(1)把方法1和方法2对应的文件放在相应文件夹中(即led_on.S和makefile放一个文件夹;startr.S、led.c、makefile放一个文件夹)
(2)打开Ubuntu9.10和FileZilla
(3)通过FileZilla,把两个文件夹复制到Ubuntu9.10
(4)在Ubuntu9.10中,执行make命令来编译生成.bin文件
(5)再通过FileZilla,把编译生成的.bin文件复制到windows系统中
(6)打开cmd,用oflash+eop把.bin文件烧录到Nand
(7)设置Nand启动,重启开发板。
(8)观察LED1

你可能感兴趣的:(ARM裸机,(JZ2440))