什么是fbtft
fbtft 在 github 中的介紹是“ Linux Framebuffer drivers for small TFT LCD display modules,翻譯過來就是支持小型 TFT LCD 顯示器的 Linux FrameBuffer 驅動。也就是專門為小型 TFT LCD 所寫的 Framebuffer 驅動。
github 地址為:notro/fbtft
wiki 地址為:notro/wiki
從 fbtft 的 github 上看,fbtft 不再更新到 github 了,遷移到了 Linux kernel staging tree。在https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git/tree/drivers/staging/fbtft?h=staging-testing中看到 fbtft 所支持的設備有:
fbtft 在 STM32MP15X 中
在STM32MP15X 的4.19內核源碼中,fbtft 源碼在內核根目錄的:drivers\staging\fbtft。
如何使用
我手上有 st7735r 跟 Ili9341 的屏,看了下 fbtft 里面的源碼正好有 st7735r 跟 Ili9341 驅動,先試下 st7735r 的屏,
在文件 drivers\staging\fbtft\fb_st7735r.c 中:
static struct fbtft_display display = {
.regwidth = 8,
.width = 128,
.height = 160,
.init_sequence = default_init_sequence,
.gamma_num = 2,
.gamma_len = 16,
.gamma = DEFAULT_GAMMA,
.fbtftops = {
.set_addr_win = set_addr_win,
.set_var = set_var,
.set_gamma = set_gamma,
},
};
FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735r", &display);
FBTFT_REGISTER_DRIVER展開后如下:
#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
\
static int fbtft_driver_probe_spi(struct spi_device *spi) \
{ \
return fbtft_probe_common(_display, spi, NULL); \
} \
\
static int fbtft_driver_remove_spi(struct spi_device *spi) \
{ \
struct fb_info *info = spi_get_drvdata(spi); \
\
return fbtft_remove_common(&spi->dev, info); \
} \
\
static int fbtft_driver_probe_pdev(struct platform_device *pdev) \
{ \
return fbtft_probe_common(_display, NULL, pdev); \
} \
\
static int fbtft_driver_remove_pdev(struct platform_device *pdev) \
{ \
struct fb_info *info = platform_get_drvdata(pdev); \
\
return fbtft_remove_common(&pdev->dev, info); \
} \
\
static const struct of_device_id dt_ids[] = { \
{ .compatible = _compatible }, \
{}, \
}; \
\
MODULE_DEVICE_TABLE(of, dt_ids); \
有這么條語句:
MODULE_DEVICE_TABLE(of, dt_ids);
從這看出要使用該設備,需要修改設備樹。
修改源碼
首先在make menuconfig中把fbtft加上:
1、修改設備樹
由於我的屏是接在 STM32MP157c 的 SPI5,所以在設備樹中 spi5 下面添加屏的設備數,CS 腳接到 STM32MP157C 的 GPIOF 6,DC 腳接到 GPIOF 3 腳,RESET 腳接到 GPIOD 13,設備數修改為如下:
&spi5 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&spi5_pins_a>;
pinctrl-1 = <&spi5_sleep_pins_a>;
cs-gpios = <&gpiof 6 GPIO_ACTIVE_HIGH>;
status = "okay";
st7735r@0{
compatible = "jianda,jd-t18003-t01", "sitronix,st7735r";
reg = <0>;
spi-max-frequency = <32000000>;
dc-gpios = <&gpiof 3 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpiod 13 GPIO_ACTIVE_HIGH>;
rotation = <270>;
backlight = &backlight;
};
};
編譯並把設備樹跟內核更新到板子上,啟動,看屏沒什么反應,/dev下也沒有fb設備,查看spi相關信息:
root@stm32mp1:~# dmesg | grep "spi"
[ 1.543185] spi_stm32 44009000.spi: 8 x 8-bit fifo size
[ 1.543206] spi_stm32 44009000.spi: 16-bit maximum data frame
[ 1.543670] spi_stm32 44009000.spi: registered master spi0
[ 1.543900] spi spi0.0: stm32_spi_setup: set gpio86 output high
[ 1.543943] spi spi0.0: setup mode 0, 8 bits/w, 32000000 Hz max --> 0
[ 1.544232] spi_stm32 44009000.spi: registered child spi0.0
[ 1.544245] spi_stm32 44009000.spi: driver initialized
[ 2.097755] fb_st7735r spi0.0: buswidth is not set
[ 2.102334] fb_st7735r: probe of spi0.0 failed with error -22
有錯誤,上網查了下資料,覺得可能是沒有添加 buswidth,在設備樹中把 buswitch 加上:
&spi5 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&spi5_pins_a>;
pinctrl-1 = <&spi5_sleep_pins_a>;
cs-gpios = <&gpiof 6 GPIO_ACTIVE_HIGH>;
status = "okay";
st7735r@0{
compatible = "jianda,jd-t18003-t01", "sitronix,st7735r";
reg = <0>;
buswidth = <8>;
spi-max-frequency = <32000000>;
dc-gpios = <&gpiof 3 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpiod 13 GPIO_ACTIVE_HIGH>;
rotation = <270>;
backlight = &backlight;
};
};
重新更新板子上的設備樹,上電,可以看到屏幕有白色變黑色,應該是可以了,看下 /dev 目錄,下圖中上部分是修改前的,下部分是修改后的,可以看到修改后的在/dev下可以看到多了個fb設備:
測試
在屏上顯示隨機數:
cat /dev/urandom > /dev/fb0