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

【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】02.hello驅(qū)動程序之cdev注冊字符設(shè)備驅(qū)動程序和設(shè)置次設(shè)備號

這篇具有很好參考價值的文章主要介紹了【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】02.hello驅(qū)動程序之cdev注冊字符設(shè)備驅(qū)動程序和設(shè)置次設(shè)備號。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

一、register_chrdev

二、解決方法

2.1?alloc_chrdev_region函數(shù):注冊一系列字符設(shè)備編號

2.2?cdev_init函數(shù):初始化cdev結(jié)構(gòu)體?

2.3??cdev_add函數(shù):將字符設(shè)備添加到系統(tǒng)中

?三、驅(qū)動程序


【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】02.hello驅(qū)動程序之cdev注冊字符設(shè)備驅(qū)動程序和設(shè)置次設(shè)備號,Linux驅(qū)動開發(fā),驅(qū)動開發(fā),學(xué)習(xí),linux

一、register_chrdev

major = register_chrdev(0, "100ask_hello", &hello_drv);

【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】01.編寫第一個hello驅(qū)動+自動創(chuàng)建設(shè)備節(jié)點(不涉及硬件操作)_阿龍還在寫代碼的博客-CSDN博客

在之前的hello驅(qū)動程序中,入口函數(shù)會用?register_chrdev來注冊字符設(shè)備驅(qū)動程序,好處是方便快捷,缺點是霸占了主設(shè)備號下的所有此設(shè)備號。當我們手動創(chuàng)建一個設(shè)備節(jié)點(主設(shè)備號相同),因為有多個次設(shè)備號,所以用上面的設(shè)備節(jié)點也可以訪問hello驅(qū)動程序。

Linux內(nèi)核提供的主設(shè)備號是有限的,如果設(shè)備很多的情況下主設(shè)備號就可能不夠用了,那怎么辦呢?
解決辦法:可以在注冊驅(qū)動設(shè)備的時候,給設(shè)備分配好固定的次設(shè)備號。

二、解決方法

先定義兩個靜態(tài)全局變量

static struct cdev hello_cdev;
static dev_t dev;

2.1?alloc_chrdev_region函數(shù):注冊一系列字符設(shè)備編號

int ret;
// major = register_chrdev(0, "100ask_hello", &hello_drv);

ret = alloc_chrdev_region(&dev, 0, 2, "hello");  // dev/hello c 245 0
if (ret < 0) {
	printk(KERN_ERR "alloc_chrdev_region() failed for hello\n");
	return -EINVAL;
}
  • register_chrdev 該函數(shù)會把主設(shè)備號下所有次設(shè)備號都霸占了

  • dev為輸出變量,這個結(jié)構(gòu)體里會含有設(shè)備的主次設(shè)備號

  • 0為次設(shè)備號,2為想獲得幾個次設(shè)備號,hello為名字

  • 如果自己創(chuàng)建設(shè)備節(jié)點 mknod /dev/xyz c 245(具體數(shù)字看對應(yīng)的主設(shè)備號) 1

  • 因為有兩個次設(shè)備號,所以用上面的設(shè)備節(jié)點也可以訪問驅(qū)動程序

2.2?cdev_init函數(shù):初始化cdev結(jié)構(gòu)體?

cdev_init(&hello_cdev, &hello_drv);
  • 初始化hello_cdev,讓hello_cdev與hello_drv結(jié)構(gòu)體掛鉤

2.3??cdev_add函數(shù):將字符設(shè)備添加到系統(tǒng)中

ret = cdev_add(&hello_cdev, dev, 2);
if (ret)
{
	printk(KERN_ERR "cdev_add() failed for hello\n");
	return -EINVAL;
}
  • 添加hello_cdev 2為此設(shè)備號個數(shù)

?三、驅(qū)動程序

hello_drv.c文章來源地址http://www.zghlxwxcb.cn/news/detail-634915.html

#include "asm-generic/errno-base.h"
#include "asm/cacheflush.h"
#include "linux/cdev.h"
#include "linux/fs.h"
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mman.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/raw.h>
#include <linux/tty.h>
#include <linux/capability.h>
#include <linux/ptrace.h>
#include <linux/device.h>
#include <linux/highmem.h>
#include <linux/backing-dev.h>
#include <linux/shmem_fs.h>
#include <linux/splice.h>
#include <linux/pfn.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/uio.h>
#include <linux/uaccess.h>


static struct class *hello_class;
static struct cdev hello_cdev;
static dev_t dev;

static unsigned char hello_buf[100];

static int hello_open (struct inode *node, struct file *filp)
{
    printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    return 0;
}
static ssize_t hello_read (struct file *filp, char __user *buf, size_t size, loff_t *offset)
{
    unsigned long len = size > 100 ? 100 : size;

    printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);

    copy_to_user(buf, hello_buf, len);

    return len;
}

static ssize_t hello_write(struct file *filp, const char __user *buf, size_t size, loff_t *offset)
{
    unsigned long len = size > 100 ? 100 : size;

    printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    copy_from_user(hello_buf, buf, len);

    return len;
}

