驱动开发platform

任务 :  基于platform驱动模型完成LED驱动的编写,实现三盏灯的点亮

应用层程序

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define LED_ON 1
#define LED_OFF 0
int main(int argc, char const *argv[])
{
	// 打开第一个设备文件
	int fd1 = open("/dev/myled0", O_RDWR);
	if (fd1 < 0)
	{
		printf("打开设备文件失败\n");
		exit(-1);
	}
	// 打开第二个设备文件
	int fd2 = open("/dev/myled1", O_RDWR);
	if (fd2 < 0)
	{
		printf("打开设备文件失败\n");
		exit(-1);
	}
	// 打开第三个设备文件
	int fd3 = open("/dev/myled2", O_RDWR);
	if (fd3 < 0)
	{
		printf("打开设备文件失败\n");
		exit(-1);
	}

	while (1)
	{
		int a, b;
		// 从终端读取
		printf("请输入字符\n");
		printf("第一个字符:1(LED1) 2(LED2) 3(LED3)\n");
		scanf("%d", &a);
		printf("第二个字符:0(关灯) 1(开灯)\n");
		printf("请输入>");
		scanf("%d", &b);
		// 向设备文件中写
		switch (b)
		{
		case 1:
			switch (a)
			{
			case 1: // LED1
				printf("LED1_ON\n");
				ioctl(fd1, LED_ON,&a);
				break;
			case 2: // LED2
				printf("LED2_ON\n");
				ioctl(fd2, LED_ON,&a);
				break;
			case 3: // LED3
				printf("LED3_ON\n");
				ioctl(fd3, LED_ON,&a);
				break;
			}
			break;
		case 0:
			switch (a)
			{
			case 1: // LED1
				printf("LED1_OFF\n");
				ioctl(fd1, LED_OFF,&a);
				break;
			case 2: // LED2
				printf("LED2_OFF\n");
				ioctl(fd2, LED_OFF,&a);
				break;
			case 3: // LED3
				printf("LED3_OFF\n");
				ioctl(fd3, LED_OFF,&a);
				break;
			}
			break;
		}
	}

	close(fd1);
	close(fd2);
	close(fd3);

	return 0;
}

驱动代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define LED_ON 1
#define LED_OFF 0
struct resource *res;
int irqnum;
struct gpio_desc *gpionum1;
struct gpio_desc *gpionum2;
struct gpio_desc *gpionum3;
struct device *dev;

int major;
struct class *cls;

struct of_device_id of_tab[] =
    {
        {
            .compatible = "hqyj,myplatform",
        },
        {
            .compatible = "hqyj,myplatform1",
        },
        {},
};
// 打开文件函数
int myopen(struct inode *inode, struct file *file)
{

    return 0;
}
// 关闭文件函数
int myclose(struct inode *inode, struct file *file)
{
	int i;
	for(i = 0;i < 3;i++)
	{
		device_destroy(cls,MKDEV(major,i));
	}
	class_destroy(cls);
	unregister_chrdev(major,"mychrdev");
    return 0;
}

// io控制函数
long myioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	printk("__ioctrl__");
    int which;
    int ret = copy_from_user(&which, (void *)arg, 4);
    if (ret)
    {
        printk("copy_from_user failed\n");
        return -EIO;
    }
    printk("copy_from_user success : [%d]\n",which);
    switch (cmd)
    {
    case LED_ON:
        switch (which)
        {
        case 1:
			printk("[1] : LED_ON\n");
            gpiod_set_value(gpionum1, 1);
            break;
        case 2:
			printk("[2] : LED_ON\n");
            gpiod_set_value(gpionum2, 1);
            break;
        case 3:
			printk("[3] : LED_ON\n");
            gpiod_set_value(gpionum3, 1);
            break;
        }
        break;
    case LED_OFF:
        switch (which)
        {
        case 1:
			printk("[1] : LED_OFF\n");
            gpiod_set_value(gpionum1, 0);
            break;
        case 2:
			printk("[2] : LED_OFF\n");
            gpiod_set_value(gpionum2, 0);
            break;
        case 3:
			printk("[3] : LED_OFF\n");
            gpiod_set_value(gpionum3, 0);
            break;
        }
        break;
    }
    return 0;
}

