• 迅为2K1000龙芯开发板pmon 下操作 GPIO


    我们可以来学习如何在 pmon 下操作 gpio 了, 为什么要把这个需求单独拿出来讲呢? 因为有的时候我们做了一款产品, 在特定的环境下需要让 GPIO 在上电时就是就保证是一个确定的电平, 如高电平或者低电平。 Uboot 上这些资料非常的多, 所以我们别的板子对于这个需求就没单独拿出来给大家讲, 但是龙芯用的是 pmon, pmon 上相关的资料太少了, 所以有必要单独作为一章给大家讲解。

    平台:迅为i.TOP-2K1000开发板

    CPU:国产龙芯处理器,双核64位系统,板载2G DDR3内存,

    系统支持:busybox,buiroot,Loognix,qt


    在 pmon 下控制 GPIO 有俩种方法, 这里以开发板上的 led3 给大家举例, 一种方法是在 c 语言环境建立之前来控制, 另一种方法是在 c 语言环境建立以后来控制。 我们分别来看一下这俩种方法。

    1 软硬件分析
    这里以开发板上的 led3 给大家举例, 我们打开开发板的底板原理图, 找到 led3 的电路, 如下图所示:

     

    通过硬件电路图我们可以发现, 当 LS2K_GPIO0 管脚输出为高电平时, Led3 发光, 反之则不发光。 我们查阅数据手册得知, 龙芯 2K1000 共有 60 个 GPIO 引脚, 4 个为专用 GPIO, 其余 56 个与其他功能复用。

    开发板上 Led3 连接的管脚为 GPIO0, 其中 GPIO0~GPIO3 为专用 GPIO 管脚, 所以不需要设置复用, 如下图所示。 注意! 如果你用的不是专用 GPIO 引脚, 则需要设置复用关系!

     

    如果要操作一个 GPIO, 我们光知道他的复用关系还不行, 我们还要操作 GPIO 的方向寄存器以及数据寄存器,通过查阅数据手册, 我们发现 LS2K 的 GPIO 的方向寄存器的地址为 0x1fe10500, 数据寄存器的地址为0x1fe10510, 如下图所示:

     

    方向寄存器描述:

    通过上图我们可以发现, 如果为 0, 则 GPIO 的方向为输入, 反之则为输出。 0 到 63 分别对应 60 个 GPIO。数据寄存器描述:

     

    通过上图我们可以发现, 如果为 0, 则 GPIO 输出低电平, 反之则为输高电平。 0 到 63 分别对应 60 个 GPIO。

    2 通过 C 控制 GPIO

    2.1 编写驱动程序
    首先我们使用命令 cd Targets/LS2K/dev 进到 pmon 的 Targets/LS2K/dev 目录, 在这个目录下放的是和 LS2K相关的驱动代码, 如下图所示:

     

    然后我们这个这个目录下使用命令 vim topeet_led.c 创建一个 c 程序, 并输入以下代码:

    #include <stdio.h>
    /*
    * 初始化 led3 管脚
    */
    void led3_init(void)
    {
    *(volatile int *)0xbfe10500 &= ~(0x01); //设置方向为输出
    *(volatile int *)0xbfe10510 &= ~(0x01); //默认输出低电平
    printf("led3 init!\n");
    } /
    *
    * 点亮 led3
    */
    void led3_on(void)
    {
    *(volatile int *)0xbfe10510 |= 0x01; //输出高电平
    printf("led3 on!\n");
    } /
    *
    * 熄灭 led3
    */
    void led3_off(void)
    {

    *(volatile int *)0xbfe10510 &= ~(0x01); //输出低电平
    printf("led3 off!\n");
    }

    为什么这里的我们操作的地址是 0xbfe10500 和 0xbfe10510 而不是我们在上一小节所说的 0x1fe10500和 0x1fe10510 呢, 因为系统上电启动后, 任何 MIPS 架构的 CPU 都是从系统的虚拟地址 0xbfc00000 启动的,其对应的物理地址为 0x1FC00000, 所以这里我们操作的是 0x1fe10500 和 0x1fe10510 对应的虚拟地址0xbfe10500 和 0xbfe10510。创建完成后如下图所示:

     

    2.2 添加编译规则
    接下来就是要把我们添加的这个 C 程序编译到 pmon 里面, 这个要如何添加呢, 如果大家看了第 9.3 小节, 我相信大家一定知道要怎么做了。我们进到 pmon 源码下的 argets/LS2K/conf 文件夹,

    然后使用命令 vim files.LS2K 打开配置文件, 并在配置文件的最下面添加以下代码
    file Targets/LS2K/dev/topeet_led.c如下图所示:

     

    2.3 控制 led
    在 9.4 小节, 我们分析了 pmon 的启动流程, 最终会在 Targets/LS2K/ls2k/tgt_machdep.c 下的 c 文件里面的 initmips 函数初始化外设, 所以我们是不是只要在这里调用我们写的 C 程序就可以了呢。
    我们打开 Targets/LS2K/ls2k/tgt_machdep.c 文件, 在 initmips 函数里面添加以下代码:

    led3_init();
    int j=3;
    while(j--)
    {
    led3_on();
    delay(1000000);
    led3_off();
    delay(1000000);
    }

    如下图所示:

     

    9.6.2.4 编译验证
    我们将编译好的 pmon 烧写到开发板, 观察 led3 的现象, 可以发现在 pmon 启动的时候 led3 会闪烁 3次, 说明我们在 pmon 下控制 led 成功, 同时可以在控制终端看到如下打印, 如下图所示:

     

    至此, 通过 C 控制 GPIO 完成。如大家没有成功点亮, 可以参考手册 9.7.6 章节使用 Ejtag 单步调试 pmon。

    3 通过汇编控制 GPIO
    上一小节, 我们使用了 C 语言控制了 gpio, 这一小节我们来看一下如何使用汇编来控制 gpio 呢? 有的同学可能会有疑问了, 既然我们可以使用 C 语言来控制 gpio, 为什么我们还要使用更底层的汇编语言呢,如果我们要使用 C 语言, 是不是需要等待 C 语言环境建立起来才可以使用呢, 那他是不是就要比汇编稍微的慢一些呢, 如果我们想让他上电立马就确定 gpio 管脚的电平的状态, 使用汇编会更好些。
    我们打开 Targets/LS2K/ls2k/start.S 下的 start.S 文件, 我们在 9.4.2 小节里面已经确定了他的位置, 这里就不在赘述了。
    然后我们在第 487 行输入以下代码, 同样, 这里还是用 gpio0 给大家举例
    /*
    *设置使用 GPIO 的方向为输出
    */
    li v0, 0xbfe10500
    ld v1, (v0)
    dli a0, (1<<0) //gpio0
    or v1, a0
    xor v1, a0
    sd v1, (v0)
    /*
    *找到 GPIO 输出数据寄存器
    */
    //0x10(v0)这种写法就是给 v0 地址偏移 0x10,v0 地址是 0xbfe10500,偏移 0x10 就是 0xbfe10510,即
    输出数据寄存器
    ld v1, 0x10(v0)
    /*
    *给数据寄存器写 1 输出高电平
    */
    or v1, a0
    sd v1, 0x10(v0) //on
    /*
    *延迟
    */
    dli a2,0xffff //delay
    1:
    subu a2, 0x1

    nop
    bgtz a2, 1b
    /*
    *给数据寄存器写 0 输出低电平
    */
    or v1, a0

    xor v1, a0  //off

     

    sd v1, 0x10(v0)

    /*
    *延迟
    */
    dli a2,0xffff //delay
    2:
    subu a2, 0x1
    nop
    bgtz a2, 2b
    如下图所示:

     

    汇编程序的思路同 C 语言一下, 同样第一步也是先设置 gpio 的复用以及方向, 如果是专用 gpio 则不用设置复用关系。 第二步则是设置 gpio 输出的高低电平。 只不过现在我们是用汇编来完成这个操作, 如大家对汇编指令不是很清楚, 可以参考资料中的龙芯架构参考手册, 位置: LS2K1000 开发板资料\07_第三方库以其他参考资料\01_其他参考资料我们将编译好的 pmon 镜像烧写开发板, 开机上电会可以观察到开发板立刻闪烁一下, 闪烁完以后串口终端才有打印信息出现。
    如大家没有成功点亮, 可以参考手册 9.7.5 章节使用 Ejtag 单步调试 pmon。

  • 相关阅读:
    Typescript类、命名空间、模块
    TypeScript 基础类型、变量声明、函数、联合类型、接口
    JS中的单线程与多线程、事件循环与消息队列、宏任务与微任务
    wangEditor上传本地视频
    java版excel转pdf,word转pdf
    idea2019.3 没有 Autoscroll from Source
    mysql 实现类似oracle函数bitand功能
    spring boot 配置文件动态更新原理 以Nacos为例
    spring boot 发布自动生成svn版本号
    spring boot JPA 数据库连接池释放
  • 原文地址:https://www.cnblogs.com/topeet/p/16337467.html
Copyright © 2020-2023  润新知