博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux平台从SD卡读文件并处理的方法
阅读量:4103 次
发布时间:2019-05-25

本文共 5440 字,大约阅读时间需要 18 分钟。

371人阅读
(0)

        在Linux的应用平台上,很多时候我们需要用到从SD卡读数据来使用,比如升级触摸屏固件,比如载入调试文本等,都需要用到Linux的文件系统来操作。通过举一个实例来说明VFS FILE操作细节,即在ADB中通过echo 到DEVICE_ATTR的store来升级TP固件,相关升级函数可以参见博文。

(1)store属性函数

[cpp]
  1. static ssize_t melfas_fwupdate_store(struct device *dev,struct device_attribute *attr,constchar *buf, size_t count) 
  2.     int UpResult; 
  3.     mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM); 
  4. printk("run here \r\n"); 
  5.     UpResult = ms6000_firmware_upgrade_from_TCard();    //T卡升级主函数 
  6.     if(UpResult== MS6000_RET_SUCCESS){ 
  7.         printk("MFS6000 DOWNLOAD SUCCESS \r\n"); 
  8.         msleep(100); 
  9.     } 
  10.     else 
  11.         mfs6000_print_fail_result(UpResult); 
  12.     i2c_client->addr = MS6000_8BIT_I2CADDR; 
  13.     mt_set_gpio_mode(GPIO_I2C0_SCA_PIN, GPIO_I2C0_SCA_PIN_M_SCL); 
  14.     mt_set_gpio_mode(GPIO_I2C0_SDA_PIN, GPIO_I2C0_SDA_PIN_M_SDA); 
  15.     mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);  //恢复中断和I2C脚的使用 
  16.  
  17.     return count; 
static ssize_t melfas_fwupdate_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count){	int UpResult;	mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM);printk("run here \r\n");	UpResult = ms6000_firmware_upgrade_from_TCard();	//T卡升级主函数	if(UpResult== MS6000_RET_SUCCESS){		printk("MFS6000 DOWNLOAD SUCCESS \r\n");		msleep(100);	}	else		mfs6000_print_fail_result(UpResult);	i2c_client->addr = MS6000_8BIT_I2CADDR;	mt_set_gpio_mode(GPIO_I2C0_SCA_PIN, GPIO_I2C0_SCA_PIN_M_SCL);	mt_set_gpio_mode(GPIO_I2C0_SDA_PIN, GPIO_I2C0_SDA_PIN_M_SDA);	mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);	//恢复中断和I2C脚的使用	return count;}

(2)从T卡读文件并处理

[cpp]
  1. static int ms6000_firmware_upgrade_from_TCard() 
  2.     unsigned char NewFwVersion,OldFwVersion; 
  3.     UINT16 rdlen;           //实际读入内存的文件长度 
  4.     loff_t file_size;           //文件大小 
  5.     UINT8 *buf = NULL;          //分配的内存指针 
  6.     struct file *fp = NULL; 
  7.     struct inode *inode = NULL; 
  8.     int ret = MS6000_RET_FILE_ACCESS_FAILED; 
  9.     mm_segment_t old_fs; 
  10.     const struct cred *old_cred; 
  11.     struct cred *override_cred; 
  12.  
  13.     override_cred = prepare_creds(); 
  14.     if (!override_cred) 
  15.         return -ENOMEM; 
  16.     override_cred->fsuid = 0; 
  17.     override_cred->fsgid = 0; 
  18.     old_cred = (struct cred *)override_creds(override_cred);   //权限属性 
  19.      
  20.     old_fs = get_fs(); 
  21.     set_fs(KERNEL_DS);                  //权限属性 
  22.  
  23.     if(mfs_i2c_read_single_reg(0x21,&OldFwVersion) ==true){ 
  24.         NewFwVersion = ms6000_GetLibVer();  //从T卡中读文件,并取出存于特定字节的版本号值 
  25.         printk("mfs6000 NewFwVersionis 0x%x,OldFwVersion is 0x%x \r\n",NewFwVersion,OldFwVersion); 
  26.     } 
  27.     i2c_client->addr = MS6000_8BIT_DOWNLOAD_ADDR;     
  28.     if(1NewFwVersion != OldFwVersion){ 
  29.         fp = filp_open("/mnt/sdcard/MCH_U5(S)_R01_VF6.bin", O_RDONLY, 0); //载入BIN格式的固件 
  30.         if (IS_ERR(fp)) { 
  31.             printk("ERROR opening file  \r\n"); 
  32.             return MS6000_RET_OPENFILE_ERROR; 
  33.         } else {         
  34.             if (!(fp->f_op)) { 
  35.                 printk("File has no file operations registered!\r\n");           
  36.                 filp_close(fp, NULL); 
  37.                 return MS6000_RET_OPENFILE_ERROR;        
  38.             }        
  39.             if (!fp->f_op->read) { 
  40.                 printk(" File has no READ operations registered!\r\n");          
  41.                 filp_close(fp, NULL); 
  42.                 return MS6000_RET_OPENFILE_ERROR;        
  43.             } 
  44.         } 
  45.  
  46.         inode = fp->f_dentry->d_inode; 
  47.         file_size = inode->i_size; 
  48.         buf = (UINT8 *)kmalloc(file_size, GFP_KERNEL); 
  49.         if(buf < 0) 
  50.             return -ENOMEM; 
  51.         rdlen = vfs_read(fp, buf, file_size, &(fp->f_pos)); 
  52.  
  53.         printk("start download, file_size is %d,rdlen is %d\r\n",file_size,rdlen); 
  54.         mtk_wdt_disable(); 
  55.         ret = ms6000_download(buf,rdlen);   //升级主函数参见文章头部博文 
  56.         mtk_wdt_get_en_setting(); 
  57.  
  58.         kfree(buf); 
  59.         filp_close(fp, NULL); 
  60.         revert_creds(old_cred); 
  61.         put_cred(override_cred); 
  62.         set_fs(old_fs);     //恢复权限 
  63.     } 
  64.     else
  65.         printk("because of the same lib, update abort!\r\n"); 
  66.     } 
  67.     return ret; 