// 操作方法结构体
struct file_operations fops = {
    .open = myopen,
    .unlocked_ioctl = myioctl,
    .release = myclose,
};

// 匹配成功函数
int pdri_probe(struct platform_device *pdev)
{
    printk("%s : %s : %d\n", __FILE__, __func__, __LINE__);

    // 字符设备注册
    major = register_chrdev(0, "mychrdev", &fops);
    if (major < 0)
    {
        printk("register_chrdev failed\n");
        return -1;
    }
    printk("register_chrdev success\n");

    // 提交上级目录
    cls = class_create(THIS_MODULE, "mychrdev");
    if (IS_ERR(cls))
    {
        printk("class_create failed\n");
        return -PTR_ERR(cls);
    }
    printk("class_create success\n");

    // 向上提交三次节点信息
    int i;
    for (i = 0; i < 3; i++)
    {
        dev = device_create(cls, NULL, MKDEV(major, i), NULL, "myled%d", i);
        if (IS_ERR(dev))
        {
            printk("[%d] : device_create failed\n", i);
            return -PTR_ERR(dev);
        }
    }
    printk("device_create success\n");

    // 获取设备信息
    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (res == NULL)
    {
        printk("MEM : platform_get_resource failed\n");
        return -1;
    }
    printk("MEN : %x\n", res->start);

    // 获取中断号信息
    irqnum = platform_get_irq(pdev, 0);
    if (irqnum < 0)
    {
        printk("IRQ : platform_get_irq failed\n");
        return -1;
    }
    printk("IRQ : %d\n", irqnum);

    // 获取LED1gpio信息
    gpionum1 = gpiod_get_from_of_node(pdev->dev.of_node, "led1-gpioe", 0, GPIOD_OUT_LOW, NULL);
    if (IS_ERR(gpionum1))
    {
        printk("gpiod_get_from_of_node failed\n");
        return PTR_ERR(gpionum1);
    }
    printk("gpiod_get_from_of_node success\n");

    // 获取LED2gpio信息
    gpionum2 = gpiod_get_from_of_node(pdev->dev.of_node, "led2-gpiof", 0, GPIOD_OUT_LOW, NULL);
    if (IS_ERR(gpionum2))
    {
        printk("gpiod_get_from_of_node failed\n");
        return PTR_ERR(gpionum2);
    }
    printk("gpiod_get_from_of_node success\n");

    // 获取LED3gpio信息
    gpionum3 = gpiod_get_from_of_node(pdev->dev.of_node, "led3-gpioe", 0, GPIOD_OUT_LOW, NULL);
    if (IS_ERR(gpionum3))
    {
        printk("gpiod_get_from_of_node failed\n");
        return PTR_ERR(gpionum3);
    }
    printk("gpiod_get_from_of_node success\n");

    return 0;
}

// 分离函数
int pdri_remove(struct platform_device *pdev)
{
    gpiod_set_value(gpionum1, 0);
    gpiod_set_value(gpionum2, 0);
    gpiod_set_value(gpionum3, 0);
    gpiod_put(gpionum1);
    gpiod_put(gpionum2);
    gpiod_put(gpionum3);
    printk("%s : %s : %d\n", __FILE__, __func__, __LINE__);
    return 0;
}

// 给驱动对象分配空间
struct platform_driver pdri = {
    .probe = pdri_probe,
    .remove = pdri_remove,
    .driver.name = "a",
    .driver.of_match_table = of_tab,
};

module_platform_driver(pdri);

MODULE_LICENSE("GPL");

你可能感兴趣的:(驱动开发)