io操作

来源:互联网 发布:汉王全屏幕软件下载 编辑:程序博客网 时间:2024/06/03 20:37

驱动层

long led_ ioctl(struct file *fp, unsigned int cmd, unsigned long arg)/*fp 文件指针,cmd 命令,arg 数据    cmd 命令是一个 32 位数     从上层应用传过来的 arg 可能是数据也可能是指针    如果是应用层是指针,读的时候需要先转换成 数据 *((int *)arg)    */
cmd bit 0-7 nr 功能码 8-15 type 命令类型,模数 幻数 16-29 size 数据尺寸 30-31 dir 方向
{    int i=0;    if(_IOC_TYPE(cmd) != 'x')       //_IOC_TYPE 取命令类型        return -EINVAL;    switch (_IOC_DIR(cmd))          //_IOC_DIR 取命令方向    {        case _IOC_READ:            for(i=0;i<MYLED_NUM;i++)                {                led_status[i] =! (rGPM4DAT&(0x1<<i));            }            if(copy_to_user((long*)arg,led_status,4))                return -EINVAL;            break;        case  _IOC_WRITE:            if(_IOC_NR(cmd)==0)         //_IOC_NR 取命令功能码                rGPM4DAT |= (0x1<<arg);            else if(_IOC_NR(cmd) == 1)                rGPM4DAT &= ~(0x1<<arg);            else                return -EINVAL;            break;        case (_IOC_WRITE|_IOC_READ):        {              for(i=0;i<MYLED_NUM;i++)                led_status[i]=! (rGPM4DAT&(0x1<<i));            switch (_IOC_NR(cmd))            {                case 0:                    rGPM4DAT |= (0x1<<*((int *)arg));                    break;                case 1:                    rGPM4DAT &= ~(0x1<<*((int *)arg));                    break;                default :                    return -EINVAL;                    break;            }            if(copy_to_user((long*)arg,led_status,MYLED_NUM))                return -EINVAL;            break;        }        case _IOC_NONE:            break;        default:            break;    }    return 0;}

应用层

主要函数

static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include <sys/ioctl.h>#define LED_ON _IOW('x',1,sizeof(long))     //_IOW(x,y,z) 合成一个驱动函数用的 cmd 命令,x:模数,幻数,命令类型 y:命令功能码 z:数据尺寸//_IOW(x,y,z)   write//_IOR(x,y,z)   read#define LED_OFF _IOW('x',0,sizeof(long))#define LED_R   _IOR('x',0,sizeof(long))#define LED_RW_OFF _IOWR('x',0,sizeof(long))#define LED_RW_ON _IOWR('x',1,sizeof(long))char led_status[4]={-1,-1,-1,-1};void print(int fd){    int i=0;    read(fd,led_status,4);    for(i=0;i<4;i++)    {        printf("led[%d]:%s\n",i,led_status[i]?"on":"off");    }    lseek(fd,0,SEEK_SET);}int main(int argc,char *argv[]){    int i;    int fd = open(argv[1],O_RDWR);    if(fd == -1)    {        printf("打开失败\n");        return 0;    }    print(fd);    lseek(fd,0,SEEK_SET);    for(i=0;i<4;i++)    {        ioctl(fd,LED_ON,i);        print(fd);        ioctl(fd,LED_R,&arg);           //ioctl 读数据时,读入的形参使用指针        printf("ths value is %d \n",arg);        sleep(1);        ioctl(fd,LED_OFF,i);        print(fd);        sleep(1);    }     i=3;     ioctl(fd,LED_RW_ON,&i);     print(fd);     printf("the value is %d \n",i);     sleep(1);     i=3;     ioctl(fd,LED_RW_OFF,&i);     print(fd);     printf("the value is %d \n",i);     sleep(1);    read(fd,led_status,4);    print(fd);    close(fd);    return 0;}