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

【IMX6ULL驅(qū)動開發(fā)學(xué)習】01.編寫第一個hello驅(qū)動+自動創(chuàng)建設(shè)備節(jié)點(不涉及硬件操作)

這篇具有很好參考價值的文章主要介紹了【IMX6ULL驅(qū)動開發(fā)學(xué)習】01.編寫第一個hello驅(qū)動+自動創(chuàng)建設(shè)備節(jié)點(不涉及硬件操作)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

一、驅(qū)動程序編寫流程

二、代碼編寫

2.1 驅(qū)動程序hello_drv.c

2.2 測試程序

2.3 編寫驅(qū)動程序的Makefile

三、上機實驗

3.1?NFS 掛載

3.2 測試示例


【IMX6ULL驅(qū)動開發(fā)學(xué)習】01.編寫第一個hello驅(qū)動+自動創(chuàng)建設(shè)備節(jié)點(不涉及硬件操作),Linux驅(qū)動開發(fā),驅(qū)動開發(fā),學(xué)習,linux

一、驅(qū)動程序編寫流程

  • 構(gòu)造file_operations結(jié)構(gòu)體

  • 在里面填充open/read/write/ioctl成員

  • 注冊file_operations結(jié)構(gòu)體?int major = register_chrdev(0, "name", &fops);

  • 入口函數(shù):調(diào)用regiister_chrdev

  • 出口函數(shù):調(diào)用unregiister_chrdev

  • 輔助信息: class_create/class_destroy? ?device_create/device_destroy

總結(jié):應(yīng)用程序調(diào)用open/read/write/ioctl,驅(qū)動程序就給你提供對應(yīng)的open/read/write/ioctl,只不過驅(qū)動程序的這些函數(shù)為了便于管理,故把函數(shù)放在file_operations結(jié)構(gòu)體里面,通過 register_chrdev函數(shù)把結(jié)構(gòu)體告訴內(nèi)核,并注冊字符設(shè)備驅(qū)動程序。驅(qū)動程序里面有個入口函數(shù),相當于main函數(shù),是裝載驅(qū)動程序時調(diào)用的函數(shù),在入口函數(shù)中注冊,把結(jié)構(gòu)體放到chrdevs數(shù)組里面來,出口函數(shù)中反注冊,就是把結(jié)構(gòu)體拿掉,在卸載驅(qū)動程序時調(diào)用的函數(shù)。 ?

二、代碼編寫

2.1 驅(qū)動程序hello_drv.c

參考 driver/char 中的程序,包含頭文件,寫框架,傳輸數(shù)據(jù):

  • 驅(qū)動中實現(xiàn) open, read, write, release, APP 調(diào)用這些函數(shù)時,都打印內(nèi)核信息
  • APP 調(diào)用 write 函數(shù)時,傳入的數(shù)據(jù)保存在驅(qū)動中? ?
  • APP 調(diào)用 read 函數(shù)時,把驅(qū)動中保存的數(shù)據(jù)返回給 APP? ?
  • 需要注意的是,驅(qū)動程序和應(yīng)用程序之間數(shù)據(jù)傳遞要使用copy_from_user(hello_buf, buf, len)和copy_to_user(buf, hello_buf, len)
  • class_create和device_create這兩個函數(shù)為我們創(chuàng)建了設(shè)備節(jié)點、主次設(shè)備號等輔助信息就不用手動創(chuàng)建設(shè)備節(jié)點了 mknod /dev/xyz c 245 0

  • class_create(THIS_MODULE, "hello_class"),創(chuàng)建類:為這個模塊創(chuàng)建類,類名叫hello_class

  • device_create(hello_class, NULL, MKDEV(major, 0), NULL, "hello"),在類下面創(chuàng)建設(shè)備信息:在hello_class下創(chuàng)建設(shè)備,沒有父親NULL,主次設(shè)備號,無私有數(shù)據(jù)NULL,格式hello根據(jù)這些信息,系統(tǒng)會為我們創(chuàng)建設(shè)備節(jié)點,設(shè)備節(jié)點名字是/dev/hello,和上面的類名無關(guān)

  • device_destroy(hello_class, MKDEV(major, 0))銷毀hello_class類下面的這個設(shè)備(由主次設(shè)備號確定)

  • class_destroy(hello_class)銷毀hello_class類

