国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【編寫LED驅(qū)動,創(chuàng)建三個設(shè)備文件,每一個設(shè)備文件和一個LED燈綁定,當(dāng)操作這個設(shè)備文件時只能控制對應(yīng)的這盞燈】

這篇具有很好參考價值的文章主要介紹了【編寫LED驅(qū)動,創(chuàng)建三個設(shè)備文件,每一個設(shè)備文件和一個LED燈綁定,當(dāng)操作這個設(shè)備文件時只能控制對應(yīng)的這盞燈】。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

作業(yè):

編寫LED驅(qū)動,創(chuàng)建三個設(shè)備文件,每一個設(shè)備文件和一個LED燈綁定,當(dāng)操作這個設(shè)備文件時只能控制對應(yīng)的這盞燈。
1.將GPIO的相關(guān)寄存器封裝成結(jié)構(gòu)體 --------> head.h
2.LED相關(guān)驅(qū)動文件 --------> led.c
led0 ------> LED1
led1 ------> LED2
led2 ------> LED3
3.應(yīng)用層測試文件 --------> test.c

head.h

#ifndef __HEAD_H__
#define __HEAD_H__
 
//定義寄存器組織結(jié)構(gòu)體
typedef struct{
    unsigned int moder;
    unsigned int otyper;
    unsigned int ospeedr;
    unsigned int pupdr;
    unsigned int idr;
    unsigned int odr;
}gpio_t;
//定義GPIOE和GPIOF
#define GPIOE 0X50006000 //LED1 PE10  LED3 PE8
#define GPIOF 0X50007000 //LED2 PF10
//#define GPIOB 0X50003000
#define RCC 0X50000A28

#define LED_ON _IOW('l',1,int)
#define LED_OFF _IOW('l',0,int)

#endif

test.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include "head.h"

int main(int argc, char const *argv[])
{
    int a, b;
    char buf[128] = {0};
    int fd_led1 = open("/dev/led0", O_RDWR);
    if (fd_led1 < 0)
    {
        printf("打開LED1設(shè)備文件失敗\n");
        exit(-1);
    }
    int fd_led2 = open("/dev/led1", O_RDWR);
    if (fd_led2 < 0)
    {
        printf("打開LED2設(shè)備文件失敗\n");
        exit(-1);
    }
    int fd_led3 = open("/dev/led2", O_RDWR);
    if (fd_led3 < 0)
    {
        printf("打開LED3設(shè)備文件失敗\n");
        exit(-1);
    }

    while (1)
    {
        // 從終端讀取
        printf("請選擇LED1燈功能\n");
        printf("0(關(guān)) 1(開)>");
        scanf("%d", &a);
        printf("請輸入要控制的燈\n");
        printf("0(LED1) 1(LED2) 2(LED3)>");
        scanf("%d", &b);
        if (a == 1) // 開燈
        {
			switch (b)
			{
			case 0:
           	    ioctl(fd_led1, LED_ON, b);
				break;
			case 1:
           	    ioctl(fd_led2, LED_ON, b);
				break;
			case 2:
           	    ioctl(fd_led3, LED_ON, b);
				break;
			}
        }
        else if (a == 0) // 關(guān)燈
        {			
			switch (b)
			{
			case 0:
           	    ioctl(fd_led1, LED_OFF, b);
				break;
			case 1:
           	    ioctl(fd_led2, LED_OFF, b);
				break;
			case 2:
           	    ioctl(fd_led3, LED_OFF, b);
				break;
			}
        }
    }
    close(fd_led1);
    close(fd_led2);
    close(fd_led3);
    return 0;
}


led0.c

#include <linux/init.h>
#include <linux/module.h>
#include<linux/fs.h>
#include<linux/device.h>
#include<linux/cdev.h>
#include<linux/slab.h>
#include<linux/io.h>
#include "head.h"

