第3课: 点亮开发板led灯
我们写的程序分成2种:
无操作系统的直接驱动
有操作系统的写出设备驱动
以下介绍下主要的设备:
1外部存储控制器 发送复杂的时序信号来控制SDRAM,有了它就比较方便扩展SDRAM
2LCD controller 工作在800X480
3 4个DMA通道 3个串口通道
4 2个SPI 串行数据接口(我们的板子无) IIC总线(板子上无)
5 2种音频总线IIS音频与AC97音频
6支持SD MMC
7 2个USB接口,1个USB控制器
8 4个PWM定时器,1个内部定时器,看门狗定时器
9 8个10bit的ADC模拟信号转换
10 RTC日历功能
11 camera 功能
12 130个i/o管脚 24个外部中断源
13电源控制(normal slow idle slepp )
14我们板子上有独立网卡芯片控制RJ45
2440比2410多了camera与ac97
cp15控制MMU和cache
AHB高速设备
============
APB低速设备
2440内部有个功能可以单独关闭某个外设
我们是通过控制特殊的寄存器来控制外设的。
下面来看第一个 130个I/O管脚(pin)
共有9组 从GPA到GPJ(见数据手册274页)
有9个配置寄存器GPACON~GPJCON
有9个内容寄存器GPADAT~GPJDAT
我们写的led灯是GPE12和GPE13这2个引脚控制的两个灯。
根据数据手册来看,CPECON控制的引脚是可以复用的,工具GPECON中设置的值来改变它的功能,它可以是I/O port功能也可以是其他功能。
在这里我们要点亮灯,就要让GPECON设置到out port。然后改变CPEDAT中的数据到0.可以点亮灯。当GPEDAT中的响应位为地位时,由于和高位产生电压差从而产生电流,点亮灯泡。如果要熄灭灯的话,就把GPEDAT相应位置1.
以下用汇编和C各写一个LED2个灯闪烁的驱动。
.text
.global _start
delay:@这个是延迟程序,闪烁当中的间隔
nop
nop
nop
subs r4,r4,#1
bne delay
movpc,lr
_start:
ldr r0,=0x56000040 @r0 = GPECONs address
ldr r1,=0x5000000
str r1,[r0] @set GPECON register
ldr r0,=0x56000044 @r0 = GPEDATs address
movr2,#10 @set the times of loop
ldr r3,=0x3000 @r3 is the mask to turn off led
mov r1,#0
loop:
strr1,[r0] @亮灯,把GPEDAT相应位置0
ldrr4,=0x500000
bldelay
strr3,[r0] @灭灯,把相应位置1
ldrr4,=0x500000
bldelay
subsr2,r2,#1
bneloop
haltloop: @如果程序不在最后一直循环的话将不能执行
bhaltloop
接下来就是写makefile
light.bin:light.o//要编译成light。bin 需要依赖.o
arm-linux-ld -Ttext 0x00000000 light.o -o light.elf //我们这里不写连接文件,而是用Ttext的形式,指定程序开始的段(text)
arm-linux-objcopy -O binary -S light.elf light.bin//把elf文件转化成2进制文件。正真的作用是定位地址和引入符号表。
arm-linux-objdump -D -b binary -m arm light.bin >light.dis //把light.bin反汇编,也可以把light.elf反汇编
light.o:light.s
arm-linux-gcc -c light.s -o light.o
clean:
rm -f light.o light.elf light.bin light.dis
之后我使用openjtag仿真枪,通过jtag口烧入内存0x0(因为连接文件定的入口在那)当然也可以通过网络下载等其他方法烧写内存SDRAM,不过没有jtag给力 =。=!。记得烧写的时候用arm920t cp15 2 0把mmu和i-cache关了,这个东西的使用件使用手册。
之后给出C程序的代码。C写起来比较方便。主张用C。我们写.h .c .s .lds makefile5个文件。其中crt0.s是用来引入C程序的。
.text
.globl _start
_start:
ldrr0, =0x53000000 @ WATCHDOG close
movr1, #0x0
strr1, [r0]
ldr sp, =1024*4 @set stack,but the capitcy of cache is only 4k
bl main @跳转到C的main符号入口
halt_loop:
b halt_loop
之后写头文件
#define GPECON (*(volatile unsigned int *)0x56000040) @volatile是用来让编译器不编译GPECON寄存器的,免得它被当初常量,它可是会变化的需要一直从寄存器中读取。
#define GPEDAT (*(volatile unsigned int *)0x56000044)
#define GPE12_out (1<(12*2))
#define GPE13_out (1<(13*2))
之后就是C文件
#include"led.h"
void wait(int time)
{
do{
time--;
}
while(time>0);
}
int main()
{
int i=10;
GPECON = GPE12_out|GPE13_out;
do{
GPEDAT = 0;
wait(300000);
GPEDAT = (3<12);
wait(300000);
i--;}
while(i>0);
return 0;
}
主程序写完后,开始写连接脚本lds文件。
SECTIONS {
. = 0x00;//从0x00开始作为入口
.text : { *(.text) }//段名称起名.text 内容是 所有的.text段
.rodata ALIGN(4) : {*(.rodata)}// ALIGN(4)4字节对齐
.data ALIGN(4) : { *(.data) }
.bss ALIGN(4) : { *(.bss) *(COMMON) }
}
来看下makefile
CFLAGS := -Wall -Wstrict-prototypes -g -fomit-fr
点亮开发板led 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)