#include "asm/cacheflush.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 int major;
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)
{
    major = register_chrdev(0, "100ask_hello", &hello_drv);
    
	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, MKDEV(major, 0), NULL, "hello");  /* /dev/hello */
       
    return 0;
}


/* 4. exit function */
static void hello_exit(void)
{    
    
    device_destroy(hello_class, MKDEV(major, 0));
    class_destroy(hello_class);
    
    unregister_chrdev(major, "100ask_hello");
}


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

2.2 測試程序

測試程序要實現(xiàn)讀、寫功能:

./hello_test /dev/xxx abcdef     // 把字符串“abcdeft”發(fā)給驅(qū)動程序
./hello_test /dev/xxx            // 把驅(qū)動中保存的字符串讀回來

hello_drv_test.c源碼如下

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

/* 寫: ./hello_test /dev/xxx 100ask
 * 讀: ./hello_test /dev/xxx
 */
int main(int argc, char **argv)
{
    int fd;
    int len;
    char buf[100];

    if (argc < 2)
    {
        printf("Usage: \n");
        printf("%s <dev> [string]\n", argv[0]);
        return -1;
    }

    // open
    fd = open(argv[1], O_RDWR);
    if (fd < 0)
    {
        printf("can not open file %s\n", argv[1]);
        return -1;
    }

    if (argc == 3)
    {
        // write
        len = write(fd, argv[2], strlen(argv[2])+1);
        printf("write ret = %d\n", len);
    }
    else
    {
        // read
        len = read(fd, buf, 100);
        buf[99] = '\0';
        printf("read str : %s\n", buf);
    }

    // close
    close(fd);
    return 0;
}

2.3 編寫驅(qū)動程序的Makefile

驅(qū)動程序中包含了很多頭文件,這些頭文件來自內(nèi)核,不同的 ARM 板它的某些頭文件可能不同。所以編譯驅(qū)動程序時,需要指定板子所用的內(nèi)核的源碼路徑。要編譯哪個文件?這也需要指定,設(shè)置 obj-m 變量即可怎么把.c 文件編譯為驅(qū)動程序.ko?這要借助內(nèi)核的頂層 Makefile。

本驅(qū)動程序的 Makefile 內(nèi)容如下:

【IMX6ULL驅(qū)動開發(fā)學(xué)習】01.編寫第一個hello驅(qū)動+自動創(chuàng)建設(shè)備節(jié)點(不涉及硬件操作),Linux驅(qū)動開發(fā),驅(qū)動開發(fā),學(xué)習,linux

KERN_DIR = /home/me/Linux-4.9.88 :指定內(nèi)核目錄

先設(shè)置好交叉編譯工具鏈,編譯好你的板子所用的內(nèi)核,然后修改 Makefile指定內(nèi)核源碼路徑,最后即可執(zhí)行make命令編譯驅(qū)動程序和測試程序。?【IMX6ULL驅(qū)動開發(fā)學(xué)習】01.編寫第一個hello驅(qū)動+自動創(chuàng)建設(shè)備節(jié)點(不涉及硬件操作),Linux驅(qū)動開發(fā),驅(qū)動開發(fā),學(xué)習,linux

三、上機實驗

3.1?NFS 掛載

我們是在 Ubuntu 中編譯程序,但是需要在 ARM 板子上測試。所以需要把程序放到 ARM 板子上。啟動單板后,可以通過 NFS 掛載 Ubuntu 的某個目錄,訪問該目錄中的程序。

ifconfig eth0 192.168.5.9                    //靜態(tài)配置開發(fā)板ip地址 
mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt //掛載到開發(fā)板上的mnt目錄下
echo "7 4 1 7" > /proc/sys/kernel/printk     //打開內(nèi)核打印信息