struct cdev *cdev; 		//字符設(shè)備空間首地址
unsigned int major=500; //靜態(tài)申請設(shè)備號
unsigned int minor=0;//次設(shè)備號的起始值
dev_t devno; 		//動態(tài)申請設(shè)備號
struct class *cls;  //接收注冊結(jié)構(gòu)體的地址
struct device *dev; //設(shè)備號

gpio_t *vir_gpioe;
gpio_t *vir_gpiof;
unsigned int *vir_rcc;

int mycdev_open(struct inode *inode, struct file *file)
{
	unsigned int aaa = MINOR(inode->i_rdev);  	//得到次設(shè)備號aaa
	file->private_data = (void *)aaa;

    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}

long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	unsigned int aaa = (int)file->private_data;    //次設(shè)備號
    // 功能控制
    switch (cmd)
    {
    case LED_ON:
        switch (aaa)
        {
        case 0:
            vir_gpioe->odr |= (0x1 << 10);
            break;
        }
        break;
    case LED_OFF:
        switch (aaa)
        {
        case 0:
            vir_gpioe->odr &= (~(0x1 << 10));
            break;
        }
        break;
    }
    return 0;
}

int mycdev_close(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}

// 定義操作方法結(jié)構(gòu)體變量并賦值
struct file_operations fops = {

    .open = mycdev_open,
    .unlocked_ioctl = mycdev_ioctl,
    .release = mycdev_close,
};

