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

字符設備驅動(內核態(tài)用戶態(tài)內存交互)

這篇具有很好參考價值的文章主要介紹了字符設備驅動(內核態(tài)用戶態(tài)內存交互)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

內核驅動:運行在內核態(tài)的動態(tài)模塊,遵循內核模塊框架接口,更傾向于插件。
應用程序:運行在用戶態(tài)的進程。
應用程序與內核驅動交互通過既定接口,內核態(tài)和用戶態(tài)訪問依然遵循內核既定接口。

環(huán)境搭建

系統(tǒng):openEuler-20.03-LTS-SP3文章來源地址http://www.zghlxwxcb.cn/news/detail-678704.html

yum install gcc kernel-devel

編寫源碼

  • char_module.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/device.h> //下面這三個頭文件是由于動態(tài)創(chuàng)建需要加的
#include <linux/device.h>
#include <linux/cdev.h>

MODULE_LICENSE("GPL");

#define DEVICE_NAME "char_module"
#define BUF_SIZE 32

static struct class *cdev_class;
dev_t dev_num = 0; // 這里是動態(tài)分配設備號和動態(tài)創(chuàng)建設備結點需要用到的
struct cdev dev_c;

static char context_buf[BUF_SIZE]={"this a test context buffer\0"};

static ssize_t read(struct file *, char *, size_t, loff_t *);
static ssize_t write(struct file *, const char *, size_t, loff_t *);
static int open(struct inode *, struct file *);
static int release(struct inode *, struct file *);

// 初始化字符設備驅動的 file_operations 結構體
struct file_operations fops = {
        .read = read,
        .write = write,
        .open = open,
        .release = release
};

static int __init demo_init(void)
{
        int ret, err;

        printk(KERN_INFO "%s: %s", DEVICE_NAME , __func__);

        // 注冊設備驅動
        ret = alloc_chrdev_region(&dev_num, 0, 1, DEVICE_NAME); // 動態(tài)分配設備號
        if (ret)
        {
                printk("demo_init register failure\n");
                unregister_chrdev_region(dev_num, 1);
                return ret;
        }
        printk("demo_init register success\n");

        // 初始化設備操作
        cdev_init(&dev_c, &fops);
        err = cdev_add(&dev_c, dev_num, 1);
        if (err)
        {
                printk(KERN_NOTICE "error %d adding cdev\n", err);
                unregister_chrdev_region(dev_num, 1);
                return err;
        }

        // 動態(tài)創(chuàng)建設備結點
        cdev_class = class_create(THIS_MODULE, DEVICE_NAME); 
        if (IS_ERR(cdev_class))
        {
                printk("ERR:cannot create a cdev_class\n");
                unregister_chrdev_region(dev_num, 1);
                return -1;
        }
        device_create(cdev_class, NULL, dev_num, 0, DEVICE_NAME);

        return ret;
}

static void __exit demo_exit(void)
{
        printk(KERN_INFO "%s: %s", DEVICE_NAME , __func__);

        // 注銷設備驅動
        device_destroy(cdev_class, dev_num);
        class_destroy(cdev_class);
        unregister_chrdev_region(dev_num, 1);
}

static ssize_t read(struct file *filp, char *buf, size_t len, loff_t *off)
{
        // 內核空間到用戶空間copy
        printk(KERN_INFO "%s: %s", DEVICE_NAME , __func__);
        if (raw_copy_to_user(buf, &context_buf, sizeof(context_buf)))
        {
                return -EFAULT;
        }
        printk(KERN_INFO "user space: %pF", buf);
        printk(KERN_INFO "read: %pF; size: %ld; data: %s", &context_buf, sizeof(context_buf), context_buf);
        return BUF_SIZE;
}

static ssize_t write (struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
        // 用戶空間到內核空間copy
        printk(KERN_INFO "%s: %s", DEVICE_NAME , __func__);
        if (raw_copy_from_user(&context_buf, buf, sizeof(context_buf)))
        {
                return -EFAULT;
        }
        printk(KERN_INFO "user space: %pF", buf);
        printk(KERN_INFO "write: %pF; size: %ld; data: %s", &context_buf, sizeof(context_buf), context_buf);
        return BUF_SIZE;
}

static int open(struct inode *inodp, struct file *filp)
{
        printk(KERN_INFO "%s: %s", DEVICE_NAME , __func__);
        return 0;
}

static int release(struct inode *inodp, struct file *filp)
{
        printk(KERN_INFO "%s: %s", DEVICE_NAME, __func__);
        return 0;
}

module_init(demo_init);
module_exit(demo_exit);
  • Makefile
ifneq ($(KERNELRELEASE),)
obj-m := char_module.o

else
PWD  := $(shell pwd)
KVER := $(shell uname -r)
KDIR := /lib/modules/$(KVER)/build
all:
        $(MAKE) -C $(KDIR) M=$(PWD) modules modules_install
clean:
        rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions modules.*  Module.*
endif

app.c

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
 
#define CHAR_DEV_NAME "/dev/char_module"

int main()
{
        int ret;
        int fd;
        char buf[32];
 
        fd = open(CHAR_DEV_NAME, O_RDWR | O_NDELAY);
        if(fd < 0)
        {
                printf("open failed!\n");
                return -1;
        }

        int size = read(fd, buf, 32);

        printf("read size: %d;\nbuffer:[%s]\n", size, buf);

        char *write_buf = "use a application wirte to driver buffer";

        int w_size = write(fd, write_buf, strlen(write_buf));

        printf("write size: %d;\nbuffer:[%s]\n", w_size, write_buf);

        close(fd);

        return 0;
}