【IMX6ULL驅(qū)動開發(fā)學(xué)習】01.編寫第一個hello驅(qū)動+自動創(chuàng)建設(shè)備節(jié)點(不涉及硬件操作),Linux驅(qū)動開發(fā),驅(qū)動開發(fā),學(xué)習,linux?【IMX6ULL驅(qū)動開發(fā)學(xué)習】01.編寫第一個hello驅(qū)動+自動創(chuàng)建設(shè)備節(jié)點(不涉及硬件操作),Linux驅(qū)動開發(fā),驅(qū)動開發(fā),學(xué)習,linux

3.2 測試示例

首先在開發(fā)板的mnt目錄下查看文件是否掛載成功,當前目錄下以及有了Ubuntu編譯好的驅(qū)動程序和測試文件

【IMX6ULL驅(qū)動開發(fā)學(xué)習】01.編寫第一個hello驅(qū)動+自動創(chuàng)建設(shè)備節(jié)點(不涉及硬件操作),Linux驅(qū)動開發(fā),驅(qū)動開發(fā),學(xué)習,linux

insmod hello_drv.ko   // 安裝驅(qū)動程序
ls /dev/hello -l      // 驅(qū)動程序會生成設(shè)備節(jié)點
./hello_drv_test      // 查看測試程序的用法

【IMX6ULL驅(qū)動開發(fā)學(xué)習】01.編寫第一個hello驅(qū)動+自動創(chuàng)建設(shè)備節(jié)點(不涉及硬件操作),Linux驅(qū)動開發(fā),驅(qū)動開發(fā),學(xué)習,linux

?顯示已載入系統(tǒng)的模塊

【IMX6ULL驅(qū)動開發(fā)學(xué)習】01.編寫第一個hello驅(qū)動+自動創(chuàng)建設(shè)備節(jié)點(不涉及硬件操作),Linux驅(qū)動開發(fā),驅(qū)動開發(fā),學(xué)習,linux

查看測試程序用法,并寫入字符串"abcdef"后讀出,測試結(jié)果如下:?

【IMX6ULL驅(qū)動開發(fā)學(xué)習】01.編寫第一個hello驅(qū)動+自動創(chuàng)建設(shè)備節(jié)點(不涉及硬件操作),Linux驅(qū)動開發(fā),驅(qū)動開發(fā),學(xué)習,linux文章來源地址http://www.zghlxwxcb.cn/news/detail-635196.html

到了這里,關(guān)于【IMX6ULL驅(qū)動開發(fā)學(xué)習】01.編寫第一個hello驅(qū)動+自動創(chuàng)建設(shè)備節(jié)點(不涉及硬件操作)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

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

    【IMX6ULL驅(qū)動開發(fā)學(xué)習】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日
    瀏覽(63)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習】15.IMX6ULL驅(qū)動開發(fā)問題記錄(sleep被kill_fasync打斷)

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

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

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

    【IMX6ULL驅(qū)動開發(fā)學(xué)習】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日
    瀏覽(25)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習】03.設(shè)置IMX6ULL開發(fā)板與虛擬機在同一網(wǎng)段(設(shè)置開發(fā)板靜態(tài)IP)

    【IMX6ULL驅(qū)動開發(fā)學(xué)習】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日
    瀏覽(50)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習】19.mmap內(nèi)存映射

    【IMX6ULL驅(qū)動開發(fā)學(xué)習】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é)習】11.Linux之SPI驅(qū)動

    【IMX6ULL驅(qū)動開發(fā)學(xué)習】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日
    瀏覽(32)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習】12.Linux驅(qū)動之設(shè)備樹

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

    承接上一篇博客 【IMX6ULL驅(qū)動開發(fā)學(xué)習】11.驅(qū)動設(shè)計之面向?qū)ο骭分層思想(學(xué)習設(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日
    瀏覽(39)
  • 【IMX6ULL驅(qū)動開發(fā)學(xué)習】12.Linux SPI驅(qū)動實戰(zhàn):DAC驅(qū)動設(shè)計流程

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

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

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

    【IMX6ULL驅(qū)動開發(fā)學(xué)習】11.驅(qū)動設(shè)計之面向?qū)ο骭分層思想(學(xué)習設(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日
    瀏覽(25)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包