spi-lcd-st7789-驅動開發-驅動新增framebuf介面(4)
阿新 • • 發佈:2021-02-19
Linux framebuf 介紹
https://blog.csdn.net/xpy123/article/details/46484291
Framebuf 介面新增
參照核心自帶的skeletonfb.c 修改,下面介紹下我自己主要修改的地方:
將framebuf介面單獨在一個檔案中實現 lcd_st7789_fb.c
spi介面的lcd沒有專門的lcd控制器將framebuf視訊記憶體資料直接傳送到spilcd,所以實際的資料部分我放在一個
核心執行緒來做,負責傳送framebuf 視訊記憶體資料的核心執行緒如下:
static int lcd_st7789_fb_send_data_thread_fn(void * data) { struct fb_info *info = platform_get_drvdata(lcd_st7789_plat_dev); MY_PRINT("Start"); while (1){ wait_event_interruptible(send_fb_data_wq, 1 == send_data_flag || 1 == quit_thread_flag); if (send_data_flag) { // MY_PRINT(""); //printk(KERN_WARNING "t1\n"); LCD_Show_Image(0, 0, info->var.width, info->var.height, info->fix.smem_start); //printk(KERN_WARNING "t2\n"); send_data_flag = 0; } else { //quit thread MY_PRINT("Quit Send Fb Data thread!"); break; } } MY_PRINT("End"); return 0; }
這個執行緒主要作用是等待一個喚醒訊號,倍喚醒後直接姐那個frambbufe視訊記憶體資料傳送到spilcd.
哪裡喚醒這個視訊記憶體資料傳送執行緒呢?
只要有更新視訊記憶體的函式,都會喚醒它。比如下面幾個函式:
static ssize_t lcd_st7789_fb_sys_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos) { //呼叫底層函式實際傳送資料到 st7789 內部 graphic ram ssize_t write_bytes; mutex_lock(&mutex_lock_viedeo_memmory); if (count > videomemorysize) { count = videomemorysize; } write_bytes = fb_sys_write(info, buf, count, ppos); send_data_flag = 1; wake_up_interruptible(&send_fb_data_wq); //通知執行緒更新lcd資料 mutex_unlock(&mutex_lock_viedeo_memmory); return write_bytes; } //用一種顏色填充矩形區域 //除了呼叫sys_fillrect 還要呼叫底層函式LCD_Fill 通過spi介面將是資料傳送到st7789 內部 graphic ram static void lcd_st7789_fb_fillrect(struct fb_info *p, const struct fb_fillrect *rect) { mutex_lock(&mutex_lock_viedeo_memmory); //1 更新本地快取中資料 sys_fillrect(p, rect); send_data_flag = 1; wake_up_interruptible(&send_fb_data_wq); //通知執行緒更新lcd資料 mutex_unlock(&mutex_lock_viedeo_memmory); } // void lcd_st7789_fb_copyarea(struct fb_info *p, const struct fb_copyarea *area) { mutex_lock(&mutex_lock_viedeo_memmory); //通知執行緒更新lcd資料 //1 更新本地快取中資料 sys_copyarea(p, area); send_data_flag = 1; wake_up_interruptible(&send_fb_data_wq); //通知執行緒更新lcd資料 mutex_unlock(&mutex_lock_viedeo_memmory); //通知執行緒更新lcd資料 } static void lcd_st7789_fb_imageblit(struct fb_info *p, const struct fb_image *image) { mutex_lock(&mutex_lock_viedeo_memmory); //通知執行緒更新lcd資料 if (image->depth != 16) { printk("Color depth only support 16, invalid depth:%d!!", image->depth); return; } //1 更新本地快取中資料 sys_imageblit(p, image); send_data_flag = 1; wake_up_interruptible(&send_fb_data_wq); //通知執行緒更新lcd資料 mutex_lock(&mutex_lock_viedeo_memmory); //通知執行緒更新lcd資料 }
對於通過cpu的lcd控制器自動傳送rgb訊號的lcd顯示屏來說,一般不需要專門的執行緒來發送視訊記憶體資料,上面對應的介面只要更新視訊記憶體資料就行,視訊記憶體資料傳送到lcd的任務由lcd控制器的硬體自動完成了。
其它關於framebuf的一些處理直接看程式碼就可以了,處理都是模式化的步驟,沒啥特別的。