我是靠谱客的博主 妩媚火,最近开发中收集的这篇文章主要介绍spi-lcd-st7789-驱动开发-驱动添加framebuf接口(4)Linux framebuf 介绍Framebuf 接口添加哪里唤醒这个显存数据发送线程呢?,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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 "t1n");
	 		LCD_Show_Image(0, 0, info->var.width, info->var.height, info->fix.smem_start);
			//printk(KERN_WARNING "t2n");
			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的一些处理直接看代码就可以了,处理都是模式化的步骤,没啥特别的。

 

最后

以上就是妩媚火为你收集整理的spi-lcd-st7789-驱动开发-驱动添加framebuf接口(4)Linux framebuf 介绍Framebuf 接口添加哪里唤醒这个显存数据发送线程呢?的全部内容,希望文章能够帮你解决spi-lcd-st7789-驱动开发-驱动添加framebuf接口(4)Linux framebuf 介绍Framebuf 接口添加哪里唤醒这个显存数据发送线程呢?所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部