您尚未登录。

楼主 # 2022-06-25 10:40:47

jkl
会员
注册时间: 2019-11-18
已发帖子: 253
积分: 141.5

发生一件很奇怪的事情,不知道问题出在哪里,大家帮忙看一下?

在应用层调用ioctl函数,内核获取的应用层传过去的一个结构体内容,其中有两个结构体成员内容对不上,其他的结构体成员值都是对的,这是怎么回事?
这是驱动层的IOCTL:

long disp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
//	printk("%s %d %s\n",__FILE__,__LINE__,__FUNCTION__);
	unsigned long karg[4];
	unsigned long ubuffer[4] = { 0 };
	s32 ret = 0;
	int num_screens = 2;
	struct disp_manager *mgr = NULL;
	struct disp_device *dispdev = NULL;
	struct disp_enhance *enhance = NULL;
	struct disp_smbl *smbl = NULL;
	struct disp_capture *cptr = NULL;
#if defined(SUPPORT_EINK)
	struct disp_eink_manager *eink_manager = NULL;
#endif

#ifdef EINK_FLUSH_TIME_TEST
	do_gettimeofday(&ioctrl_start_timer);
#endif				/*test eink time */

	num_screens = bsp_disp_feat_get_num_screens();

	if (copy_from_user
	    ((void *)karg, (void __user *)arg, 4 * sizeof(unsigned long))) {
		__wrn("copy_from_user fail\n");
		return -EFAULT;
	}
	
	ubuffer[0] = *(unsigned long *)karg;
	ubuffer[1] = (*(unsigned long *)(karg + 1));
	ubuffer[2] = (*(unsigned long *)(karg + 2));
	ubuffer[3] = (*(unsigned long *)(karg + 3));

	if (ubuffer[0] < num_screens)
		mgr = g_disp_drv.mgr[ubuffer[0]];
	if (mgr) {
		dispdev = mgr->device;
		enhance = mgr->enhance;
		smbl = mgr->smbl;
		cptr = mgr->cptr;
	}
#if defined(SUPPORT_EINK)
	eink_manager = g_disp_drv.eink_manager[0];

	if (!eink_manager)
		__wrn("eink_manager is NULL!\n");

#endif

	if (cmd < DISP_FB_REQUEST) {
		if (ubuffer[0] >= num_screens) {
			__wrn
			    ("para err, cmd = 0x%x,screen id = %d\n",
			     cmd, (int)ubuffer[0]);
			return -1;
		}
	}
	if (DISPLAY_DEEP_SLEEP & suspend_status) {
		__wrn("ioctl:%x fail when in suspend!\n", cmd);
		return -1;
	}

	if (cmd == DISP_print)
		__wrn("cmd:0x%x,%ld,%ld\n", cmd, ubuffer[0], ubuffer[1]);

	switch (cmd) {
	。。。。。。。。
		/* ----layer---- */
	case DISP_LAYER_SET_CONFIG:
	{
		printk("%s %d %s\n",__FILE__,__LINE__,__FUNCTION__);
		unsigned int i = 0;
		const unsigned int lyr_cfg_size = ARRAY_SIZE(lyr_cfg);

		mutex_lock(&g_disp_drv.mlock);

		if (ubuffer[2] > lyr_cfg_size) {
			__wrn("Total layer number is %d\n", lyr_cfg_size);
			mutex_unlock(&g_disp_drv.mlock);
			return -EFAULT;
		}

		if (copy_from_user(lyr_cfg,
			(void __user *)ubuffer[1],
			sizeof(struct disp_layer_config) * ubuffer[2]))	{
			__wrn("copy_from_user fail\n");
			mutex_unlock(&g_disp_drv.mlock);

			return  -EFAULT;
		}

		printk("lyr_cfg[0].info.alpha_mode = %d,lyr_cfg[0].info.alpha_value = %x,lyr_cfg[0].info.fb.size[0].width = %d,lyr_cfg[0].info.fb.size[0].height = %d,lyr_cfg[0].channel = %d,lyr_cfg[0].layer_id = %d,lyr_cfg[0].enable = %d\n",
			lyr_cfg[0].info.alpha_mode ,
			lyr_cfg[0].info.alpha_value ,
			lyr_cfg[0].info.fb.size[0].width ,
			lyr_cfg[0].info.fb.size[0].height ,
			lyr_cfg[0].channel ,
			lyr_cfg[0].layer_id ,
			lyr_cfg[0].enable);


#if !defined(CONFIG_EINK_PANEL_USED)
		printk("%s %d %s\n",__FILE__,__LINE__,__FUNCTION__);
		if (mgr && mgr->set_layer_config)
			ret = mgr->set_layer_config(mgr, lyr_cfg, ubuffer[2]);
		printk("%s %d %s\n",__FILE__,__LINE__,__FUNCTION__);
#endif
		mutex_unlock(&g_disp_drv.mlock);
		break;
	}



	。。。。


	default:
		ret = disp_ioctl_extend(cmd, (unsigned long)ubuffer);
		break;
	}

	return ret;
}

