Firefly开源社区

12
发表新贴
打印 上一主题 下一主题

golang实现GPIO控制

230

积分

23

威望

20

贡献

技术达人

Rank: 2

积分
230

突出贡献

golang实现GPIO控制

发表于 2015-4-22 22:09:50      浏览:20931 | 回复:15        打印      只看该作者   [复制链接] 楼主
本帖最后由 tjCFeng 于 2015-4-23 17:33 编辑

    Go是Google开发的一种编译型,可平行化,并具有垃圾回收功能的编程语言。

    Go是有表达力、简洁、清晰和有效率的。它的并行机制使其很容易编写多核和网络应用,而新的类型系统 允许构建有性的模块化程序。Go编译到机器码非常快 速,同时具有便利的垃圾回收和强大的运行时反射。

   GO快速的、静态类型编译语言,但是感觉上是动态 类型的,解释型语言,易于编写。而且它的特点和C、pascal一样,可以编译为本地原生代码,生成的可直行文件可以直接拷贝到其他同种系统中运行,开发和运行效率都很高,甚至可以达到C语言的80%。


    在大概熟悉了go的语法后,打算在arm平台上尝试一下直接操作底层寄存器的开发,大体思路应该是一样的,但是go已经封装了很多功能,不能直接调用系统的API函数,如果调用的话需要通过嵌入C来实现。从网上找了几个例子看了下也是这样的。不过我还是不死心,进过两天的摸索,查看了相关的例子之后终于初步实现了寄存器的操作,可以算做是学习go的第一步吧。


    本次开发的环境是在Firefly-RK3288开发板的Lubuntu下进行的,直接编译为本地可执行文件。go的开发环境就不详细说明了,从github上下载源代码后直行all.bash可以自动完成安装。目前是1.4.2版本,修复了许多bug。

    以前用pascal封装过Allwinner A20的寄存器类库,估计go大同小异,都是先找到地址,映射到内存,再根据寄存器来赋值完成功能。

    不过一上来就给我难住了,首先是打开/dev/mem文件,返回的应该是个int的文件句柄,而go返回的是个结构体不能直接用。在查看了手册后发现,其中的Fd()是这个句柄,可以拿来使用,第一个问题解决。


    接下来就是映射内存地址了。先看原理图,找到需要用到的IO口


    板子上的WORK_LED是我要控制的,而它对应的是GPIO8_A1这个Pin,并且的高电平是关闭,低电平是点亮。

    这个GPIO8的地址是多少呢?从内核代码里和手册上都能找到



    物理地址是0xFF7F0000。在pascal中是要除以PAGE_SIZE来计算的,而到了go里,不知道是不是因为go把mmap封装了,这样调用不成功,很是奇怪,因为在c和pascal里都是这样的,没道理会改变吧。

    经过多次试验发现,这里是不能除PAGE_SIZE的,估计是跟go的封装有关。映射成功,稀里糊涂第二个问题解决,至少不报错了。


    在go里mmap之后返回的是一个数组,而不是一个指针,并且go的数组指针指向的并不是数组的首地址,所以不能直接对指针赋值来改变寄存器的值,而是直接对数组赋值达到这个效果。映射后的数组是8位的,为了和手一致,需要转换成32位的,经过学习(抄的代码:-)),又用到了unsafe类型,转换后可以打印出数组的内容了,看来第三个问题也解决了。



    赶紧来操作寄存器试一试,GOIO_A0是第0位,那么GPIO_A1理所当然是第1位了。所以直接对这个数组[1]进行赋1和清0,果然那个Work_LED能够控制了。




    大功告成,终于可以控制GPIO了。不过真的对吗?感觉有些地方想不通,手册里标明的第一个寄存器是高低电平,第二个是输入输出,那么我对着数组的[1]赋值算是什么呢?



    经过几次的调试,最后得到确认,数组的[0]才是对应的DR,[1]是DDR,因为数据已经从8位转换为32位了,所以数组[0]中的[1]才是我要控制的GPIO_A1,前面操作的原来是方向寄存器。

    到此才算基本搞清楚了go操作寄存器的方法。第一步至关重要,只要成功了后面的就好办了。



    附上go的全部程序,就是这么一点语句,折腾了两个晚上的时间。


回复

使用道具 举报

20

积分

0

威望

0

贡献

技术小白

积分
20
发表于 2015-4-23 08:59:30        只看该作者  沙发
恭喜楼主  底层控制又进一步
回复

使用道具 举报

230

积分

23

威望

20

贡献

技术达人

Rank: 2

积分
230

突出贡献

发表于 2015-4-23 12:09:52        只看该作者  板凳
xmetoo 发表于 2015-4-23 08:59
恭喜楼主  底层控制又进一步

没有又进一步,只是用go语言实现了一下,呵呵
回复

使用道具 举报

16

积分

0

威望

0

贡献

游客

积分
16
发表于 2015-5-14 14:52:05        只看该作者  地板
弱弱的问一下,runtime是楼主自己做的?
回复

使用道具 举报

230

积分

23

威望

20

贡献

技术达人

Rank: 2

积分
230

突出贡献

发表于 2015-5-14 17:13:36        只看该作者  5#
本帖最后由 tjCFeng 于 2015-5-14 17:14 编辑
biiigfish 发表于 2015-5-14 14:52
弱弱的问一下,runtime是楼主自己做的?

编译后,runtime已经包括在可执行文件中。
golang 是静态编译型的语言,即使从其他的arm linux编译的直接拷过来也能运行,不需要安装其他的东西。
回复

使用道具 举报

18

积分

0

威望

0

贡献

技术小白

积分
18
发表于 2015-5-24 20:19:03        只看该作者  6#
rk3288的寄存器手册,能否发我一份呢
2457254539@qq.com
tks
回复

使用道具 举报

230

积分

23

威望

20

贡献

技术达人

Rank: 2

积分
230

突出贡献

发表于 2015-5-24 21:03:49        只看该作者  7#
lalazou 发表于 2015-5-24 20:19
rk3288的寄存器手册,能否发我一份呢

tks

我就是在论坛下的,Firefly已经共享不少了。http://developer.t-firefly.com/thread-686-1-1.html
回复

使用道具 举报

1187

积分

1

威望

3

贡献

中级创客

Rank: 4

积分
1187
QQ
发表于 2015-5-26 14:21:46        只看该作者  8#
教程很好{:3_59:}
回复

使用道具 举报

230

积分

23

威望

20

贡献

技术达人

Rank: 2

积分
230

突出贡献

发表于 2015-5-27 06:32:40        只看该作者  9#

感谢支持:lol
回复

使用道具 举报

1187

积分

1

威望

3

贡献

中级创客

Rank: 4

积分
1187
QQ
发表于 2015-5-28 11:48:55        只看该作者  10#
楼主,我想问下syscall.Mmap里面的4096参数是哪里来的?
回复

使用道具 举报

返回列表
12
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

友情链接 : 爱板网 电子发烧友论坛 云汉电子社区 粤ICP备14022046号-2
快速回复 返回顶部 返回列表