娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

字符設備驅動(1)代碼分析---之register_chrdev

發布者:Lihua521最新更新時間:2025-02-05 來源: cnblogs關鍵字:字符設備驅動  代碼分析 手機看文章 掃描二維碼
隨時隨地手機看文章

/*****************************************************************************

簡    述:簡單字符型驅動程序,手動靜態分配設備號,手動創建設備節點

******************************************************************************/

#include <linux/module.h>

#include

#include gpio.h>

#include

#include

#include

#include


#define DEVICE_NAME        'leds'


struct button_desc {

    int gpio;

    int number;

    char *name;    

};


struct led_desc {

    int gpio;

    int number;

    char *name;    

};


static struct button_desc buttons[] = {

    { S5PV210_GPH2(0), 0, 'KEY0' },

    { S5PV210_GPH2(1), 1, 'KEY1' },

    { S5PV210_GPH2(2), 2, 'KEY2' },

    { S5PV210_GPH2(3), 3, 'KEY3' },

    { S5PV210_GPH3(0), 4, 'KEY4' },

    { S5PV210_GPH3(1), 5, 'KEY5' },

    { S5PV210_GPH3(2), 6, 'KEY6' },

    { S5PV210_GPH3(3), 7, 'KEY7' },

};


static struct led_desc leds[] = {

    {S5PV210_GPJ2(0),1,'LED1'},

    {S5PV210_GPJ2(1),2,'LED2'},    

    {S5PV210_GPJ2(2),3,'LED3'},

    {S5PV210_GPJ2(3),4,'LED4'},

};


#define OK            (0)

#define ERROR         (-1)

dev_t  devNum;

unsigned int subDevNum = 1;//要申請的次設備號個數

int reg_major  =  234;    

int reg_minor =   0;



static irqreturn_t button_interrupt(int irq, void *dev_id)

{

    struct button_desc *bdata = (struct button_desc *)dev_id;


    int down;

    unsigned tmp;

    tmp = gpio_get_value(bdata->gpio);


    /* active low */

    down = !tmp;

    printk('KEY %d: %08xn', bdata->number, down);

        

    if(bdata->number < 4)

    {

        gpio_set_value(leds[bdata->number].gpio,0);

        printk('LED %d: On n',leds[bdata->number].number);

    }

    else

    {

        gpio_set_value(leds[(bdata->number) - 4].gpio,1);

        printk('LED %d: OFF n',leds[(bdata->number)-4].number);

    }

    

    return IRQ_HANDLED;

}


int butsOpen(struct inode *p, struct file *f)

{

    

        int irq;

    int i;

    int err = 0;

    printk(KERN_EMERG'butsOpenrn');

    for (i = 0; i < ARRAY_SIZE(buttons); i++) {

        if (!buttons[i].gpio)

            continue;


        irq = gpio_to_irq(buttons[i].gpio);

        // irq = IRQ_EINT(16)+i =160+i 'S5PV210_GPH2(i)'

        //irq = IRQ_EINT(24)+i =168+i  'S5PV210_GPH3(i)'

        err = request_irq(irq, button_interrupt, IRQ_TYPE_EDGE_FALLING, 

                buttons[i].name, (void *)&buttons[i]);

        if (err)

            break;

    }

    

    for(i = 0; i    {

        if(!leds[i].gpio)

            continue;

        gpio_direction_output(leds[i].gpio,1);

    }

    

    if (err) {

        i--;

        for (; i >= 0; i--) {

            if (!buttons[i].gpio)

                continue;


            irq = gpio_to_irq(buttons[i].gpio);

            disable_irq(irq);

            free_irq(irq, (void *)&buttons[i]);

        }


        return -EBUSY;

    }

    return 0;

}


static const struct file_operations gFile = 

{

    .owner = THIS_MODULE,

    .open  =  butsOpen,    

};



int charDrvInit(void)

{

    

    devNum = MKDEV(reg_major, reg_minor);

    printk(KERN_EMERG'devNum is %drn', devNum);

   

    if(OK == register_chrdev(reg_major, DEVICE_NAME, &gFile))

    {

        printk(KERN_EMERG 'register_chrdev_region okrn');

    }

    else

    {

        printk(KERN_EMERG'register_chrdev_region errorrn');

        return ERROR;

    }

    

    printk(KERN_EMERG 'button driver initial done...rn');

    return 0;

}


void __exit charDrvExit(void)

{

    int i,irq;

    unregister_chrdev(reg_major, DEVICE_NAME);

    for (i = 0; i < ARRAY_SIZE(buttons); i++) {

            if (!buttons[i].gpio)

                continue;


            irq = gpio_to_irq(buttons[i].gpio);

            disable_irq(irq);

            free_irq(irq, (void *)&buttons[i]);

        }

    

    return;

}

module_init(charDrvInit);//執行insmod時會執行此行代碼并調用charDrvInit,驅動開始

module_exit(charDrvExit);//執行rmmod時,結束

MODULE_LICENSE('GPL');

MODULE_AUTHOR('LiuB');

復制代碼

res = register_chrdev(I2C_MAJOR, 'i2c', &i2cdev_fops);

復制代碼

res = register_chrdev(I2C_MAJOR, 'i2c', &i2cdev_fops);

    static inline int register_chrdev(unsigned int major, const char *name,

                  const struct file_operations *fops)

    {

        return __register_chrdev(major, 0, 256, name, fops);

            

    }

    int __register_chrdev(unsigned int major, unsigned int baseminor,

              unsigned int count, const char *name,const struct file_operations *fops)

    {    

        struct char_device_struct *cd;

        struct cdev *cdev;

            cd = __register_chrdev_region(major, baseminor, count, name);

                {

                    struct char_device_struct *cd, **cp;

                    cd = kzalloc(sizeof(struct char_device_struct), GFP_KERNEL);

                    cd->major = major;

                    cd->baseminor = baseminor;

                    cd->minorct = minorct;

                    strlcpy(cd->name, name, sizeof(cd->name));

                    i = major_to_index(major);

                    for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)

                    。。。。。

                    //找到可以添加新的設備的位置*cp

            //此處cd為鏈表中唯一節點,cd->next = NULL,所以這句代碼相當于在cd鏈表后添加一個節點*cp

                    cd->next = *cp;

                    //繼續讓cd指向鏈表尾

                    *cp = cd;

                    mutex_unlock(&chrdevs_lock);

                    return cd;

                }

            cdev = cdev_alloc();//給局部結構體變量cdev分配空間

            //將register_chrdev(I2C_MAJOR, 'i2c', &i2cdev_fops)中的i2cdev_fops結構體的具體內容賦給新建的cdev結構體

            cdev->owner = fops->owner;

            cdev->ops = fops;

            kobject_set_name(&cdev->kobj, '%s', name);

            //添加設備

            err = cdev_add(cdev, MKDEV(cd->major, baseminor), count);

                {

                    //dev= MKDEV(cd->major, baseminor)

                    cdev->dev = dev;//添加設備號

                    cdev->count = count;//設備個數

                    //將指定的設備號加入到管理設備號及其對應設備的kobj_map結構體中的probe數組中

                    return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);

                }

            cd->cdev = cdev;//將賦值完成的cdev傳到結構體cd中的cdev結構體成員

            return major ? 0 : cd->major;

    }