static int __init mycdev_init(void)   //寄存器地址映射和初始化
{
    int ret; 				//ret返回錯誤碼 

	// 映射物理地址
    vir_gpioe = ioremap(GPIOE, sizeof(gpio_t));
    if (vir_gpioe == NULL)
    {
        printk("MODER寄存器映射失敗\n");
        return -EFAULT;
    }

    vir_rcc = ioremap(RCC, 4);
    if (vir_rcc == NULL)
    {
        printk("RCC寄存器映射失敗\n");
        return -EFAULT;
    }

    vir_gpiof = ioremap(GPIOF, sizeof(gpio_t));
    if (vir_gpiof == NULL)
    {
        printk("MODER寄存器映射失敗\n");
        return -EFAULT;
    }
    printk("寄存器映射成功\n");

    //1.分配字符設(shè)備驅(qū)動對象空間  cdev_alloc
    cdev=cdev_alloc(); 		//字符設(shè)備空間首地址
    if(cdev==NULL)
    {
        printk("申請字符設(shè)備驅(qū)動對象空間失敗\n");
        ret=-EFAULT;
        goto out1;
    }
    printk("字符設(shè)備驅(qū)動對象申請成功\n");

    //2.字符設(shè)備驅(qū)動對象部分初始化  cdev_init
    cdev_init(cdev,&fops);

    //3.申請設(shè)備號  register_chrdev_region/alloc_chrdev_region
    if(major>0)//靜態(tài)申請設(shè)備號
    {
        ret=register_chrdev_region(MKDEV(major,minor),1,"led0"); //設(shè)備號需要是組合出來的,次設(shè)備數(shù)量,設(shè)備文件名
        if(ret)
        {
            printk("靜態(tài)指定設(shè)備號失敗\n");
            goto out2;
        }
    }
    else//動態(tài)申請設(shè)備號
    {
        ret=alloc_chrdev_region(&devno,minor,1,"led0");   //動態(tài)申請設(shè)備號,次設(shè)備號,設(shè)備數(shù)量,文件名
         if(ret)
        {
            printk("動態(tài)申請設(shè)備號失敗\n");
            goto out2;
        }
        major=MAJOR(devno); 	//根據(jù)設(shè)備號得到主設(shè)備號
        minor=MINOR(devno); 	//根據(jù)設(shè)備號得到次設(shè)備號
    }
    printk("申請設(shè)備號成功\n");

    //4.注冊字符設(shè)備驅(qū)動對象  cdev_add()
    ret=cdev_add(cdev,MKDEV(major,minor),1); //字符設(shè)備,設(shè)備號,設(shè)備數(shù)量
    if(ret)
    {
        printk("注冊字符設(shè)備驅(qū)動對象失敗\n");
        goto out3;
    }
    printk("注冊字符設(shè)備驅(qū)動對象成功\n");

    //5.向上提交目錄
    cls=class_create(THIS_MODULE,"led0"); //指向自身的指針,文件名
    if(IS_ERR(cls))
    {
        printk("向上提交目錄失敗\n");
        ret=-PTR_ERR(cls);
        goto out4;
    }
    printk("向上提交目錄成功\n");

    //6.向上提交設(shè)備節(jié)點
    dev=device_create(cls,NULL,MKDEV(major,0),NULL,"led0"); //創(chuàng)建設(shè)備節(jié)點
    if(IS_ERR(dev))
    {
        printk("向上提交節(jié)點信息失敗\n");
        ret=-PTR_ERR(dev);
        goto out5;
    }
    printk("向上提交設(shè)備節(jié)點信息成功\n");

     (*vir_rcc) |= (0x3 << 4);
    // 寄存器初始化led1
    vir_gpioe->moder &= (~(0x3 << 20));
    vir_gpioe->moder |= (0x1 << 20);
    vir_gpioe->odr &= (~(0x1 << 10));
    printk("LED1硬件寄存器初始化成功\n");
    return 0;

out5:
    //銷毀上面提交的設(shè)備信息
    device_destroy(cls,MKDEV(major,0));
    class_destroy(cls);
out4:
    cdev_del(cdev);
out3:
    unregister_chrdev_region(MKDEV(major,minor),1);
out2:
    kfree(cdev);
out1:
    return ret;
}
static void __exit mycdev_exit(void)
{
    //1.銷毀設(shè)備信息  device_destroy
    device_destroy(cls,MKDEV(major,0));
    //2.銷毀目錄  class_destroy
    class_destroy(cls);
    //3.注銷對象  cdev_del()
    cdev_del(cdev);
    //4.釋放設(shè)備號   unregister_chrdev_region()
    unregister_chrdev_region(MKDEV(major,minor),1);
    //5.釋放對象空間  kfree()
    kfree(cdev);

	// 取消寄存器地址映射
    iounmap(vir_gpioe);
    iounmap(vir_rcc);
    iounmap(vir_gpiof);
    // 銷毀設(shè)備節(jié)點信息
	device_destroy(cls, MKDEV(major, 0));
	// 銷毀字符設(shè)備驅(qū)動
    class_destroy(cls);
    // 字符設(shè)備驅(qū)動的注銷
    unregister_chrdev(major, "led0");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");


led1.c

#include <linux/init.h>
#include <linux/module.h>
#include<linux/fs.h>
#include<linux/device.h>
#include<linux/cdev.h>
#include<linux/slab.h>
#include<linux/io.h>
#include "head.h"

struct cdev *cdev; 		//字符設(shè)備空間首地址
unsigned int major=500; //靜態(tài)申請設(shè)備號
unsigned int minor=1;//次設(shè)備號的起始值
dev_t devno; 		//動態(tài)申請設(shè)備號
struct class *cls;  //接收注冊結(jié)構(gòu)體的地址
struct device *dev; //設(shè)備號

gpio_t *vir_gpioe;
gpio_t *vir_gpiof;
unsigned int *vir_rcc;

int mycdev_open(struct inode *inode, struct file *file)
{
	unsigned int aaa = MINOR(inode->i_rdev);  	//得到次設(shè)備號aaa
	file->private_data = (void *)aaa;

    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}

long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	unsigned int aaa = (int)file->private_data;    //次設(shè)備號
    // 功能控制
    switch (cmd)
    {
    case LED_ON:
        switch (aaa)
        {
        case 1:
            vir_gpiof->odr |= (0x1 << 10);
            break;
        }
        break;
    case LED_OFF:
        switch (aaa)
        {
        case 1:
            vir_gpiof->odr &= (~(0x1 << 10));
            break;
        }
        break;
    }
    return 0;
}