static int hello_release (struct inode *node, struct file *filp)
{
    printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    return 0;
}

/* 1. create file_operations */
static const struct file_operations hello_drv = {
    .owner      = THIS_MODULE,
	.read		= hello_read,
	.write		= hello_write,
	.open		= hello_open,
    .release    = hello_release,
};


/* 2. register_chrdev */

/* 3. entry function */
static int hello_init(void)
{
    int ret;

    //申請主次設(shè)備號的空間 主次設(shè)備號放在dev結(jié)構(gòu)體中
    //dev為輸出變量,這個結(jié)構(gòu)體里會含有設(shè)備的主次設(shè)備號
    //0為次設(shè)備號,2為想獲得幾個次設(shè)備號,hello為名字
	ret = alloc_chrdev_region(&dev, 0, 2, "hello");// dev/hello c 245 0
	if (ret < 0) {
		printk(KERN_ERR "alloc_chrdev_region() failed for hello\n");
		return -EINVAL;
	}

    //初始化hello_cdev,讓hello_cdev與hello_drv結(jié)構(gòu)體掛鉤
    cdev_init(&hello_cdev, &hello_drv);

    //添加hello_cdev 2為此設(shè)備號個數(shù)
    ret = cdev_add(&hello_cdev, dev, 2);
	if (ret)
    {
		printk(KERN_ERR "cdev_add() failed for hello\n");
		return -EINVAL;
    }
		    
	hello_class = class_create(THIS_MODULE, "hello_class");
	if (IS_ERR(hello_class)) {
		printk("failed to allocate class\n");
		return PTR_ERR(hello_class);
	}

    device_create(hello_class, NULL, dev, NULL, "hello");  /* /dev/hello */
    return 0;
}


/* 4. exit function */
static void hello_exit(void)
{
    device_destroy(hello_class, dev);

    class_destroy(hello_class);

    //unregister_chrdev(major, "100ask_hello");
    cdev_del(&hello_cdev);
    unregister_chrdev_region(dev, 2);
}


module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