for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)

退出for循環的四種情況:
1、已存在的主設備號大于即將新添加的主設備號
2、已存在的主設備號等于即將新添加的主設備號&&并且次設備最小號大于新注冊的次設備最小號
3、已存在的主設備號等于即將新添加的主設備號&&次設備最小號等于新注冊的次設備最小號
4、已存在的主設備號等于即將新添加的主設備號&&次設備最小號小于新注冊的次設備最小號&&新注冊的次設備最小號小于已存在的次設備號范圍(最小號+個數)
注:
1、對于第一種情況跳過下面的if判斷注冊到鏈表中
2、對于第二、三、四種情況在跳出for循環后繼續進行下面判斷來分析是否沖突,如果不沖突則注冊到鏈表中

[1] [2]
關鍵字:字符設備驅動  代碼分析 引用地址:字符設備驅動(1)代碼分析---之register_chrdev

上一篇:字符設備驅動(1)代碼分析---之gpio_get_value
下一篇:三星S5-PV210內存初始化

推薦閱讀最新更新時間:2025-04-23 17:43

中斷喚醒的代碼案例及分析
生活上有很多東西都搭載著單片機而進行工作的,而且有相當一部分的設備、儀器、產品都是靠蓄電池來提供電源的,往往這些靠蓄電池供電的設備、儀器、產品都能夠用上一大段時間。例如我們經常接觸到的遙控器,假若MCU一直不停地運行,不出一段時間,電池的能量會很快耗光。當然在8051系列單片機搭載的系統中,不光有單片機需要耗電,同時還有其他外圍部件耗電的,因此,我們在適當的時候關閉設備的運行同時將8051系列單片機的運行模式進入空閑模式或者掉電模式,以節省不必要的能源,達到低功耗的目的。 平時8051系列單片機正常工作的電流為4毫安~7毫安;當8051系列單片機進入掉電模式下,它的工作電流小于1微安。由此可見,低功耗設備的功耗控制很有必要在適
[單片機]
STM8S匯編代碼分析
br data-filtered= filtered 其中.asm文件是匯編代碼的源文件,.inc文件是包含文件,類似于 a class= replace_word title= C語言知識庫 href= http://lib.csdn.net/base/c target= _blank C語言 /a 當在的.c文件和.h文件。接下來讓我們來分析一下這三個文件。(分析匯編代碼最好也要對STM8單片機的啟動流程有所了解,可以看我的另一篇博文 a href= http://blog.csdn.net/u010093140/article/details/49982879 http://blog.csdn.net/u01009314
[單片機]
STM8S匯編<font color='red'>代碼</font><font color='red'>分析</font>
51單片機RS232串口通信代碼分析
一、串口初始化 void usart_init() { SCON = 0x50; //REN=1允許串行接受狀態,串口工作模式1 TMOD = 0x20; //定時器工作方式2 PCON = 0x00; TH1 = 0xFD; //波特率9600、數據位8、停止位1。效驗位無 (11.0592M) TL1 = 0xFD; ES = 1; //開串口中斷 EA = 1; //開總中斷 TR1 = 1; //啟動定時器 } SCON寄存器 1.SM0、SM1:串行口工作方式控制位 2.SM2:多機通信控制位 3.REN:允許接收位 4.TB8:發送接收數據位8 5.RB8:接收數據位8 6.TI:發送中斷標志位 TI=1表
[單片機]
51單片機RS232串口通信<font color='red'>代碼</font><font color='red'>分析</font>
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 奇台县| 四平市| 常熟市| 滨海县| 兴安盟| 衡东县| 沧源| 临泉县| 屯留县| 从化市| 大荔县| 响水县| 彝良县| 静宁县| 佛教| 兴城市| 鹤峰县| 新津县| 商洛市| 英超| 新源县| 礼泉县| 威信县| 汕头市| 汝阳县| 广丰县| 清流县| 砀山县| 齐齐哈尔市| 永城市| 都兰县| 玛沁县| 香格里拉县| 岚皋县| 凤冈县| 当阳市| 如东县| 亚东县| 南阳市| 杭锦后旗| 肃北|