static int ms6000_firmware_upgrade_from_TCard(){	unsigned char NewFwVersion,OldFwVersion;	UINT16 rdlen;			//实际读入内存的文件长度	loff_t file_size;			//文件大小	UINT8 *buf = NULL;			//分配的内存指针	struct file *fp = NULL;	struct inode *inode = NULL;	int ret = MS6000_RET_FILE_ACCESS_FAILED;	mm_segment_t old_fs;	const struct cred *old_cred;	struct cred *override_cred;	override_cred = prepare_creds();	if (!override_cred)		return -ENOMEM;	override_cred->fsuid = 0;	override_cred->fsgid = 0;	old_cred = (struct cred *)override_creds(override_cred);	//权限属性		old_fs = get_fs();	set_fs(KERNEL_DS);					//权限属性	if(mfs_i2c_read_single_reg(0x21,&OldFwVersion) == true){		NewFwVersion = ms6000_GetLibVer();	//从T卡中读文件,并取出存于特定字节的版本号值		printk("mfs6000 NewFwVersionis 0x%x,OldFwVersion is 0x%x \r\n",NewFwVersion,OldFwVersion);	}	i2c_client->addr = MS6000_8BIT_DOWNLOAD_ADDR;		if(1NewFwVersion != OldFwVersion){		fp = filp_open("/mnt/sdcard/MCH_U5(S)_R01_VF6.bin", O_RDONLY, 0);  //载入BIN格式的固件		if (IS_ERR(fp)) {			printk("ERROR opening file 	\r\n");			return MS6000_RET_OPENFILE_ERROR;		} else {					if (!(fp->f_op)) {				printk("File has no file operations registered!\r\n");							filp_close(fp, NULL);				return MS6000_RET_OPENFILE_ERROR;					}					if (!fp->f_op->read) {				printk(" File has no READ operations registered!\r\n");							filp_close(fp, NULL);				return MS6000_RET_OPENFILE_ERROR;					}		}		inode = fp->f_dentry->d_inode;		file_size = inode->i_size;		buf = (UINT8 *)kmalloc(file_size, GFP_KERNEL);		if(buf < 0)			return -ENOMEM;		rdlen = vfs_read(fp, buf, file_size, &(fp->f_pos));		printk("start download, file_size is %d,rdlen is %d\r\n",file_size,rdlen);		mtk_wdt_disable();		ret = ms6000_download(buf,rdlen);	//升级主函数参见文章头部博文		mtk_wdt_get_en_setting();		kfree(buf);		filp_close(fp, NULL);		revert_creds(old_cred);		put_cred(override_cred);		set_fs(old_fs);		//恢复权限	}	else{		printk("because of the same lib, update abort!\r\n");	}	return ret;}

按以上方式升级完后不用重启手机即可正常操作。验证成功与否的话,进入工厂菜单中即可看到正确的版本号F6,则说明升级成功。需要注意的是:该种方式只能用BIN固件升级,不能用C格式固件,因为读入的是流文件,也解释了之前升级C固件却导致TP不能用的原因。

(3)以上是升级TP固件,如果是从T卡中读文件并解析文件,则需要编写对应的流文件解析代码段即可。

转载地址:http://sbbsi.baihongyu.com/

你可能感兴趣的文章
JavaSE_day12 集合
查看>>
JavaSE_day14 集合中的Map集合_键值映射关系
查看>>
Day_15JavaSE 异常
查看>>
异常 Java学习Day_15
查看>>
JavaSE_day_03 方法
查看>>
day-03JavaSE_循环
查看>>
Mysql初始化的命令
查看>>
day_21_0817_Mysql
查看>>
day-22 mysql_SQL 结构化查询语言
查看>>
MySQL关键字的些许问题
查看>>
浅谈HTML
查看>>
css基础
查看>>
HTML&CSS进阶
查看>>
Servlet进阶和JSP基础
查看>>
servlet&jsp 的使用以及jsp的历史遗留用法
查看>>
servlet中的cookie和session
查看>>
过滤器及JSP九大隐式对象
查看>>
软件(项目)的分层
查看>>
菜单树
查看>>
MySQL-分布式架构-MyCAT
查看>>