瑞芯微RK3506通过fbtft适配ST7735S屏幕记录
网上有很多相关的文章,但是内核版本不相同,屏幕模组也不同,我适配时踩了很多坑。。。记录一下
主控 HD-RK3506G-MINI
内核 6.1.99
屏幕 ST7735S 1.8' 128*160,某宝搜TFT屏幕第一家就是
1.不用修改fbtft代码
现在fbtft已经被完善,相关的配置都在设备树,不需要再修改驱动代码了
2.内核相关配置
进入瑞芯微家的sdk,./build.sh kconfig进入内核配置
选择Device Drivers ---> [*] SPI support ---> <*> Rockchip SPI controller driver (不论是tinydrm还是fbtft都一定要选,不然后面的配置不会出现)
选择Device Drivers ---> [*] Staging drivers ---> <*> Support for small TFT LCD display modules ---> <*> FB driver for the ST7735R LCD Controller
内核默认没有打开VT(虚拟终端),需要在Character devices中打开,再打开FrameBuffer Console,这样就可以在屏幕上显示终端了
退出配置,接下来修改设备树
注意有时候你做的修改会被默认配置替换,比如rk3506-display.config每次编译前都会被merge,需要注意下输出的提示
2.设备树SPI配置
// 加入rk3506g-mini-v10.dtsi中
&spi1 {
status = "okay";
pinctrl-names = "default";
st7735: st7735r@0 {
compatible = "sitronix,st7735r";
reg = <0>; //chip select 0:cs0, 1:cs1
spi-max-frequency = <32000000>; //spi output clock
rgb; // rgb模式, 如果实际测试红蓝反了就改成bgr
buswidth = <8>;
fps = <60>;
// 0 90 180 270 顺时针
rotate = <270>; // 又是坑 rotation已更名为rotate
dc-gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; // DC脚,具体引脚请参考原理图
reset-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; // rest脚
};
};
修改完设备树后输入./build.sh kernel编译内核,输出kernel/zboot.img,烧录进板
3.测试程序
开机后TFT屏幕应该由白变黑,代表设备通信正常,简单用C写了个demo,可以测试屏幕参数是否正常:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <string.h>
#include <time.h>
// 屏幕参数
#define WIDTH 128
#define HEIGHT 160
#define BPP 16 // 16位色
// 颜色定义 (RGB565格式)
#define RED 0xF800
#define GREEN 0x07E0
#define BLUE 0x001F
#define WHITE 0xFFFF
#define BLACK 0x0000
// 根据实际情况修改
#define FB_DEVICE "/dev/fb0"
int main(int argc, char *argv[]) {
int fbfd = 0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long int screensize = 0;
char *fbp = 0;
int x = 0, y = 0;
unsigned int color = 0;
long int location = 0;
// 打开帧缓冲设备
fbfd = open(FB_DEVICE, O_RDWR);
if (fbfd == -1) {
perror("Error: cannot open framebuffer device");
exit(1);
}
// 获取固定屏幕信息
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {
perror("Error reading fixed information");
exit(2);
}
// 获取可变屏幕信息
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
perror("Error reading variable information");
exit(3);
}
printf("Display info: %dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
// 检查是否为16bpp (st7735s)
if (vinfo.bits_per_pixel != 16) {
printf("Error: not supported bits per pixel (requires 16bpp)\n");
exit(4);
}
// 计算屏幕大小
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
// 映射帧缓冲到内存
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
if ((int)fbp == -1) {
perror("Error: failed to map framebuffer device to memory");
exit(5);
}
// 测试颜色数组
unsigned int colors[] = {RED, GREEN, BLUE, WHITE};
const char *color_names[] = {"RED", "GREEN", "BLUE", "WHITE"};
for (int c = 0; c < 4; c++) {
color = colors[c];
printf("Displaying %s screen...\n", color_names[c]);
// 填充整个屏幕
for (y = 0; y < HEIGHT; y++) {
for (x = 0; x < WIDTH; x++) {
location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel / 8) +
(y + vinfo.yoffset) * finfo.line_length;
if (vinfo.bits_per_pixel == 16) {
*((unsigned short *)(fbp + location)) = color;
}
}
}
// 等待2秒
sleep(2);
}
// 清理
munmap(fbp, screensize);
close(fbfd);
printf("Test completed.\n");
return 0;
}
二编: 屏幕太小,换ILI9341+XPT2046触摸屏了,目前还在研究触屏,下一期出驱动+触摸屏校准笔记
--------------
你已经看完这篇博文了!
本文来自博客园,作者:星如雨yu,转载请注明原文链接:https://www.cnblogs.com/tianpanyu/p/18916685
另,建议转载手动看一眼,把代码块转过去呗(超小声嘀咕)

浙公网安备 33010602011771号