手机apk怎么通过ioctl操作linux gpio ioctl

博客访问: 664
博文数量: 2
博客积分: 10
博客等级: 民兵
技术积分: 20
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
原文地址: 作者:
ioctl---控制硬件设备<font face="楷体_GB2312" size="4" color="#.原型:用户空间ioctl(int fd,unsigned long cmd,&...)"..."表示可选参数,是否存在依赖cmd内核空间static int&ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)同样arg依赖于cmd<font size="4" face="楷体_GB2312" color="#.如何实现ioctl功能(1)定义命令cmd:为安全起见,命令号最好在系统范围内唯一,应使用include/asm/ioctl.h和Documentation/ioctl-number.txt未使用过的命令号。ioctl命令编码被划分为几个位段:类型、序数、传送方向、参数大小,在&linux/ioctl.h&type:幻数,8位宽,(先参考ioctl-number.txt),一般是一个字母,标识某个设备number:序数,8位宽,标识该设备命令编号direction:如果命令涉及读写设备,该字段定义数据传输方向(从应用程序角度看)。size:所涉及传输的数据大小,13或14位内核提供了下列宏来定义命令_IO(type,nr)没有参数的命令
_IOR(type,nr,size)从驱动中读数据,size一般写数据类型
_IOW(type,nr,size)写数据到设备_IOWR(type,nr,size)对设备读写操作比如//for gerneral gpio
typedef struct {
&&&&unsigned char num;
&&&&unsigned char val;
}gpio_app;
#define GPIO_GET&&&&_IOR('M', 0, gpio_app)
#define GPIO_SET&&&&_IOW('M',&1, gpio_app)
#define GPIO_DIR&&&&_IORW('M',2, gpio_app)(2)实现命令:包括三个方面,返回值、参数使用、命令实现①返回值在执行switch语句,当命令号不能匹配任意一个设备命令时,返回-EINVAL(非法参数)return (value ? &0 : -EINVAL);②参数参数是一个整数时可直接使用,当是一个指针时,必须确保该指针是合法的。对未验证的用户空间指针访问,可能导致oops,系统崩溃或安全问题。不需要检测的数据交换函数unsigned long copy_to_user(void __user*to,const void *from,unsigned long count);
unsigned long copy_from_user(void *to,const void __user*from,unsigned long count);//适合于每次访问char,int等单个数据类型
get_user(k,u);&&&&
put_user(k,u);需要检测的函数__get_user(k,u);
__put_user(k,u);检测方法int access_ok(type,addr,size)第一个参数type:是VERIFY_READ或VERIFY_WRITE,表面是读/写用户内存addr:用户内存地址size:要检测的内存长度返回1--成功,0--失败不能读写eg:if(_IOC_DIR(cmd)&_IOC_READ)
&&&&err = !access_ok(VERIFY_WRITE,(void __user*)arg,_IOC_SIZE(cmd));
else if (_IOC_DIR(cmd)&_IOC_WRITE)
&&&&err = !access_ok(VERIFY_READ,(void __user*)arg,_IOC_SIZE(cmd));
&&&&return -EFAULT;③命令实现真正实现命令对应的动作。
阅读(267) | 评论(0) | 转发(0) |
上一篇:没有了
相关热门文章
给主人留下些什么吧!~~
请登录后评论。对GPIO操作
对GPIO操作
发布时间: 20:13:41
编辑:www.fx114.net
本篇文章主要介绍了"对GPIO操作",主要涉及到对GPIO操作方面的内容,对于对GPIO操作感兴趣的同学可以参考一下。
是的,终于明白并且实验成功了,在用户空间不能直接访问的,还好开发板提供了一个内存映射的字符设备,我映射到用户空间了.不过将来要做更多事情的话,还得恶补一下Linux下的驱动编写.以下分享一下通过内存映射访问字符设备的方法:这段程序是在网上下载的,但是编译时有点问题,我修改过之后就可以运行了.//以下是gpio_test.c文件,在RedHat9上编译通过,在405EP的taihu开发板运行通过,点亮LED.#include & &stdio.h&#include & &fcntl.h&#include & &stdlib.h&#include & &unistd.h&#include & &sys/mman.h&#include & &unistd.h&void & & *mapDirectIoRegister(unsigned & long & addr, & size_t & length);int & & & & iounmap(volatile & void & *start, & size_t & length);void & & & sysLedSet(unsigned & char & value);#define & MAP_SIZE & & & & & & & & & & & & & & & & & & & & & & & & 4096UL#define & MAP_MASK & & & & & & & & & & & & & & & & & & & & & & & & (MAP_SIZE & - & 1) //4095#define & HCU3_LED_REGISTER & & & & & & & & & & & & & & & 0xEF600700volatile & unsigned & long & *ledR#define & __PPC4xx__#ifdef & __PPC4xx__inline & void & out_32(volatile & unsigned & long & *addr, & unsigned & val){& & & & & & & & __asm__ & __volatile__( "stw%U0%X0 & %1,%0; & eieio " & : & "=m " & (*addr) & : & "r " &(val));}#elseextern & inline & void & out_32(volatile & unsigned & long & *addr, & unsigned & val){ & * & which & shows & you & how & to & use & PPC & assembler & code & to & ensure & correct & IO &ordering.& & & & & & & & *addr & = & val & & & 0}#endifvoid & & *mapDirectIoRegister(unsigned & long & addr, & size_t & length){void & *map_base, & * & virtAoff_t & target & = & ((unsigned & int) & addr) & & & ~MAP_MASK; //off_t就是int类型; & MAP_MASK=4095UL=& & ~MAP_MASK=0xFFFFF000ULint && & & & & & & &if & ((fd & = & open( "/dev/mem ", & O_RDWR & | & O_SYNC)) & == & -1) //打开内存文件(驱动){printf( "/dev/mem & could & not & be & opened./n ");exit(1);}& & & & & & & &// & Map & one & pagemap_base & = & mmap((void & *)target, & length, & PROT_READ & | & PROT_WRITE, & MAP_SHARED,fd, & target);if(map_base & == & (void & *) & -1){printf( "Memory & map & failed & for & address & 0x%lx/n ", & addr);return & map_}& & & & & & & &virtAddr & = & (void & *) & ((unsigned & long)map_base & + & ( & (unsigned & long)addr & & & MAP_MASK)); //基地址+偏移量printf( "Memory & map & 0x%lx & -& & %p & offset & 0x%lx & virtual & %p/n ", & addr, & map_base,addr & & & MAP_MASK, & virtAddr);//输出:Memory & map & 0xef600700 & -& & 0x & offset & 0x700 & virtual & 0xreturn & virtA}int & iounmap(volatile & void & *start, & size_t & length){unsigned & long & ofs_ofs_addr & = & (unsigned & long)start & & & (getpagesize()-1);& & & & & & & &&return & munmap((void*)start-ofs_addr, & length+ofs_addr);}void & sysLedSet(unsigned & char & value){*ledRegister & = & (( & unsigned & long & ) & ~value & & &23) & ;out_32(ledRegister, & ( & unsigned & long & ) & ~value & & &23 & );}int & main & (int & argc, & char & *argv[]){unsigned & char &printf( "%s: & %s & %s/n ", & __FUNCTION__, & __DATE__, & __TIME__ & ); //输出main: & Feb & & 9 & 2007 & 18:13:55 && & & & & & & &ledRegister & = & (unsigned & long & *)mapDirectIoRegister(HCU3_LED_REGISTER, & MAP_SIZE); //MAP_SIZE=4096UL//上面一行输出:Memory & map & 0xef600700 & -& & 0x & offset & 0x700 & virtual & 0x//ledRegister[1] & & = & 0x7ffe0000; && &*ledRegister & & = & & 0x7//out_32(ledRegister, & 0x7fffffff & );sleep(1);*ledRegister & & = & 0x0;//out_32(ledRegister, & 0x0 & );iounmap((volatile & void & *)HCU3_LED_REGISTER, & MAP_SIZE);printf( "/n%s:done/n ", & __FUNCTION__); //输出:main:donereturn & 0;}
以下是dev_gpio.c#include & "dev_gpio.h "static & ioport_device_t & gpio_devices[256];int & __init & gpio_init(void){int &register_chrdev(IOPORT_MAJOR, & "gpiotest ", & &gpio_ctl_fops);return & 0;}__initcall(gpio_init);int & gpio_open(struct & inode & *inode, & struct & file & *filp){int &minor & = & MINOR(inode-& i_rdev);*(volatile & unsigned & short*)(0xfff)&=~0x0080;*(volatile & unsigned & short*)(0xfff)|=0x0080;gpio_devices[minor]++;return & 0;}//__ioremapint & gpio_release(struct & inode & *inode, & struct & file & *filp){int &minor & = & MINOR(inode-& i_rdev);if & (gpio_devices[minor])gpio_devices[minor]--;*(volatile & unsigned & short*)(0xfff)&=~0x0080;*(volatile & unsigned & short*)(0xfff)|=0x0080;return & 0;}int & gpio_ctl_ioctl(struct & inode & *inode,struct & file & *flip,unsigned & int & command,unsigned & long & arg){int & err & = & 0;int & minor & = & MINOR(inode-& i_rdev);switch & (command){case & IOWRITE:*(volatile & unsigned & short*)(0xfff)&=~0x0080;return & 0;case & IOCLEAR:*(volatile & unsigned & short*)(0xfff)|=0x0080;return & 0;default:err & = & -EINVAL;}return &}
//以下是dev_gpio.h#include & &linux/fs.h&#include & &linux/iobuf.h&#include & &linux/major.h&#include & &linux/blkdev.h&#include & &linux/capability.h&#include & &linux/smp_lock.h&#include & &asm/uaccess.h&#include & &asm/io.h&#include & &linux/vmalloc.h&#define & dprintk(x...)#define & IOPORT_MAJOR & 220typedef & char & ioport_device_t;int & gpio_open(struct & inode & *, & struct & file & *);int & gpio_release(struct & inode & *, & struct & file & *);int & gpio_ctl_ioctl(struct & inode & *, & struct & file & *, & unsigned & int, & unsigned & long);static & struct & file_operations & gpio_fops & ={open: & gpio_open,release: & gpio_release,};static & struct & file_operations & gpio_ctl_fops & ={ioctl: & gpio_ctl_ioctl,open: & gpio_open,release: & gpio_release,};
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接:博客访问: 128973
博文数量: 90
博客积分: 65
博客等级: 民兵
技术积分: 910
注册时间:
linux kernel 工程师
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: LINUX
本测试程序通过&ioctl(fd, I2C_RDWR, &ioctl_data)访问I2C
#include &stdio.h&
#include &unistd.h&
#include &fcntl.h&
#include &errno.h&
#include &sys/ioctl.h&
#include &linux/i2c-dev.h&
#include &linux/i2c.h&
#define I2C_DEV&&&&"/dev/i2c-0"
#define I2C_PCA9554_ADDR&0x54
#define WRITE_VALUE&&&&&&&& 0x49
&struct i2c_rdwr_ioctl_data ioctl_data = {0};
&struct i2c_msg msg[4] = {{0}};
&unsigned char data[4] = {0};
&unsigned char out[2] = {0};
&fd = open(I2C_DEV, O_RDWR);
&if (fd & 0) {
&&printf("failed to open %s\n", I2C_DEV);
&&return (-1);
&/* test reading and writing registers in PCA9554 */
&/* read from Configuration Register (0x03) */
&data[0] = 0x03;
&msg[0].addr = I2C_PCA9554_ADDR;
&msg[0].flags = 0;&/* write */
&msg[0].len = 1;
&msg[0].buf = &data[0];
&msg[1].addr = I2C_PCA9554_ADDR;
&msg[1].flags = I2C_M_RD;
&msg[1].len = 1;
&msg[1].buf = &out[0];
&ioctl_data.nmsgs = 2;
&ioctl_data.msgs = &msg[0];
&rc = ioctl(fd, I2C_RDWR, &ioctl_data);
&if (rc & 0) {
&&printf("read, I2C_RDWR failed: %d.\n", errno);
&&close(fd);
&&return (-1);
&printf("Config reg: 0x%02x\n", out[0] );
&/* write 0x5a into Configuration Register (0x03) */
&printf("write 0x%02x at 0x03\n", WRITE_VALUE);
&data[0] = 0x03;&/* address */
&data[1] = WRITE_VALUE;&/* data */
&msg[0].addr = I2C_PCA9554_ADDR;
&msg[0].flags = 0;&/* write */
&msg[0].len = 2;
&msg[0].buf = &data[0];
&ioctl_data.nmsgs = 1;
&ioctl_data.msgs = &msg[0];
&rc = ioctl(fd, I2C_RDWR, &ioctl_data);
&if (rc & 0) {
&&printf("write, I2C_RDWR failed: %d.\n", errno);
&&close(fd);
&&return (-1);
&sleep(1);
&/* read out again to check */
&printf("read out at 0x03\n");
&data[0] = 0x03;
&msg[0].addr = I2C_PCA9554_ADDR;
&msg[0].flags = 0;&/* write */
&msg[0].len = 1;
&msg[0].buf = &data[0];
&msg[1].addr = I2C_PCA9554_ADDR;
&msg[1].flags = I2C_M_RD;
&msg[1].len = 1;
&msg[1].buf = &out[0];
&ioctl_data.nmsgs = 2;
&ioctl_data.msgs = &msg[0];
&rc = ioctl(fd, I2C_RDWR, &ioctl_data);
&if (rc & 0) {
&&printf("read, I2C_RDWR failed: %d.\n", errno);
&&close(fd);
&&return (-1);
&if (out[0] != WRITE_VALUE)
&&printf("write failed. ");
&&printf("write success. ");
&printf("Config_reg: 0x%02x\n", out[0] );
&sleep(1);
&close(fd);
&return (0);
阅读(3620) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。}

我要回帖

更多关于 of get named gpio 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信