jz2440 裸板程序的开发

前言

crt0.S 文件

@******************************************************************************
@ File:crt0.S
@ 功能:通过它转入C程序
@******************************************************************************

.text
.global _start
_start:
ldr r0, =0x53000000 @ WATCHDOG寄存器地址
mov r1, #0x0
str r1, [r0] @ 写入0,禁止WATCHDOG,否则CPU会不断重启

ldr sp, =1024*4 @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K
@ nand flash中的代码在复位后会移到内部ram中,此ram只有4K
bl main @ 调用C程序中的main函数
halt_loop:
b halt_loop

led.c 文件

/************************************
* 按下按钮, 就点亮对应的LED灯.
* KEY: EINT0, EINT2, EINT11
* KEY: GPF0, GPF2, GPG3
* LED: D12, D11, D10
* LED: GPF6, GPF5, GPF4
************************************
*/

// s3c2440 对应的寄存器地址. 需要看数据手册.
#define GPFCON (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
#define GPFUP (*(volatile unsigned long *)0x56000058)
#define GPGCON (*(volatile unsigned long *)0x56000060)
#define GPGDAT (*(volatile unsigned long *)0x56000064)
#define GPGUP (*(volatile unsigned long *)0x56000068)

#define PIN0 (1<<0)
#define PIN1 (1<<1)
#define PIN2 (1<<2)
#define PIN3 (1<<3)
#define PIN4 (1<<4)
#define PIN5 (1<<5)
#define PIN6 (1<<6)
#define PIN7 (1<<7)

int main()
{
GPFCON = 0x1500; // set LED pin as output
GPFDAT = 0x00;
GPGCON = 0x00;

while (1) {
if (GPFDAT & PIN0) {
GPFDAT |= PIN6;
} else {
GPFDAT &= ~PIN6;
}
if (GPFDAT & PIN2) {
GPFDAT |= PIN5;
} else {
GPFDAT &= ~PIN5;
}
if (GPGDAT & PIN3) {
GPFDAT |= PIN4;
} else {
GPFDAT &= ~PIN4;
}
}
return 0;
}

Makefile 文件

# 目标文件 : 依赖文件1 依赖文件2
led.bin : crt0.S led.c
# 汇编->目标文件
arm-linux-gcc -g -c -o crt0.o crt0.S
# C->汇编
arm-linux-gcc -g -c -o led.o led.c
# 目标文件链接为 led_elf, 初始地址为0
arm-linux-ld -Ttext 0x0000000 -g crt0.o led.o -o led_elf
# 用 led_elf文件生成 烧录文件 led.bin
arm-linux-objcopy -O binary -S led_elf led.bin
# 反汇编
arm-linux-objdump -D -m arm led_elf > led.dis

clean:
rm -f led.dis led.bin led_elf *.o

编译和烧录

  • 将上述三个文件放入同一个目录, 譬如 /led_test
    • crt0.S 可理解为硬件初始化, 使用模板即可
    • led.c 需要自己写, 软件的大部分开发工作用C语言实现
    • Makefile 写的非常直白的makefile, 不适用于复杂的工程.
  • 使用Linux主机进行编译.
    • 即登录 Ubuntu, 即配置好交叉编译环境的Linux主机
    • shell 下进入 /led_test 目录
    • 输入指令 make 即可, 就会得到 led.bin 文件
    • 清空编译和链接文件, 输入 make clean, 就相当于执行了 rm -f led.dis led.bin led_elf *.o
  • led.bin 烧录到 Flash 中, 最后重启开发板.
    • 有多种烧录方式, 我这边使用的是 JLINK, 用JFlash烧录即可 (只支持烧录 Nor Flash)
    • s3c2440 属于 ARM9 系列. 使用Nor Flash启动时, SRAM 起始地址为 0x4000_0000
    • 或者使用uboot+dnw的方式, 烧录到SDRAM中并运行
  • 然后, 如果开发的是嵌入式linux, 基本流程也是这样的 (注意区分两个Linux):
      1. 在电脑上开发软件 (Windows, Linux, Mac 随便的)
      1. Linux主机上进行编译(就是交叉编译), 获得一个可执行文件.
      1. 把可执行文件烧录/加载到**嵌入式Linux(开发板)**上, 运行即可.

原创于 DRA&PHO