• 第二季-专题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

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

  • 相关阅读:
    Java 内部类理解
    Java 抽象类和接口的理解
    Java String 和 new String()的区别
    Java 基本类型和对象类型的区别
    Java对象与对象引用变量的理解
    bash: crontab: command not found
    Linux下压缩某个文件夹命令
    爬虫实战项目二、字体反爬
    Pandas学习之四:修改增加
    Pandas库学习之三:处理元素
  • 原文地址:https://www.cnblogs.com/free-1122/p/11452012.html
Copyright © 2020-2023  润新知