注意事项,ioctl的函数参数,之前我用了static long newchar_ioctl(struct inode *inode, struct file *filep,
unsigned long cmd, unsigned long arg),发生了可以调用到驱动的ioctl但是就是无法把ioctl的参数传到驱动中,要小心
还要就是对应的gpio没找对,因为没有ic的spec,这点也要注意才对
h文件如下:
#include <linux/fb.h>
#include <linux/ioctl.h>
#define NEWCHAR_IOC_MAGIC 'a'
struct matt{
int gpio2_value;
int gpio4_value;
int gpio6_value;
};
#define GPIO_test _IO(NEWCHAR_IOC_MAGIC, 0x01)
#define GPIO_SET _IOW(NEWCHAR_IOC_MAGIC, 0x02, struct matt)
#define GPIO_GET _IOR(NEWCHAR_IOC_MAGIC, 0x03, unsigned long)
#define GPIO_m _IOW(NEWCHAR_IOC_MAGIC, 0x04, int)
驱动c文件如下
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/nodemask.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/fsl_devices.h>
#include <linux/smsc911x.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <linux/i2c.h>
#include <linux/i2c/pca953x.h>
#include <linux/ata.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/pmic_external.h>
#include <linux/pmic_status.h>
#include <linux/mxcfb.h>
#include <linux/pwm_backlight.h>
#include <linux/fec.h>
#include <linux/memblock.h>
#include <linux/gpio.h>
#include <linux/etherdevice.h>
#include <linux/regulator/anatop-regulator.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/fixed.h>
#include <linux/mfd/max17135.h>
#include <sound/wm8962.h>
#include <sound/pcm.h>
#include <linux/power/sabresd_battery.h>
#include <mach/common.h>
#include <mach/hardware.h>
#include <mach/mxc_dvfs.h>
#include <mach/memory.h>
#include <mach/iomux-mx6sl.h>
#include <mach/imx-uart.h>
#include <mach/viv_gpu.h>
#include <mach/imx_rfkill.h>
#include <asm/irq.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include "74vhc541.h"
#include <linux/types.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/console.h>
#include <linux/io.h>
#include <linux/ipu.h>
#include <linux/mxcfb.h>
#include <linux/regulator/consumer.h>
#include <linux/spinlock.h>
#include <linux/fsl_devices.h>
#include <mach/hardware.h>
#include <mach/clock.h>
#define EIM_D182
#define EIM_D174
#define EIM_D218
#define matt_gpio2 IMX_GPIO_NR(1, 2)
#define DEVICE_NAME "matt_test"
static char demo_buffer[20];
static int MAJOR_DEV_NUM =1;
static int newchar_open(struct inode *inode, struct file *filep)
{
printk( "======== matt_open ");
gpio_free(EIM_D18);
gpio_free(EIM_D17);
gpio_free(EIM_D21);
/*gpio_request(EIM_D18, "EIM_D18");
gpio_direction_output(EIM_D18, 1);
__gpio_set_value(EIM_D18, 0);
gpio_request(EIM_D17, "EIM_D17");
gpio_direction_output(EIM_D17, 1);
__gpio_set_value(EIM_D17, 0);
gpio_request(EIM_D21, "EIM_D21");
gpio_direction_output(EIM_D21, 1);
__gpio_set_value(EIM_D21, 0);*/
return 0;
}
static int newchar_release(struct inode *inode, struct file *filep)
{
/*gpio_request(EIM_D17, "EIM_D17");
gpio_direction_output(EIM_D17, 1);
__gpio_set_value(EIM_D17, 0);
gpio_request(EIM_D21, "EIM_D21");
gpio_direction_output(EIM_D21, 1);
__gpio_set_value(EIM_D21, 0);*/
printk( "======== matt_release \n");
return 0;
}
static ssize_t newchar_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
{
printk( "======== matt_read \n");
gpio_direction_output(EIM_D18, 0);
__gpio_set_value(EIM_D18, 0);
return 0;
}
ssize_t newchar_write (struct file *filp, char __user *buf, size_t count, loff_t *ppos) {
printk( "======== matt_write\n ");
ssize_t retval = -ENOMEM;
loff_t pos = *ppos;
int i;
int dat=0;
if (pos > 20)
goto out;
if (count > (256 - pos))
count = 256 - pos;
pos += count;
if (copy_from_user(demo_buffer+*ppos, buf, count)) {
retval = -EFAULT;
goto out;
}
/* if(!gpio_is_valid(EIM_D18))
{
printk( "======== matt gpio invalid \n");
}
if(!gpio_request(EIM_D18, "EIM_D18"))
{
printk( "======== matt gpio_request success\n");
}*/
printk( "======== matt_demo_buffer[i]=%c\n ",demo_buffer[0]);
dat=gpio_get_value(matt_gpio2);
printk("matt-gpio_get_value1================%d\n",dat);
if(demo_buffer[0]=='a')
{
__gpio_set_value(matt_gpio2, 0);
dat=gpio_get_value(matt_gpio2);
printk("matt-gpio_get_value=================%d\n",dat);
}else{
__gpio_set_value(matt_gpio2, 1);
dat=gpio_get_value(matt_gpio2);
printk("matt-gpio_get_value=================%d\n",dat);
}
/* for( i=0;i<7;i++)
{
__gpio_set_value(EIM_D18, 0);
printk( "======== matt_demo_buffer[i]=%c\n ",demo_buffer[i]);
}*/
*ppos = pos;
retval = count;
out:
return retval;
return 0;
}
static ssize_t gpio_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
printk( "======== matt gpio_show ");
}
static ssize_t gpio_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
printk( "======== matt gpio_store ");
return size;
}
//static DEVICE_ATTR(matt_gpio, 0664, gpio_show,gpio_store);
static long newchar_ioctl(struct file *filep,
unsigned long cmd, unsigned long arg)
{
long ret= 0;
int m=0;
printk("matt ioctl start+1\n");
ret = EINVAL;
struct matt *nc;
nc=kzalloc(sizeof(struct matt), GFP_KERNEL);
printk("matt cmd=%ld\n",GPIO_test);
printk("matt cmd1=%ld\n",GPIO_SET);
printk("matt recive cmd=%ld\n",cmd);
switch(cmd)
{
case GPIO_test:
{
printk("matt GPIO_test\n");
}
break;
case GPIO_SET:
{
printk("matt GPIO_SET\n");
if(copy_from_user(nc, (const char*)arg, sizeof(struct matt)) != 0)
{
printk("matt copy failure\n");
return -EFAULT;
}
printk("matt gpio1=%d\n",nc->gpio2_value);
printk("matt gpio2=%d\n",nc->gpio4_value);
printk("matt gpio3=%d\n",nc->gpio6_value);
}
break;
case GPIO_GET:
{
printk("matt ioctl get\n");
}
break;
}
return ret;
}
struct file_operations newchar_fops =
{
.owner = THIS_MODULE,
.unlocked_ioctl = newchar_ioctl,
.open = newchar_open,
.write =newchar_write,
.release = newchar_release,
.read = newchar_read,
};
static dev_t first; // Global variable for the first device number
static struct cdev c_dev; // Global variable for the character device structure
static struct class *cl; // Global variable for the device class
static int __init first_drv_init(void)
{
printk("======== cdevdemo_init ");
int ret;
/*
* Register btusb as a character device driver with linux OS and return
* ERROR on failure
*/
if ((cl = class_create(THIS_MODULE, DEVICE_NAME)) == NULL)
{
printk("matt erro1");
return 1;
}
if (alloc_chrdev_region(&first, 0, 1, DEVICE_NAME) < 0)
{
printk("matt erro2");
class_destroy(cl);
return 1;
}
if (device_create(cl, NULL, first, NULL, DEVICE_NAME) == NULL)
{
printk("matt erro3");
unregister_chrdev_region(first, 1);
class_destroy(cl);
return 1;
}
cdev_init(&c_dev, &newchar_fops);
if (cdev_add(&c_dev, first, 1) == -1)
{
printk("matt erro4");
device_destroy(cl, first);
unregister_chrdev_region(first, 1);
class_destroy(cl);
return 1;
}
//ret = device_create_file(&c_dev, &dev_attr_matt_gpio);
//matt
if(!gpio_direction_output(matt_gpio2, 1))
{
printk( "======== matt gpio_direction_output success\n");
}
printk( "======== matt finish");
return 0;
}
void first_drv_exit(void)
{
printk( "End cdevdemo");
device_destroy(cl, first);
cdev_del(&c_dev);
unregister_chrdev_region(first, 1);
class_destroy(cl);
}
MODULE_LICENSE("Dual BSD/GPL");
module_param(MAJOR_DEV_NUM, int, S_IRUGO);
module_init(first_drv_init);
module_exit(first_drv_exit);
测试文件如下
#include <linux/fb.h>
#include <stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <linux/ioctl.h>
#include "74vhc541.h"
#define MXCFB_SET_GBL_ALPHA _IOW('F', 0x21, struct mxcfb_gbl_alpha)
#define MXCFB_CSC_UP _IOW('F', 0x4D, int)
struct mxcfb_gbl_alpha {
int enable;
int alpha;
};
int main()
{
int fd = 0;
printf("start ioctl \n");
unsigned long arg = 0;
int x=25;
//char* buffer=NULL;
// buffer=(char*)malloc(100*sizeof(char));
struct matt lisa={
.gpio2_value=1,
.gpio4_value=0,
.gpio6_value=1,
};
struct mxcfb_gbl_alpha kk={
.enable=5,
.alpha=5,
};
printf("gpio2_value=%d\n",lisa.gpio2_value);
fd = open("/dev/matt_test",O_RDWR);
if (fd < 0)
{
printf("matt-Open Dev Mem0 Error!\n");
return -1;
}
sleep(5);
// x=read(fd,buffer,30);
// x = write(fd, "bsdfghj", 7);
printf("matt-open success \n");
printf("matt-GPIO_test=%d \n",GPIO_test);
/* if (ioctl(fd, MXCFB_SET_GBL_ALPHA,&kk) < 0)
{
printf("matt fail\n");
return -1;
}
sleep(5);*/
if (ioctl(fd, GPIO_SET,&lisa) < 0)
{
printf("Call cmd MEMDEV_IOCSETDATA fail\n");
return -1;
}
close(fd);
return 0;
}