Navigation

    全志在线开发者论坛

    • Register
    • Login
    • Search
    • Categories
    • Tags
    • 在线文档
    • 社区主页

    ioctl函数获取值错误

    Linux
    2
    3
    1804
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • W
      wyljkl LV 7 last edited by YuzukiTsuru

      在应用层调用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
      

      通道值和图层值对不上

      1 Reply Last reply Reply Quote Share 0
      • W
        wyljkl LV 7 last edited by

        有思路的大家都可以提一下,感谢!

        H 1 Reply Last reply Reply Quote Share 0
        • H
          hyl451292681 LV 4 @wyljkl last edited by

          @wyljkl 可以看下引用的sunxi_display2.h 是不是跟内核 include文件夹下的内容一致。

          1 Reply Last reply Reply Quote Share 0
          • 1 / 1
          • First post
            Last post

          Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

          行为准则 | 用户协议 | 隐私权政策