到了這里,關(guān)于【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】02.hello驅(qū)動程序之cdev注冊字符設(shè)備驅(qū)動程序和設(shè)置次設(shè)備號的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】22.IMX6ULL開發(fā)板讀取ADC(以MQ-135為例)

    【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】22.IMX6ULL開發(fā)板讀取ADC(以MQ-135為例)

    IMX6ULL一共有兩個ADC,每個ADC都有八個通道,但他們共用一個ADC控制器 在imx6ull.dtsi文件中已經(jīng)幫我們定義好了adc1的節(jié)點部分信息 注意 num-channels = 2; ,這個表示指定使用ADC1的兩個通道,即通道1和通道2 如果你要使用多個ADC通道,修改這個值即可 配置ADC引腳的 pinctrl ,在自己的

    2024年02月12日
    瀏覽(60)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】15.IMX6ULL驅(qū)動開發(fā)問題記錄(sleep被kill_fasync打斷)

    【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】15.IMX6ULL驅(qū)動開發(fā)問題記錄(sleep被kill_fasync打斷)

    發(fā)現(xiàn)問題的契機: 學(xué)習(xí)異步通知的時候,自己實現(xiàn)一個功能:按鍵控制蜂鳴器,同時LED燈在閃爍 結(jié)果:LED好像也同時被按鍵控制了 最后調(diào)試結(jié)果發(fā)現(xiàn): 應(yīng)用層的 sleep 被驅(qū)動層的 kill_fasync 打斷,所以sleep沒有執(zhí)行完就重新進入下一次循環(huán)了 修改代碼后解決該問題 解決邏輯就

    2024年02月13日
    瀏覽(17)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】08.IMX6ULL通過GPIO子系統(tǒng)函數(shù)點亮LED

    【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】08.IMX6ULL通過GPIO子系統(tǒng)函數(shù)點亮LED

    通過GPIO子系統(tǒng)函數(shù)點亮LED 1、GPIO子系統(tǒng)函數(shù) 1.1 確定 led 的GPIO標號,查看內(nèi)核中的gpiochip 查看 gpiochip ,以正點原子的IMX6ULL阿爾法開發(fā)板為例 查看原理圖,發(fā)現(xiàn)led接的引腳是 GPIO1_IO3,對應(yīng) /sys/kernel/debug/gpio 中的 gpiochip0 組,gpiochip0 組從0開始算起, 所以 GPIO1_IO3 對應(yīng)的標號就

    2024年02月10日
    瀏覽(23)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】03.設(shè)置IMX6ULL開發(fā)板與虛擬機在同一網(wǎng)段(設(shè)置開發(fā)板靜態(tài)IP)

    【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】03.設(shè)置IMX6ULL開發(fā)板與虛擬機在同一網(wǎng)段(設(shè)置開發(fā)板靜態(tài)IP)

    為什么要設(shè)置IMX6ULL與虛擬機通信? 因為要把在虛擬機下編譯的文件傳到IMX6ULL開發(fā)板上運行 設(shè)置好同一網(wǎng)段,可以互ping后,可以參考這篇博客,實現(xiàn)開發(fā)板與虛擬機的文件互傳 IMX6ULL開發(fā)板與虛擬機互傳文件 一、設(shè)置windows有線網(wǎng)卡 二、配置虛擬機雙網(wǎng)卡(原本有一個NAT網(wǎng)卡

    2024年02月07日
    瀏覽(48)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】19.mmap內(nèi)存映射

    【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】19.mmap內(nèi)存映射

    mmap將一個文件或者其它對象映射進內(nèi)存 ,使得應(yīng)用層可以直接讀取到驅(qū)動層的數(shù)據(jù),無需通過copy_to_user函數(shù) 可以用于像LCD這樣的外設(shè), 需要讀寫大量數(shù)據(jù)的 一、應(yīng)用層 mmap用法: 用open系統(tǒng)調(diào)用打開文件, 并返回描述符fd. 用mmap建立內(nèi)存映射, 并返回映射首地址指針start. 對映

    2024年02月16日
    瀏覽(21)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】11.Linux之SPI驅(qū)動

    【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】11.Linux之SPI驅(qū)動

    參考:驅(qū)動程序開發(fā):SPI設(shè)備驅(qū)動_spi驅(qū)動_鄧家文007的博客-CSDN博客 目錄 一、SPI驅(qū)動簡介 1.1 SPI架構(gòu)概述 1.2 SPI適配器(控制器)數(shù)據(jù)結(jié)構(gòu) 1.2 SPI設(shè)備數(shù)據(jù)結(jié)構(gòu) 1.3 SIP設(shè)備驅(qū)動 1.4 接口函數(shù) ?二、SPI驅(qū)動模板 SPI驅(qū)動框架和I2C驅(qū)動框架是十分相似的,不同的是因為SPI是通過片選引

    2024年02月11日
    瀏覽(31)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】12.Linux驅(qū)動之設(shè)備樹

    【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】12.Linux驅(qū)動之設(shè)備樹

    承接上一篇博客 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】11.驅(qū)動設(shè)計之面向?qū)ο骭分層思想(學(xué)習(xí)設(shè)備樹過渡部分) 代碼獲取: https://gitee.com/chenshao777/imx6-ull_-drivers 我后面將三個層合并了(實際上只有前兩層),合并成一個dev_drv.c了,暫時沒有加GPIO操作,只是個框架 合并前的代碼在 11.butt

    2024年02月13日
    瀏覽(48)
  • iMX6ULL驅(qū)動開發(fā) | 讓imx6ull開發(fā)板支持usb接口FC游戲手柄

    iMX6ULL驅(qū)動開發(fā) | 讓imx6ull開發(fā)板支持usb接口FC游戲手柄

    手邊有一閑置的linux開發(fā)板iMX6ULL一直在吃灰,不用來搞點事情,總覺得對不住它。業(yè)余打發(fā)時間就玩起來吧,總比刷某音強。從某多多上買來一個usb接口的游戲手柄,讓開發(fā)板支持以下它,后續(xù)就可以接著在上面玩童年經(jīng)典游戲啦。 ?我使用的是正點原子的I.MX6U-ALPHA 開發(fā)板,

    2024年02月14日
    瀏覽(38)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】12.Linux SPI驅(qū)動實戰(zhàn):DAC驅(qū)動設(shè)計流程

    【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】12.Linux SPI驅(qū)動實戰(zhàn):DAC驅(qū)動設(shè)計流程

    基礎(chǔ)回顧:?【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】10.Linux I2C驅(qū)動實戰(zhàn):AT24C02驅(qū)動設(shè)計流程_阿龍還在寫代碼的博客-CSDN博客 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】11.Linux之SPI驅(qū)動_阿龍還在寫代碼的博客-CSDN博客 查看芯片手冊,有兩種DAC數(shù)據(jù)格式,12位和16位,這里選用16位數(shù)據(jù)(2字節(jié))編寫驅(qū)動。 ?重點在

    2024年02月11日
    瀏覽(28)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】11.驅(qū)動設(shè)計之面向?qū)ο骭分層思想(學(xué)習(xí)設(shè)備樹過渡部分)

    【IMX6ULL驅(qū)動開發(fā)學(xué)習(xí)】11.驅(qū)動設(shè)計之面向?qū)ο骭分層思想(學(xué)習(xí)設(shè)備樹過渡部分)

    一個 可移植性好 的驅(qū)動程序,應(yīng)該有三個部分組成 1、驅(qū)動框架程序(xxx_drv.c) — 對接應(yīng)用層的 open read write 函數(shù),不做GPIO具體操作 2、硬件操作程序(xxx_chip_gpio.c)— 執(zhí)行具體的GPIO操作,初始化、讀寫 3、硬件資源定義程序(xxx_board.c,這在之后就過渡成了設(shè)備樹)— 為

    2024年02月11日
    瀏覽(24)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包