当前位置:首页 > 编程笔记 > 正文
已解决

驱动开发platform

来自网友在路上 167867提问 提问时间:2023-10-31 22:22:22阅读次数: 67

最佳答案 问答题库678位专家为你答疑解惑

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

应用层程序

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>#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: // LED1printf("LED1_ON\n");ioctl(fd1, LED_ON,&a);break;case 2: // LED2printf("LED2_ON\n");ioctl(fd2, LED_ON,&a);break;case 3: // LED3printf("LED3_ON\n");ioctl(fd3, LED_ON,&a);break;}break;case 0:switch (a){case 1: // LED1printf("LED1_OFF\n");ioctl(fd1, LED_OFF,&a);break;case 2: // LED2printf("LED2_OFF\n");ioctl(fd2, LED_OFF,&a);break;case 3: // LED3printf("LED3_OFF\n");ioctl(fd3, LED_OFF,&a);break;}break;}}close(fd1);close(fd2);close(fd3);return 0;
}

驱动代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/fs.h>
#include <linux/device.h>#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");

查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"驱动开发platform":http://eshow365.cn/6-29049-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!