第二季-专题6-点亮指路灯

专题6-点亮指路灯

1. LED原理图分析

在嵌入式系统软件(bootloader, kernel)开发初期,由于串口等硬件尚未被初始化,因此调试手段相当有限,这时通常会采用LED来作为程序调试的重要手段。

 

       左边的图是低电平导通,右边的图是高电平导通。

       LED的引脚究竟接在哪里是依靠核心板的电路图来识别的,依靠核心板的GPIO到底是接在哪里来判断的。

2. GPIO

GPIO(General-Purpose Input/Output Ports)通用输入/输出端口。在嵌入式系统中, CPU经常需要控制许多结构简单的外部设备或者电路,这些设备通常只要求两种状态(开/关), 对这些设备的控制,使用传统的串口或者USB口就显得复杂,所以,在嵌入式微处理器上通常提供了一种“通用可编程I/O端口”,也就是GPIO。

一个GPIO端口至少需要两个寄存器,一个是“控制寄存器”,用于选择该端口作为输入还是输出。另一个是存放数据的”数据寄存器”。

s3c2440有130个IO引脚,分成了A-J一共9个组;6410有187个IO引脚,被分成了A-Q一共17个组

3. 设计流程

(1)设置GPIO控制寄存器,把引脚设置为输出功能

(2)根据原理图设置GPIO数据寄存器,点亮LED

4. 写代码

TQ2440:

在TQ210的电路原理图上,可以观测到它的LED启动方式的低电平启动,对应的名称为nLED_1~nLED_4。接着我们打开TQ210的核心板原理图,搜索nLED_1~nLED_4,找到对应的引脚是GBD5~GPB8对应着10-17位,前10位可以都设置为0。

       打开2440的芯片手册,找到对应的GPB控制寄存器GPBCON,如下:

 

       GPBDAT寄存器,0-21对应0-11引脚:

 

代码:

在之前的start.s上做如下的修改:

reset:

       bl set_svc

       bl disable_watchdog

       bl disable_interrupt

       bl disable_mmu

       bl light_led

#define GPBCON 0x56000010  @控制寄存器

#define GPBDAT 0x56000014   @数据寄存器

light_led:

       ldr r0, =GPBCON     @控制寄存器

       ldr r1,=0x15400      @二进制的01 01 01 01 00 00 00 00 00

       str r1, [r0]           @将r1的值填到r0之中

      

       ldr r0, =GPBDAT      @数据寄存器

       ldr r1,=0x6BF         @二进制的1 10 10 11 11 11 

       str r1, [r0]            @将r1的值填到r0之中

       mov pc, lr            @返回

       在2440上按要求连接,输入命令/home/dnw ./gboot.bin 0X30000000,关闭电源,将开发板设置从nand flash启动,发现连个量,两个是熄灭的。

Tiny6410:

       打开它的核心板原理图,可以看到它的二极管是低电平点亮。LED1-LED4分别连GPK4-GPK7引脚。

 

       两个寄存器完成控制,一个寄存器完成数据。GPK这组一共有16个脚,一组控制寄存器需要4位控制一个,也就是需要2组控制寄存器。

       控制寄存器,我们需要操作的是GPK4-GKP7,如下:

 

       数据寄存器,设置两个量,两个灭,每一位控制一个灯

 

代码:

reset:

       bl set_svc

       bl disable_watchdog

       bl disable_interrupt

       bl disable_mmu

       bl light_led

#define GPKCON 0x7f008800  @控制寄存器

#define GPKDAT 0x7f008808   @数据寄存器

light_led:

       ldr r0, =GPKCON     @控制寄存器

       ldr r1,=0x11110000   @二进制的0001 0001 0001 0001 0000 0000 0000 0000

       str r1, [r0]           @将r1的值填到r0之中

      

       ldr r0, =GPKDAT      @数据寄存器

       ldr r1,=0xa0          @二进制的1010 0000,4-7一个量一个灭 

       str r1, [r0]            @将r1的值填到r0之中

       mov pc, lr            @返回

       下载命令/home/dnw ./gboot.bin 0x50000000,发现在6410中的4盏灯都没有亮。原因是在6410的初始化过程需要进行“外设基地址初始化”,这就是我们需要补齐的。

专题6补充-外设基地址初始化(6410)

       打开ARM11核的手册,搜索CP15,对应的是c15 0 c2 4显示:

 

       在page3-130,显示:

      

       在6410中的PC15的基地址是:

 

代码改成:

reset:

       bl set_svc

       bl set_peri_port                 @转到外设基地址

       bl disable_watchdog

       bl disable_interrupt

       bl disable_mmu

       bl light_led

set_peri_port:

       ldr r0, =0x70000000            @外设基地址开始处

       orr r0, r0, #0x13                @对应的256M,对应数字b10100

       mcr p15,0,r0,c15,c2,4           @写回pc15寄存器

       mov pc, lr

TQ210开发板(V4):

 

       LED的原理图显示它是高电平点亮。

       TQ210有237个GPIO引脚,分成了很多组,我们用到的是GPC0和GPC1组。

GPC0组的控制寄存器地址是0xE0200060,GPC0DAT寄存器地址是0xE0200064。

我们用到GPC0的第3位和第4位,控制方式如下:

 

       对应的数据寄存器值的选定表如下,前三位都是0,led高电平工作,3-4位为1:

 

代码:

reset:

        bl set_svc

        bl disable_watchdog

        bl disable_interrupt

        bl disable_mmu

        bl light_led

light_led:

    ldr     R0,=0xE0200060     @设置控制寄存器                     

    ldr     R1,=0x11000        @控制数据寄存器值,二进制为0001 0001 0000 0000 0000

    str     R1,[R0]            

    ldr     R0,=0xE0200064      @设置数据寄存器

    ldr     R1,=0x00000018      @设置数据寄存器的值,二进制位11000

    str     R1,[R0]

    mov pc, lr

       执行make后,进行210文件加头,运行./mkv210 gboot.bin gboot-210.bin,使用命令

./home/dnw gboot-210.bin 0xc0008000。发现led的程序没有亮。

       检查发现,所有的步骤都没有遗漏,点灯程序也正确。为了检测究竟是哪里出的错误,间点灯程序上移动,检查是否是其他的初始化程序出现了问题,最终发现是mmu的关闭程序出现了问题。

       打开cotex_a8核心手册,在147页,如下:

 

       在之前的2440和6410中的Icache和Dcache的初始化语句都是mcr p15,0,r0,c7,c7,0

但是在210中是没有的,Icache初始化是:mcr p15,0,r0,c7,c5,0,Dcache的初始化语句是:

mcr p15,0,r0,c7,c6,1。改写TQ210的mmu初始化位置:

disable_mmu:

    mcr p15,0,r0,c7,c5,0

    mcr p15,0,r0,c7,c6,1

    mrc p15,0,r0,c1,c0,0

    bic r0, r0, #0x00000007

    mcr p15,0,r0,c1,c0,0

    mov pc, lr

    这样在编译就通过了,显示正确的结果。

猜你喜欢

转载自www.cnblogs.com/free-1122/p/11452012.html