中断控制led灯亮灭
驱动文件源码
led-key.c
#include<linux/init.h>
#include<linux/module.h>
#include<linux/of.h>
#include<linux/of_gpio.h>
#include<linux/gpio.h>
#include<linux/of_irq.h>
#include<linux/interrupt.h>
struct device_node *led_dev;
struct device_node *key_dev;
struct gpio_desc *gpiono_led_1;
struct gpio_desc *gpiono_led_2;
struct gpio_desc *gpiono_led_3;
unsigned int irqno_1;
unsigned int irqno_2;
unsigned int irqno_3;
irqreturn_t myirq_handler(int irq, void *dev){
printk("irq=%d\n",irq);
switch (irq)
{
case 71:
gpiod_set_value(gpiono_led_1,!gpiod_get_value(gpiono_led_1));
break;
case 72:
gpiod_set_value(gpiono_led_2,!gpiod_get_value(gpiono_led_2));
break;
case 73:
gpiod_set_value(gpiono_led_3,!gpiod_get_value(gpiono_led_3));
break;
}
return IRQ_HANDLED;
}
static int __init mycdev_init(void){
int ret;
led_dev = of_find_node_by_path("/leds");
if(led_dev == NULL)
{
printk("解析led灯设备树节点失败\n");
return -EFAULT;
}
printk("解析led灯设备树成功\n");
key_dev = of_find_node_by_path("/myirq");
if(key_dev == NULL)
{
printk("解析中断设备树节点失败\n");
return -EFAULT;
}
printk("解析中断设备树成功\n");
gpiono_led_1 = gpiod_get_from_of_node(led_dev,"led1-gpios",0,GPIOD_OUT_LOW,NULL);
if(IS_ERR(gpiono_led_1))
{
printk("获取GPIO号失败\n");
return -PTR_ERR(gpiono_led_1);
}
gpiono_led_2 = gpiod_get_from_of_node(led_dev,"led2-gpios",0,GPIOD_OUT_LOW,NULL);
if(IS_ERR(gpiono_led_2))
{
printk("获取GPIO号失败\n");
return -PTR_ERR(gpiono_led_2);
}
gpiono_led_3 = gpiod_get_from_of_node(led_dev,"led3-gpios",0,GPIOD_OUT_LOW,NULL);
if(IS_ERR(gpiono_led_3))
{
printk("获取GPIO号失败\n");
return -PTR_ERR(gpiono_led_3);
}
printk("申请GPIO编号成功\n");
irqno_1 = irq_of_parse_and_map(key_dev,0);
if(!irqno_1){
printk("解析中断号失败\n");
return -ENXIO;
}
printk("解析软中断号成功 irqno=%d\n",irqno_1);
irqno_2 = irq_of_parse_and_map(key_dev,1);
if(!irqno_2){
printk("解析中断号失败\n");
return -ENXIO;
}
printk("解析软中断号成功 irqno=%d\n",irqno_2);
irqno_3 = irq_of_parse_and_map(key_dev,2);
if(!irqno_3){
printk("解析中断号失败\n");
return -ENXIO;
}
printk("解析软中断号成功 irqno=%d\n",irqno_3);
//注册中断
ret = request_irq(irqno_1,myirq_handler,IRQF_TRIGGER_FALLING,"key1",NULL);
if(ret){
printk("注册中断1失败\n");
return ret;
}
//注册中断
ret = request_irq(irqno_2,myirq_handler,IRQF_TRIGGER_FALLING,"key2",NULL);
if(ret){
printk("注册中断2失败\n");
return ret;
}
//注册中断
ret = request_irq(irqno_3,myirq_handler,IRQF_TRIGGER_FALLING,"key3",NULL);
if(ret){
printk("注册中断3失败\n");
return ret;
}
printk("注册中断成功\n");
return 0;
}
static void __exit mycdev_exit(void){
free_irq(irqno_1,NULL);
free_irq(irqno_2,NULL);
free_irq(irqno_3,NULL);
gpiod_set_value(gpiono_led_1,0);
gpiod_put(gpiono_led_1);
gpiod_set_value(gpiono_led_2,0);
gpiod_put(gpiono_led_2);
gpiod_set_value(gpiono_led_3,0);
gpiod_put(gpiono_led_3);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
字符设备指令控制led灯亮灭
驱动文件
led-cmd.c文章来源:https://www.toymoban.com/news/detail-627809.html
#include<linux/init.h>
#include<linux/module.h>
#include<linux/io.h>
#include<linux/fs.h>
#include<linux/of.h>
#include<linux/of_gpio.h>
#include<linux/gpio.h>
struct device_node *led_dev;
struct gpio_desc *gpiono_led_1;
struct gpio_desc *gpiono_led_2;
struct gpio_desc *gpiono_led_3;
struct class *cls;
struct device *dev;
char kbuf[128]={0};
unsigned int major;//定义一个变量保存主设备号
//封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
long ret;
ret=copy_from_user(kbuf,ubuf,size);
switch (kbuf[0])
{
case '1':
gpiod_set_value(gpiono_led_1,!gpiod_get_value(gpiono_led_1));
break;
case '2':
gpiod_set_value(gpiono_led_2,!gpiod_get_value(gpiono_led_2));
break;
case '3':
gpiod_set_value(gpiono_led_3,!gpiod_get_value(gpiono_led_3));
break;
}
return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
void all_led_init(void){
int ret;
led_dev = of_find_node_by_path("/leds");
if(led_dev == NULL)
{
printk("解析led灯设备树节点失败\n");
//return -EFAULT;
}
gpiono_led_1 = gpiod_get_from_of_node(led_dev,"led1-gpios",0,GPIOD_OUT_LOW,NULL);
if(IS_ERR(gpiono_led_1))
{
printk("获取GPIO号失败\n");
//return -PTR_ERR(gpiono_led_1);
}
gpiono_led_2 = gpiod_get_from_of_node(led_dev,"led2-gpios",0,GPIOD_OUT_LOW,NULL);
if(IS_ERR(gpiono_led_2))
{
printk("获取GPIO号失败\n");
//return -PTR_ERR(gpiono_led_2);
}
gpiono_led_3 = gpiod_get_from_of_node(led_dev,"led3-gpios",0,GPIOD_OUT_LOW,NULL);
if(IS_ERR(gpiono_led_3))
{
printk("获取GPIO号失败\n");
// return -PTR_ERR(gpiono_led_3);
}
printk("申请GPIO编号成功\n");
}
//定义一个操作方法结构体变量并且初始化
struct file_operations fops={
.open=mycdev_open,
.release=mycdev_close,
.read=mycdev_read,
.write=mycdev_write,
};
static int __init mycdev_init(void){
//注册字符设备驱动
major=register_chrdev(0,"mychrdev",&fops);
if(major<0)
{
printk("注册字符设备驱动失败\n");
return major;
}
printk("注册字符设备驱动成功major=%d\n",major);
// 向上提交目录
cls = class_create(THIS_MODULE, "mycdev");
if (IS_ERR(cls))
{
printk("向上提交目录失败\n");
return -PTR_ERR(cls);
}
printk("向上提交目录信息成功\n");
// 向上提交设备节点信息
dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "mycdev");
if (IS_ERR(dev))
{
printk("向上提交设备节点信息失败\n");
return -PTR_ERR(dev);
}
printk("向上提交设备节点成功\n");
all_led_init();
return 0;
}
static void __exit mycdev_exit(void){
gpiod_set_value(gpiono_led_1,0);
gpiod_put(gpiono_led_1);
gpiod_set_value(gpiono_led_2,0);
gpiod_put(gpiono_led_2);
gpiod_set_value(gpiono_led_3,0);
gpiod_put(gpiono_led_3);
//注销字符设备驱动
//销毁节点信息
device_destroy(cls,MKDEV(major,0));
//销毁目录信息
class_destroy(cls);
unregister_chrdev(major,"mychrdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
应用文件
led.c文章来源地址https://www.toymoban.com/news/detail-627809.html
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{
char buf[128] = {0};
int fd = open("/dev/mycdev", O_RDWR);
if (fd < 0)
{
printf("打开设备文件失败\n");
exit(-1);
}
while (1)
{
printf("请输入控制命令:1(led1关灯/开灯)2(led2关灯/开灯)3(led3关灯/开灯)>");
fgets(buf, sizeof(buf), stdin); // 从终端输入数据到buf
buf[strlen(buf) - 1] = '\0'; // 将buf末尾的'\n'切换为'\0'
write(fd, buf, sizeof(buf));
}
close(fd);
return 0;
}
到了这里,关于arm学习之stm32设备树学习-中断控制led灯亮灭+字符设备指令控制led灯亮灭的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!