構建并測試

  • 驅動構建
    make && insmod char_module.ko
    
  • 驅動信息確認
    字符設備驅動(內核態(tài)用戶態(tài)內存交互),交互
  • 應用程序構建
    gcc app.c -o app
    ./app
    
  • 應用程序運行結果
    字符設備驅動(內核態(tài)用戶態(tài)內存交互),交互
  • 查看驅動日志
    dmesg
    
    字符設備驅動(內核態(tài)用戶態(tài)內存交互),交互

到了這里,關于字符設備驅動(內核態(tài)用戶態(tài)內存交互)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

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

領支付寶紅包贊助服務器費用

相關文章

  • 驅動開發(fā)--字符驅動設備2

    字符設備驅動 1.定義 以字節(jié)流的形式進行訪問,且只能順序訪問的設備,針對字符設備編寫的驅動叫做字符設備驅動 2.字符設備框架 用戶空間通過IO函數如open、read、write、close等函數接口,調用內核空間中的字符設備驅動函數中的用戶自定義的open、read、write、close等函數,通

    2024年02月15日
    瀏覽(49)
  • 字符設備驅動實例(ADC驅動)

    字符設備驅動實例(ADC驅動)

    ????????ADC是將模擬信號轉換為數字信號的轉換器,在 Exynos4412 上有一個ADC,其主要的特性如下。 (1)量程為0~1.8V。 (2)精度有 10bit 和 12bit 可選。 (3)采樣時鐘最高為5MHz,轉換速率最高為1MSPS (4)具有四路模擬輸入,同一時刻只有一路進行轉換 (5) 轉換完成后可以產生中斷。

    2024年02月11日
    瀏覽(24)
  • 嵌入式Linux(8):字符設備驅動--注冊字符類設備

    雜項設備 注冊雜項設備: 注銷雜項設備: 字符類設備 文件:include/linux/cdev.h 步驟流程: 定義一個cdev結構體。 使用cdev_init函數初始化cdev結構體成員變量。 參數: 第一個:要初始化的cdev結構體 第二個:文件操作集: cdev-ops = fops;//實際就是把文件操作集寫ops 使用cdev_add函數

    2023年04月22日
    瀏覽(24)
  • Linux設備驅動——第三章字符驅動

    當對幸福的憧憬過于急切,那痛苦就在人的心靈深處升起?!涌?本章的目的是編寫一個完整的字符設備驅動。我們開發(fā)一個字符驅動是因為這一類適合大部分簡單的硬件設備。字符驅動也比塊驅動易于理解。本章的最終目的是編寫一個模塊化的字符驅動,但是我們不會在

    2024年02月08日
    瀏覽(24)
  • Linux 驅動學習筆記 ——(1)字符設備驅動

    Linux 驅動學習筆記 ——(1)字符設備驅動

    《【正點原子】I.MX6U嵌入式Linux驅動開發(fā)指南》學習筆記 字符設備是 Linux 驅動中最基本的一類設備驅動,字節(jié)設備就是按照字節(jié)流來讀寫的設備,常見的字符設備包括:LED、蜂鳴器、按鍵、I2C 以及 SPI 等。 Linux 中一切皆文件,字符設備驅動加載成功后會在 /dev 目錄下生成相

    2024年02月08日
    瀏覽(26)
  • 字符設備驅動

    字符設備驅動

    前面內容: 1 Linux驅動—內核模塊基本使用 2 Linux驅動—內核模塊參數,依賴(進一步討論) linux根據驅動程序實現的模型框架將設備的驅動分為了三類: 字符設備驅動:以字節(jié)流為單位順序讀寫,不能隨機訪問。如,幀緩沖 ( framebuffer)驅動,聲卡,串口等。 塊設備驅動:以固定

    2023年04月08日
    瀏覽(19)
  • 字符設備驅動開發(fā)

    字符設備驅動開發(fā)

    1、字符設備驅動簡介 字符設備是 Linux 驅動中最基本的一類設備驅動, 字符設備就是一個一個字節(jié),按照字節(jié) 流進行讀寫操作的設備,讀寫數據是分先后順序的。 比如我們最常見的點燈、按鍵、IIC、SPI, LCD 等等都是字符設備,這些設備的驅動就叫做字符設備驅動。 先來簡

    2024年02月10日
    瀏覽(29)
  • 字符設備驅動開發(fā)(最初方式)

    字符設備驅動開發(fā)(最初方式)

    字符設備是Linux中最基本的一類設備驅動,我們常見的點燈、按鍵、IIC、SPI、LCD等等都是通過字符設備驅動框架來進行開發(fā)的。字符設備驅動是通過一個一個字節(jié)流的方式來進行讀寫操作設備,讀寫數據是分先后順序的。 通過空間劃分的方式來說,Linux系統(tǒng)中分為用戶空間和

    2024年02月17日
    瀏覽(24)
  • 字符設備驅動讀寫操作實現

    字符設備驅動讀寫操作實現

    put_user(x,ptr) x:char、int類型的簡單變量名 get_user(x,ptr) x:char、int類型的簡單變量名 mychar.c testmychar_app.c Makefile 實現結果: 改動之后的mychar.c代碼 把這些全局變量封裝在結構體中,這樣可以更好地管理數據,降低代碼的耦合性,提高代碼的可維護性和可擴展性

    2024年02月10日
    瀏覽(20)
  • 驅動開發(fā) 字符設備驅動分部注冊實現LED燈

    驅動開發(fā) 字符設備驅動分部注冊實現LED燈

    head.h 驅動文件 應用文件 現象實現

    2024年02月19日
    瀏覽(18)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領取紅包

二維碼2

領紅包