int mycdev_close(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}

// 定義操作方法結(jié)構(gòu)體變量并賦值
struct file_operations fops = {

    .open = mycdev_open,
    .unlocked_ioctl = mycdev_ioctl,
    .release = mycdev_close,
};

static int __init mycdev_init(void)   //寄存器地址映射和初始化
{
    int ret; 				//ret返回錯誤碼

	// 映射物理地址
    vir_gpioe = ioremap(GPIOE, sizeof(gpio_t));
    if (vir_gpioe == NULL)
    {
        printk("MODER寄存器映射失敗\n");
        return -EFAULT;
    }

    vir_rcc = ioremap(RCC, 4);
    if (vir_rcc == NULL)
    {
        printk("RCC寄存器映射失敗\n");
        return -EFAULT;
    }

    vir_gpiof = ioremap(GPIOF, sizeof(gpio_t));
    if (vir_gpiof == NULL)
    {
        printk("MODER寄存器映射失敗\n");
        return -EFAULT;
    }
    printk("寄存器映射成功\n");

    //1.分配字符設(shè)備驅(qū)動對象空間  cdev_alloc
    cdev=cdev_alloc(); 		//字符設(shè)備空間首地址
    if(cdev==NULL)
    {
        printk("申請字符設(shè)備驅(qū)動對象空間失敗\n");
        ret=-EFAULT;
        goto out1;
    }
    printk("字符設(shè)備驅(qū)動對象申請成功\n");

    //2.字符設(shè)備驅(qū)動對象部分初始化  cdev_init
    cdev_init(cdev,&fops);

    //3.申請設(shè)備號  register_chrdev_region/alloc_chrdev_region
    if(major>0)//靜態(tài)申請設(shè)備號
    {
        ret=register_chrdev_region(MKDEV(major,minor),1,"led1"); //設(shè)備號需要是組合出來的,次設(shè)備數(shù)量,設(shè)備文件名
        if(ret)
        {
            printk("靜態(tài)指定設(shè)備號失敗\n");
            goto out2;
        }
    }
    else//動態(tài)申請設(shè)備號
    {
        ret=alloc_chrdev_region(&devno,minor,1,"led1");   //動態(tài)申請設(shè)備號,次設(shè)備號,設(shè)備數(shù)量,文件名
         if(ret)
        {
            printk("動態(tài)申請設(shè)備號失敗\n");
            goto out2;
        }
        major=MAJOR(devno); 	//根據(jù)設(shè)備號得到主設(shè)備號
        minor=MINOR(devno); 	//根據(jù)設(shè)備號得到次設(shè)備號
    }
    printk("申請設(shè)備號成功\n");

    //4.注冊字符設(shè)備驅(qū)動對象  cdev_add()
    ret=cdev_add(cdev,MKDEV(major,minor),1); //字符設(shè)備,設(shè)備號,設(shè)備數(shù)量
    if(ret)
    {
        printk("注冊字符設(shè)備驅(qū)動對象失敗\n");
        goto out3;
    }
    printk("注冊字符設(shè)備驅(qū)動對象成功\n");

    //5.向上提交目錄
    cls=class_create(THIS_MODULE,"led1"); //指向自身的指針,文件名
    if(IS_ERR(cls))
    {
        printk("向上提交目錄失敗\n");
        ret=-PTR_ERR(cls);
        goto out4;
    }
    printk("向上提交目錄成功\n");

    //6.向上提交設(shè)備節(jié)點
    dev=device_create(cls,NULL,MKDEV(major,1),NULL,"led1"); //創(chuàng)建設(shè)備節(jié)點
    if(IS_ERR(dev))
    {
        printk("向上提交節(jié)點信息失敗\n");
        ret=-PTR_ERR(dev);
        goto out5;
    }
    printk("向上提交設(shè)備節(jié)點信息成功\n");

     (*vir_rcc) |= (0x3 << 4);
    // 寄存器初始化led1
    vir_gpiof->moder &= (~(0x3 << 20));
    vir_gpiof->moder |= (0x1 << 20);
    vir_gpiof->odr &= (~(0x1 << 10));
    printk("LED2硬件寄存器初始化成功\n");
    return 0;

out5:
    //銷毀上面提交的設(shè)備信息
    device_destroy(cls,MKDEV(major,1));
    class_destroy(cls);
out4:
    cdev_del(cdev);
out3:
    unregister_chrdev_region(MKDEV(major,minor),1);
out2:
    kfree(cdev);
out1:
    return ret;
}
static void __exit mycdev_exit(void)
{
    //1.銷毀設(shè)備信息  device_destroy
    device_destroy(cls,MKDEV(major,1));
    //2.銷毀目錄  class_destroy
    class_destroy(cls);
    //3.注銷對象  cdev_del()
    cdev_del(cdev);
    //4.釋放設(shè)備號   unregister_chrdev_region()
    unregister_chrdev_region(MKDEV(major,minor),1);
    //5.釋放對象空間  kfree()
    kfree(cdev);

	// 取消寄存器地址映射
    iounmap(vir_gpioe);
    iounmap(vir_rcc);
    iounmap(vir_gpiof);
    // 銷毀設(shè)備節(jié)點信息
	device_destroy(cls, MKDEV(major, 1));
	// 銷毀字符設(shè)備驅(qū)動
    class_destroy(cls);
    // 字符設(shè)備驅(qū)動的注銷
    unregister_chrdev(major, "led1");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");


led2.c

#include <linux/init.h>
#include <linux/module.h>
#include<linux/fs.h>
#include<linux/device.h>
#include<linux/cdev.h>
#include<linux/slab.h>
#include<linux/io.h>
#include "head.h"

struct cdev *cdev; 		//字符設(shè)備空間首地址
unsigned int major=500; //靜態(tài)申請設(shè)備號
unsigned int minor=2;//次設(shè)備號的起始值
dev_t devno; 		//動態(tài)申請設(shè)備號
struct class *cls;  //接收注冊結(jié)構(gòu)體的地址
struct device *dev; //設(shè)備號

gpio_t *vir_gpioe;
gpio_t *vir_gpiof;
unsigned int *vir_rcc;

int mycdev_open(struct inode *inode, struct file *file)
{
	unsigned int aaa = MINOR(inode->i_rdev);  	//得到次設(shè)備號aaa
	file->private_data = (void *)aaa;

    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}

long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	unsigned int aaa = (int)file->private_data;    //次設(shè)備號
    // 功能控制
    switch (cmd)
    {
    case LED_ON:
        switch (aaa)
        {
        case 2:
            vir_gpioe->odr |= (0x1 << 8);
            break;
        }
        break;
    case LED_OFF:
        switch (aaa)
        {
        case 2:
            vir_gpioe->odr &= (~(0x1 << 8));
            break;
        }
        break;
    }
    return 0;
}

