查看: 813|回复: 0

【LeMaker Guitar】GoS500库 -- 2.GPIO

[复制链接]
  • TA的每日心情
    奋斗
    2022-9-16 05:52
  • 签到天数: 1368 天

    连续签到: 1 天

    [LV.10]以坛为家III

    发表于 2016-5-18 08:45:54 | 显示全部楼层 |阅读模式
    分享到:
    LeMaker Guitar不仅底板上引出了40个排针,可以外接很多设备,而且还提供了几种扩展板,每种扩展板侧重的功能不同。为了写底层程序,我选择了LN_IO,这个扩展板把多种接口分类设计,可以接GPIO、UART、SPI、IIC、LCD等设备,而且板载了8个LED,非常方便做试验,所以后面的程序主要以这个扩展板来演示。

        众所周知,Linux的用户层的程序是不能直接操作寄存器的,如果想通过各种寄存器来完成某种功能只能通过编译内核程序来实现。然而编译内核程序很是麻烦,必须下载对应版本的内核源代码,然后再用C来写程序,非常不方便调试,很容易出错,所以UIO就是为了解决这些问题。当然UIO也不是万能的,和直接写驱动程序各有利弊,根据自己的需要来决定使用哪种开发方式。回到刚才的问题,要解决用户层程序操作寄存器,就要进行物理地址到内存地址的映射转换。
        好在这个映射的方法很简单,也是通用的,我将它单独封装了一个类,以供其他各种类来调用。

        这个转换类我将它设计为单例方式,每次调用时不需要创建,同样使用完毕后也不需要在指定位置释放。这个类在首次被调用时打开/dev/mem内存文件,内存中所有的内容都包括在这个文件里,也包括寄存器的值。所以要更改寄存器的值,只要找到寄存器在内存中的虚拟地址然后对其赋值就可以了。
        这个类中包括了三个函数:GetMMap、Register、FreeMMap。
        GetMMap函数就是获取指定物理地址在内存中的内容,然后再根据寄存器的偏移量通过Register函数获得具体的位置,使用后再由FreeMMap函数来释放。
        有了这个基础,就可以继续下面的步骤了。要操作GPIO,就要先了解手册中对GPIO的功能描述、操作方法,以及各个寄存器的定义。
        炬力S500这个芯片比较特别,它将GPIO和PWM结合到了一起,而且在功能复用的设置上也是一反常态,并没有设计为一个bit对应一种功能。

        炬力S500的GPIO共有五组:GPIOA、GPIOB、GPIOC、GPIOD、GPIOE。每一组都包括OUTEN、INEN和DAT三种,作用为是否使能输出、是否使能输入和电平值。
        这里需要特别注意一下,复用功能的设置规定为:只有关闭了OUTEN和INEN,才能设置其他的复用功能;而在任意功能下,只要打开了OUTEN或INEN,那么这个引脚就立即自动设置为GPIO了。这就是我开始很纳闷为什么复用值中不包括输入或输出的对应位。

       了解了这些就知道该怎样写程序了。


        GPIO.go文件里包括了两个类,一个是Port类,也就是对端口进行的操作;一个是Pin类,是对端口中某一个引脚进行的操作。一个寄存器对应一个端口,而寄存器中的某一位对应的则是指定的引脚,一个Port中包括了32个Pin。
        Port类目前实现了获取寄存器的内存地址,还应该包括对端口的操作,只不过为了验证功能还没有加上,后续会完善进来。
        Pin类可以设置引脚电平的高低、翻转、设置复用功能,同样目前只实现了输入和输出的设置,其他功能后面根据具体的差异分别完成。
        由于Linux的用户层驱动不支持中断的响应,而且我暂时还没有找到好的办法实现,所以中断功能也没有加进来。实在不愿意再去编译内核程序来提供中断信号,那样就失去了UIO的意义了。
        GPIO类很简单,下面在主程序中调用实现控制LED的亮灭。

        Guitar的底板提供了两个LED,其中Green默认为心跳状态,所以在控制这个灯之前要先关闭心跳功能:echo "none" > /sys/class/leds/green:GPIOB12/trigger。LN_IO扩展板上有8个LED,查看原理图确定这些LED所对应的端口和引脚。

        调用的时候为每一个LED创建一个实例,通过参数指定Port和Pin,得到结果就是这个LED了。注意,Golang支持多返回值,CreateGPIO函数的第一个返回值是实例,第二个返回值是是否成功。如果不关心某一个返回值的时候,需要用"_"这个占位符来占位,否则将不能编译成功。
    这个程序的功能就是将这些GPIO指定为输出,并且每次程序运行都翻转电平。编译后运行程序可以看到效果,底板上的Green和Blue灯交替亮灭,LN_IO板上的8个灯也同样亮灭。



        到这里GPIO的程序基本完成了,通过封装,在使用时不需要考虑底层的操作,只要创建实例、指定复用功能、设置电平就可以了。
        以上这些代码已上传到https://github.com/tjCFeng/GoS500,可以直接在工程中引用。
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-11-19 08:49 , Processed in 0.119640 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.