Linux手写FrameBuffer任意引脚驱动spi屏幕

一、硬件设备

        开发板:香橙派 5Plus,cpu:RK3588,带有 40pin 外接引脚。

        屏幕:SPI 协议 0.96 寸 OLED。

二、需求

        主要是想给板子增加一个可视化的监视器,并且主页面可调。

        平时跑个模型或者服务,想查看状态和参数,要么通过 SSH 远程连接,要么开启 Docker 跑面板,但是怎么会有抬头显示来的方便呢?于是捣鼓单片机的心又开始跳动了,准备手写一套完整的驱动和应用。

        硬件 SPI 引脚刚好在风扇的出风口,为了满足强迫症,决定使用软件模拟 SPI,直接手翻引脚。考虑到后期可能会增加新的设备,于是直接将除 VCC 和 GND 以外的脚全部通过应用层传入,可以随意更改。

三、驱动

        0.96的 OLED 分辨率不高,使用字符设备来实现足矣。

1、传统的字符设备注册流程:

并在开头先完成了帧缓存的映射:

        这里我增加了缓冲区大小的自动调整,内核在分配虚拟内存区域(VMA)时,可能会出于性能或管理方便的考虑,将映射大小调整为页面大小的整数倍,在64位系统中一页是 4096 字节。 所以即使只请求了 1024 (分辨率128 * 64 / 8)字节,内核也会分配一个完整的页面(4096 字节)。

        vmalloc_user 函数注意带有 user 后缀,专门为用户空间的映射而设计的。我一开始使用不带后缀的,在内核的映射函数 remap_vmalloc_range 总是报错,不知是不是因为 vmalloc 带有调试信息等额外的元数据,导致用户空间无法映射。

2、帧缓冲写入oled

        这里读者需要注意 oled 的刷新方式,我在实践过程中发现手上的屏幕是左下角为(0,0)原点,但是我的帧缓冲写入方式为左上角为原点,所以这里需要对页的写入顺序进行反转。

        如果你发现写入一个24点大小字符,字符的第一个字节对应字符的底部,最后一个字节对应字符的顶部,这导致了字符的上下部分显示颠倒,但每一部分内部的像素是正确的,那么尝试更换页的读写顺序函数,两个我都放到了函数中。

3、file_operations 结构体

        在驱动中,我实现了读、写、ioctl和mmap。读时返回屏幕的硬件信息和帧大小,写时可以直接将数据字节流写入到帧缓冲,用于快速清屏。

        ioctl 函数实现了简单的接口:

可以传入引脚的编号,开启和关闭OLED,刷新帧缓存和清屏。

驱动实现的 mmap 函数:

这里设置了 vma 的权限,见注释。

重点讲一下 ioctl 接口实现的 GPIO 写时初始化:

        (1) 先进行 GPIO 检查,如果已经初始化并且还没有释放引脚,则退出。

        (2) 将 GPIO 引脚结构体复制到内核,保存到内核中的设备结构体;

        (3) 进行 GPIO 的初始化,包括向内核申请引脚,设置方向,并标记已配置:

        (4) 进行 OLED 的初始化,这里可能各不相同,建议找购买渠道询问:

        以上是驱动的大概框架,由于字符驱动本身比较基础,开源资料也非常多,所以只展示了我个人设计的地方,代码具体实现细节我会放在 github 及 gitee。

1125962926/spi-oled-driver: Framebuffer drivers implemented by char-devices that can change pins at willhttps://github.com/1125962926/spi-oled-driverhttps://github.com/1125962926/spi-oled-driverhttps://github.com/1125962926/spi-oled-driverhttps://github.com/1125962926/spi-oled-driverhttps://github.com/1125962926/spi-oled-driverspi-oled-driver: 手写Linux FrameBuffer 0.96 寸 spi 屏幕驱动,支持从 app 传入任意引脚https://gitee.com/lrf1125962926/spi-oled-driverhttps://gitee.com/lrf1125962926/spi-oled-driverhttps://gitee.com/lrf1125962926/spi-oled-driverhttps://gitee.com/lrf1125962926/spi-oled-driverhttps://gitee.com/lrf1125962926/spi-oled-driver

四、应用

        APP 的使用框架已经搭建好,包括信号的处理,命令行参数的解析,GPIO的传入,设备的文件锁,ioctl控制,帧缓存映射,poll函数实现定时刷新,同时还能休眠线程,减少CPU负载。各位小伙伴可以直接上手用,减少写驱动的时间。

        并且使用运行脚本和停止脚本,运行脚本可以实现文件锁来防止多次打开,文件锁内保存app的PID,停止脚本可以读取后关闭进程,并删除PID文件。

        UI的设计还在开发中,这部分根据原有的设想,内容会很多,所以会在完成后单独写一篇文章分享。有关 0.96寸 OLED 的 UI 界面设计,也欢迎各位小伙伴提供思路和建议,我也在寻找优秀好看的 UI,毕竟 htop 和 btop 的界面用习惯了,top那密密麻麻的一片看着难受。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

plmm烟酒僧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值