int mycdev_close(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}

// 定義操作方法結(jié)構(gòu)體變量并賦值
struct file_operations fops = {

    .open = mycdev_open,
    .unlocked_ioctl = mycdev_ioctl,
    .release = mycdev_close,
};

static int __init mycdev_init(void)   //寄存器地址映射和初始化
{
    int ret; 				//ret返回錯誤碼 

	// 映射物理地址
    vir_gpioe = ioremap(GPIOE, sizeof(gpio_t));
    if (vir_gpioe == NULL)
    {
        printk("MODER寄存器映射失敗\n");
        return -EFAULT;
    }

    vir_rcc = ioremap(RCC, 4);
    if (vir_rcc == NULL)
    {
        printk("RCC寄存器映射失敗\n");
        return -EFAULT;
    }

    vir_gpiof = ioremap(GPIOF, sizeof(gpio_t));
    if (vir_gpiof == NULL)
    {
        printk("MODER寄存器映射失敗\n");
        return -EFAULT;
    }
    printk("寄存器映射成功\n");

    //1.分配字符設(shè)備驅(qū)動對象空間  cdev_alloc
    cdev=cdev_alloc(); 		//字符設(shè)備空間首地址
    if(cdev==NULL)
    {
        printk("申請字符設(shè)備驅(qū)動對象空間失敗\n");
        ret=-EFAULT;
        goto out1;
    }
    printk("字符設(shè)備驅(qū)動對象申請成功\n");

    //2.字符設(shè)備驅(qū)動對象部分初始化  cdev_init
    cdev_init(cdev,&fops);

    //3.申請設(shè)備號  register_chrdev_region/alloc_chrdev_region
    if(major>0)//靜態(tài)申請設(shè)備號
    {
        ret=register_chrdev_region(MKDEV(major,minor),1,"led2"); //設(shè)備號需要是組合出來的,次設(shè)備數(shù)量,設(shè)備文件名
        if(ret)
        {
            printk("靜態(tài)指定設(shè)備號失敗\n");
            goto out2;
        }
    }
    else//動態(tài)申請設(shè)備號
    {
        ret=alloc_chrdev_region(&devno,minor,1,"led2");   //動態(tài)申請設(shè)備號,次設(shè)備號,設(shè)備數(shù)量,文件名
         if(ret)
        {
            printk("動態(tài)申請設(shè)備號失敗\n");
            goto out2;
        }
        major=MAJOR(devno); 	//根據(jù)設(shè)備號得到主設(shè)備號
        minor=MINOR(devno); 	//根據(jù)設(shè)備號得到次設(shè)備號
    }
    printk("申請設(shè)備號成功\n");

    //4.注冊字符設(shè)備驅(qū)動對象  cdev_add()
    ret=cdev_add(cdev,MKDEV(major,minor),1); //字符設(shè)備,設(shè)備號,設(shè)備數(shù)量
    if(ret)
    {
        printk("注冊字符設(shè)備驅(qū)動對象失敗\n");
        goto out3;
    }
    printk("注冊字符設(shè)備驅(qū)動對象成功\n");

    //5.向上提交目錄
    cls=class_create(THIS_MODULE,"led2"); //指向自身的指針,文件名
    if(IS_ERR(cls))
    {
        printk("向上提交目錄失敗\n");
        ret=-PTR_ERR(cls);
        goto out4;
    }
    printk("向上提交目錄成功\n");

    //6.向上提交設(shè)備節(jié)點
    dev=device_create(cls,NULL,MKDEV(major,2),NULL,"led2"); //創(chuàng)建設(shè)備節(jié)點
    if(IS_ERR(dev))
    {
        printk("向上提交節(jié)點信息失敗\n");
        ret=-PTR_ERR(dev);
        goto out5;
    }
    printk("向上提交設(shè)備節(jié)點信息成功\n");

     (*vir_rcc) |= (0x3 << 4);
    // 寄存器初始化led1
    vir_gpioe->moder &= (~(0x3 << 16));
    vir_gpioe->moder |= (0x1 << 16);
    vir_gpioe->odr &= (~(0x1 << 8));
    printk("LED1硬件寄存器初始化成功\n");
    return 0;

out5:
    //銷毀上面提交的設(shè)備信息
    device_destroy(cls,MKDEV(major,2));
    class_destroy(cls);
out4:
    cdev_del(cdev);
out3:
    unregister_chrdev_region(MKDEV(major,minor),1);
out2:
    kfree(cdev);
out1:
    return ret;
}
static void __exit mycdev_exit(void)
{
    //1.銷毀設(shè)備信息  device_destroy
    device_destroy(cls,MKDEV(major,2));
    //2.銷毀目錄  class_destroy
    class_destroy(cls);
    //3.注銷對象  cdev_del()
    cdev_del(cdev);
    //4.釋放設(shè)備號   unregister_chrdev_region()
    unregister_chrdev_region(MKDEV(major,minor),1);
    //5.釋放對象空間  kfree()
    kfree(cdev);

	// 取消寄存器地址映射
    iounmap(vir_gpioe);
    iounmap(vir_rcc);
    iounmap(vir_gpiof);
    // 銷毀設(shè)備節(jié)點信息
	device_destroy(cls, MKDEV(major, 2));
	// 銷毀字符設(shè)備驅(qū)動
    class_destroy(cls);
    // 字符設(shè)備驅(qū)動的注銷
    unregister_chrdev(major, "led2");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");


實驗結(jié)果

【編寫LED驅(qū)動,創(chuàng)建三個設(shè)備文件,每一個設(shè)備文件和一個LED燈綁定,當(dāng)操作這個設(shè)備文件時只能控制對應(yīng)的這盞燈】,底層驅(qū)動文章來源地址http://www.zghlxwxcb.cn/news/detail-528974.html

到了這里,關(guān)于【編寫LED驅(qū)動,創(chuàng)建三個設(shè)備文件,每一個設(shè)備文件和一個LED燈綁定,當(dāng)操作這個設(shè)備文件時只能控制對應(yīng)的這盞燈】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 驅(qū)動開發(fā) 字符設(shè)備驅(qū)動分部注冊實現(xiàn)LED燈

    驅(qū)動開發(fā) 字符設(shè)備驅(qū)動分部注冊實現(xiàn)LED燈

    head.h 驅(qū)動文件 應(yīng)用文件 現(xiàn)象實現(xiàn)

    2024年02月19日
    瀏覽(18)
  • Linux下LED設(shè)備驅(qū)動開發(fā)(LED燈實現(xiàn)閃爍)

    Linux下LED設(shè)備驅(qū)動開發(fā)(LED燈實現(xiàn)閃爍)

    前面我們介紹了Linux設(shè)備模型、平臺設(shè)備驅(qū)動、設(shè)備樹(device tree)、GPIO子系統(tǒng)以及pinctrl子系統(tǒng)等,大家看這篇文章之前需要提前知道的基礎(chǔ)都在這篇文章中: Linux設(shè)備模型、平臺設(shè)備驅(qū)動、設(shè)備樹(device tree)、GPIO子系統(tǒng)以及pinctrl子系統(tǒng)介紹 有部分函數(shù)沒有涉及到的最后會講解

    2024年02月17日
    瀏覽(20)
  • Linux -- 字符設(shè)備驅(qū)動--LED的驅(qū)動開發(fā)(初級框架)

    Linux -- 字符設(shè)備驅(qū)動--LED的驅(qū)動開發(fā)(初級框架)

    看原理圖確定引腳,確定引腳輸出什么電平才能點亮 / 熄滅 LED 看主芯片手冊,確定寄存器操作方法:哪些寄存器?哪些位?地址是? 編寫驅(qū)動:先寫框架,再寫硬件操作的代碼 注意 :在芯片手冊中確定的寄存器地址被稱為 物理地址 ,在 Linux 內(nèi)核中無法直接使用。 需要使

    2024年04月28日
    瀏覽(27)
  • 驅(qū)動開發(fā) day8 (設(shè)備樹驅(qū)動,按鍵中斷實現(xiàn)led亮滅)

    //編譯驅(qū)動? (注意Makefile的編譯到移植到開發(fā)板的內(nèi)核) ? ? ? ? make arch=arm //清除編譯生成文件 ? ? ? ? make clean ****************************************** //安裝驅(qū)動 ? ? ? ? insmod mycdev.ko //卸載驅(qū)動 ? ? ? ? rmmod mycdev ? 需要在內(nèi)核路徑/arch/arm/boot/dts/? 修改 stm32mp157a-fsmp1a-dts 文件 *

    2024年02月14日
    瀏覽(47)
  • QEMU學(xué)習(xí)(二):LED設(shè)備仿真及驅(qū)動開發(fā)

    QEMU學(xué)習(xí)(二):LED設(shè)備仿真及驅(qū)動開發(fā)

    在仿真led之前,先來了解一下QEMU源碼結(jié)構(gòu)及GPIO仿真原理。 QEMU源碼目錄 我們只羅列出涉及的少許文件,由此可以看出,我們要仿真的設(shè)備文件都放在hw目錄下,一般來說一個.c 文件會有一個.h 文件,它們的目錄類似。 比如 hw/gpio/imx_gpio.c 對應(yīng)的頭文件為 include/hw/gpio/imx_gpio.

    2024年02月09日
    瀏覽(22)
  • 5.2.10.應(yīng)用程序如何調(diào)用驅(qū)動 mknod /dev/test c 250 0 創(chuàng)建設(shè)備文件,應(yīng)用app 程序 調(diào)用 我們 驅(qū)動 殼子

    5.2.10.應(yīng)用程序如何調(diào)用驅(qū)動 mknod /dev/test c 250 0 創(chuàng)建設(shè)備文件,應(yīng)用app 程序 調(diào)用 我們 驅(qū)動 殼子

    5.2.10.應(yīng)用程序如何調(diào)用驅(qū)動 5.2.10.1、驅(qū)動設(shè)備文件的創(chuàng)建 (1)何為設(shè)備文件 ? ??索引驅(qū)動 (2)設(shè)備文件的關(guān)鍵信息是:設(shè)備號 = 主設(shè)備號 + 次設(shè)備號,使用ls -l去查看設(shè)備文件,就可以得到這個設(shè)備文件對應(yīng)的主次設(shè)備號。 ????????4顆LED不可能 都占用 主設(shè)備號,設(shè)備號

    2024年02月16日
    瀏覽(29)
  • 筆記:linux中LED驅(qū)動設(shè)備樹配置和用法

    設(shè)備樹中的LED驅(qū)動一般是這樣寫,LED驅(qū)動可以控制GPIO的電平變化,生成文件節(jié)點很方便 compatible = \\\"gpio-leds\\\"; 對應(yīng)了驅(qū)動中 drivers/leds/leds-gpio.c這個驅(qū)動文件 label = \\\"gpio_demo\\\"; 這個名字會在文件系統(tǒng)中生成對應(yīng)的設(shè)備節(jié)點 /sys/class/leds/gpio_demo linux,default-trigger = \\\"default-off\\\"; 指的是

    2024年02月10日
    瀏覽(19)
  • 驅(qū)動開發(fā)學(xué)習(xí)之字符設(shè)備同時點亮三盞LED燈
  • Linux 驅(qū)動開發(fā)基礎(chǔ)知識——LED 模板驅(qū)動程序的改造:設(shè)備樹(十一)

    Linux 驅(qū)動開發(fā)基礎(chǔ)知識——LED 模板驅(qū)動程序的改造:設(shè)備樹(十一)

    ?個人名片: ??作者簡介:學(xué)生 ??個人主頁:妄北y ??個人QQ:2061314755 ??個人郵箱:2061314755@qq.com ??個人WeChat:Vir2021GKBS ?? 本文由妄北y原創(chuàng),首發(fā)CSDN ?????? ??座右銘:大多數(shù)人想要改造這個世界,但卻罕有人想改造自己。 專欄導(dǎo)航: 妄北y系列專欄導(dǎo)航: C/C++的基

    2024年02月21日
    瀏覽(14)
  • 怎么編寫PCIe設(shè)備驅(qū)動程序

    怎么編寫PCIe設(shè)備驅(qū)動程序

    DocumentationPCIMSI-HOWTO.txt driversnvmehostpci.c PCI總線設(shè)備驅(qū)動模型: 右邊是pci_dev,由PCIe控制器的驅(qū)動程序掃描PCIe總線,識別出設(shè)備,并構(gòu)造、注冊pci_dev pci_dev結(jié)構(gòu)體含有豐富的信息,比如vid、pid、class、已經(jīng)分配得到的mem/io資源、INTx中斷資源 左邊是PCIe設(shè)備驅(qū)動程序pci_driver,

    2023年04月17日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包