linux copy_from_user/copy_to_user

来源:互联网 发布:算法统宗中的歌诀题 编辑:程序博客网 时间:2024/05/21 10:10

copy_from_user/copy_to_user:用于在用户地址空间和内核地址空间之间进行整段数据的拷贝。


gpio_misc.c:

#include <linux/module.h>//MODULE_AUTHOR,MODULE_LICENSE#include <linux/init.h>//module_init,module_exit#include <linux/fs.h>//file_operations#include <linux/miscdevice.h>//misdevice#include <asm/io.h>//ioread32,iowrite32#include "mmp_err.h"#include "mmpf_i2cm.h"#include "mmpf_system.h"#include "mmpf_pio.h"#include <linux/irq.h>#include <linux/uaccess.h>/*设备名称*/#define DEVICE_NAME "gpio_access"typedef struct port_value_struct {int port;int value;} PORT_VALUE;static PioCallBackFunc *gPIO_CallBackFunc[PIO_MAX_PIN_SIZE];extern MMP_ERR MMPF_PIO_SetData(MMPF_PIO_REG piopin, MMP_UBYTE outputValue);extern MMP_ERR MMPF_PIO_GetData(MMPF_PIO_REG piopin, MMP_UBYTE * returnValue);extern MMP_ERR MMPF_PIO_EnableOutputMode(MMPF_PIO_REG piopin, MMP_BOOL bEnable);extern MMP_ERR MMPF_PIO_EnableGpioMode(MMPF_PIO_REG piopin, MMP_BOOL bEnable);extern MMP_ERR MMPF_PIO_EnableInterrupt(MMPF_PIO_REG piopin, MMP_BOOL bEnable, MMP_ULONG boundingTime, PioCallBackFunc *CallBackFunc);static int gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){//      printk("cmd=%d,arg=%d\n", cmd, arg);switch (cmd)  {  case 'r'://read  {  /* MMP_UBYTE value;     MMPF_PIO_GetData((MMPF_PIO_REG)62, &value);     printk("charger value is %d\n", value);     put_user(value, (int __user *)arg); */  PORT_VALUE port_value ;  if (copy_from_user(&port_value, (PORT_VALUE *)arg, sizeof(PORT_VALUE)))    {    printk("copy_from_user failed.\n");    return -EFAULT;    }  MMPF_PIO_EnableGpioMode(port_value.port,1);  MMPF_PIO_EnableOutputMode((MMPF_PIO_REG)port_value.port,0);    MMPF_PIO_GetData((MMPF_PIO_REG) port_value.port, &port_value.value);  printk("read: port=%d,value=%d\n", port_value.port, port_value.value);  //put_user(value, (int __user *)arg);  if (copy_to_user((PORT_VALUE *)arg, &port_value, sizeof(PORT_VALUE)))    {    printk("copy_to_user failed.\n");    return -EFAULT;    }  return 0;  }  case 'w'://write  {  PORT_VALUE port_value;  if (copy_from_user(&port_value, (PORT_VALUE *)arg, sizeof(PORT_VALUE)))    {    printk("copy_from_user failed.\n");    return -EFAULT;    }  printk("write: port=%d,value=%d\n", port_value.port, port_value.value);  MMPF_PIO_EnableGpioMode(port_value.port,1);  MMPF_PIO_EnableOutputMode((MMPF_PIO_REG)port_value.port,1);    MMPF_PIO_SetData((MMPF_PIO_REG) port_value.port, (MMP_BOOL) port_value.value);  }  return 0; case 'i': {PORT_VALUE *port_value = arg; //the value should be 1(enable) or 0(disable)if(0 == port_value->value)MMPF_PIO_EnableOutputMode((MMPF_PIO_REG)port_value->port,0);  MMPF_PIO_EnableInterrupt(port_value->port, port_value->value, 0, 0);printk("port_value %d %d\n",port_value->port, port_value->value);return 0;  }  default:  return -EINVAL;  }return 0;}static struct file_operations dev_fops = {.owner = THIS_MODULE,.unlocked_ioctl = gpio_ioctl,//定义的ioctl函数};static struct miscdevice misc = {.minor = MISC_DYNAMIC_MINOR,//动态分配次设备号.name = DEVICE_NAME,//设备名称.fops = &dev_fops,};/*模块初始化*/static int __init dev_init(void){int ret;ret = misc_register(&misc);printk(DEVICE_NAME "\tinitialized.\n");return ret;}static void __exit dev_exit(void){//卸载printk(DEVICE_NAME "\texit.\n");misc_deregister(&misc);}module_init(dev_init);module_exit(dev_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("luke");


gpio_reg.c:

#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <sys/ioctl.h>#define DEV_NAME "/dev/gpio_access"typedef struct port_value_struct {int port;int value;} PORT_VALUE;void write_gpio(int port, int value){int fd;PORT_VALUE port_value;fd = open(DEV_NAME, O_RDONLY);if (fd < 0)  {  printf("gpio_access open fail\n");  return;  }port_value.port = port;port_value.value = value;printf("write_gpio():port=%d,value=%d\n", port, value);if (ioctl(fd, 'w', &port_value) < 0)  {  printf("ioctl w error\n");  }close(fd);}void interrupt_gpio(int port, int value){int fd;PORT_VALUE port_value;fd = open(DEV_NAME, O_RDONLY);if (fd < 0)  {  printf("gpio_access open fail\n");  return;  }port_value.port = port;port_value.value = value;printf("interrupt_gpio():port=%d,value=%d\n", port, value);if (ioctl(fd, 'i', &port_value) < 0)  {  printf("ioctl i error\n");  }close(fd);}void read_gpio(int port){int fd;PORT_VALUE port_value;port_value.port = port;fd = open(DEV_NAME, O_RDONLY);if (fd < 0)  {  printf("gpio_access open fail\n");  return;  }if (ioctl(fd, 'r', &port_value) < 0)  {  printf("ioctl r error\n");  close(fd);  return;  }printf("read_gpio():port=%d,value=%d\n", port, port_value.value);close(fd);}void usage(char *cmd){printf("*****luke gpio_reg V1.1*************\n");printf("Usage: %s r <port> - read value of the port\n", cmd);printf("       %s w <port> <value>- write value to the port\n", cmd);printf("       %s i <port> <value>- enable/disable interrupt of the port\n", cmd);printf("eg:ds1302_reg r 62\n");printf("   ds1302_reg w 62 1\n");printf("   ds1302_reg i 62 1\n");printf("\n");}void main(int argc, char *argv[]){//printf("argc=%d",argc);if (argc < 2)  {  usage(argv[0]);  return;  }if (argv[1][0] != 'r' && argv[1][0] != 'w' && argv[1][0] != 'i')  {  usage(argv[0]);  return;  }if ((argv[1][0] == 'r' && argc != 3))  {  usage(argv[0]);  return;  }if (argv[1][0] == 'w' && argc != 4)  {  usage(argv[0]);  return;  }if (argv[1][0] == 'i' && argc != 4)  {  usage(argv[0]);  return;  }switch (argv[1][0])  {  case 'r':  read_gpio(strtoul(argv[2], NULL, 10));  break;  case 'w':  write_gpio(strtoul(argv[2], NULL, 10), strtoul(argv[3], NULL, 10));  break;  case 'i':  interrupt_gpio(strtoul(argv[2], NULL, 10), strtoul(argv[3], NULL, 10));  break;  }}



0 0
原创粉丝点击