ioctl函数获取值错误
-
在应用层调用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
通道值和图层值对不上
-
有思路的大家都可以提一下,感谢!
-
@wyljkl 可以看下引用的sunxi_display2.h 是不是跟内核 include文件夹下的内容一致。
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号