这是应用层测试主函数:

int main(int argc, char *argv[])
{
	unsigned long arg[3];
/* 一个 struct disp_layer_config 结构体对应一个图层的全部信息 */
	struct disp_layer_config config;
	unsigned int width = 1024;
	unsigned int height = 600;
	unsigned int ret = 0;
	

	disp = open("/dev/disp", O_RDWR);
    if (disp == -1) {
        printf("hdmitester: open /dev/disp failed(%s)\n", strerror(errno));
		return 0;
//        goto err;
    }

	memset(&config, 0, sizeof(struct disp_layer_config));
	/* 选择图层所属的通道以及本图层 ID(0-3)*/
	config.channel = 0;
	config.layer_id = 0;
	config.enable = 1;
	config.info.mode = LAYER_MODE_BUFFER;
	// config.info.fb.addr[0] = (unsigned long long)mem_in; //FB 物理地址
	config.info.fb.size[0].width = width;
	config.info.fb.size[0].height = height;
	config.info.fb.align[0] = 4;//bytes
	config.info.fb.format = DISP_FORMAT_ARGB_8888; //DISP_FORMAT_YUV420_P
	
	/* crop 表示裁剪区域的大小 */
	config.info.fb.crop.x = 0;
	config.info.fb.crop.y = 0;
	/* 定点小数。 高 32bit 为整数,低 32bit 为小数 */ 
	config.info.fb.crop.width = ((unsigned long)width) << 32; 
	/* 定点小数。 高 32bit 为整数,低 32bit 为小数 */
	config.info.fb.crop.height= ((unsigned long)height)<<32;
	config.info.fb.flags = DISP_BF_NORMAL;
	config.info.fb.scan = DISP_SCAN_PROGRESSIVE;
	config.info.alpha_mode = 1; //global pixel alpha
	config.info.alpha_value = 0xff;//global alpha value
	/* 显示窗口的大小 */
	config.info.screen_win.x = 0;
	config.info.screen_win.y = 0;
	config.info.screen_win.width = width;
	config.info.screen_win.height= height;
	config.info.id = 0;
	/* 上层调用 DE 显示引擎所用的 ioctl 接口 */
	arg[0] = 0;//screen 0 即选择显示通路 0
	arg[1] = (unsigned long)&config;
	arg[2] = 1; //只设置一个图层即当前图层
	ret = ioctl(disp, DISP_LAYER_SET_CONFIG, (void*)arg);


	printf("%s() <<<\n",__func__);
    return 0;
}

调试信息:

root@TinaLinux:/# ./lcd_test 
[   17.914242] drivers/video/fbdev/sunxi/disp2/disp/dev_disp.c 3885 disp_ioctl
[   17.922099] lyr_cfg[0].info.alpha_mode = 1,lyr_cfg[0].info.alpha_value = ff,lyr_cfg[0].info.fb.size[0].width = 1024,lyr_cfg[0].info.fb.size[0].height = 600,lyr_cfg[0].channel = 1024,lyr_cfg[0].layer_id = 600,lyr_cfg[0].enable = 1
[   17.944952] drivers/video/fbdev/sunxi/disp2/disp/dev_disp.c 3933 disp_ioctl
[   17.952800] [DISP] disp_get_layer,line:111:
[   17.952805] disp_get_layer (0,1024,600) fail
[   17.962388] drivers/video/fbdev/sunxi/disp2/disp/dev_disp.c 3936 disp_ioctl

通道值和图层值对不上

最近编辑记录 jkl (2022-06-25 10:41:50)

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn