嵌入式內核驅動開發之學習筆記(二) 實現應用控制驅動

      網友投稿 802 2022-05-29

      Linux系統根據驅動程序實現的模型框架將設備驅動分成字符設備驅動、塊設備驅動、網絡設備驅動三大類。這里簡單理解一下概念

      字符設備:設備按字節流處理數據,通常用的串口設備、鍵盤設備都是這種。

      塊設備:設備按塊單位對數據處理,通常是存儲設備。

      網絡設備:顧名思義,建立在socket接口上的設備。

      字符設備驅動框架

      作為字符設備驅動要素:

      1,必須有一個設備號,用在眾多到設備驅動中進行區分

      2,用戶必須知道設備驅動對應到設備節點(設備文件)

      3,對設備操作其實就是對文件操作,應用空間操作open,read,write的時候,實際在驅動代碼有對應到open, read,write

      linux把所有到設備都看成文件,用戶對字符設備進行操作實際上就是對驅動進行操作,實際上就是操作對應的設備文件!

      而設備號是內核層區別設備的一個標識,我們通過驅動代碼程序實現下面 應用程序到設備驅動的控制過程。

      應用層程序 -->? 設備結點? -->? 設備號? -->? 設備驅動? -->? 硬件

      實現一簡易的框架。首先是驅動程序的實現

      當用戶裝載完驅動模塊,程序會執行 chr_drv_init 這個回調函數,向系統申請一個主設備號(表示程序為哪一類設備服務),創建設備結點(產生/dev/chr2,linux系統能識別這個設備文件);當用戶卸載驅動模塊后,程序執行 chr_drv_exit 這個回調函數,將之前申請的設備結點和設備號回收。

      結構體類型 file_operations 定義了很多對應用層的接口,這些成員變量都是函數指針。我們將這些指針指向自己定義的函數入口。再去實現我們的函數功能。

      //chr_drv.c

      #include

      #include

      #include

      #include

      static unsigned int dev_major = 250;

      static struct class *devcls;

      static struct device *dev;

      ssize_t chr_drv_read(struct file *filp, char __user *buf, size_t count, loff_t *fpos);

      ssize_t chr_drv_write(struct file *filp, const char __user *buf, size_t count, loff_t *fpos);

      int chr_drv_open(struct inode *inode, struct file *filp);

      int chr_drv_close(struct inode *inode, struct file *filp);

      const struct file_operations my_fops = {

      .open = chr_drv_open,

      .read = chr_drv_read,

      .write = chr_drv_write,

      .release = chr_drv_close,

      };

      static int __init chr_drv_init(void)

      {

      printk("-------%s-------------\n", __FUNCTION__);

      //向系統申請設備號

      int ret;

      ret = register_chrdev(dev_major, "chr_dev_test", &my_fops);

      if(ret == 0){

      printk("register ok\n");

      }else{

      printk("register failed\n");

      return -EINVAL;

      }

      //創建設備結點

      devcls = class_create(THIS_MODULE, "chr_cls");

      dev = device_create(devcls, NULL, MKDEV(dev_major, 0), NULL, "chr2");

      return 0;

      }

      static void __exit chr_drv_exit(void)

      {

      printk("-------%s-------------\n", __FUNCTION__);

      //銷毀這個設備結點

      device_destroy(devcls, MKDEV(dev_major, 0));

      class_destroy(devcls);

      //釋放這個設備號

      unregister_chrdev(dev_major, "chr_dev_test");

      }

      module_init(chr_drv_init);

      module_exit(chr_drv_exit);

      MODULE_LICENSE("GPL");

      // read(fd, buf, size);

      ssize_t chr_drv_read(struct file *filp, char __user *buf, size_t count, loff_t *fpos)

      {

      printk("-------%s-------\n", __FUNCTION__);

      return 0;

      }

      ssize_t chr_drv_write(struct file *filp, const char __user *buf, size_t count, loff_t *fpos)

      {

      printk("-------%s-------\n", __FUNCTION__);

      return 0;

      }

      int chr_drv_open(struct inode *inode, struct file *filp)

      {

      printk("-------%s-------\n", __FUNCTION__);

      return 0;

      }

      int chr_drv_close(struct inode *inode, struct file *filp)

      {

      printk("-------%s-------\n", __FUNCTION__);

      return 0;

      }

      應用程序用來測試驅動程序的這些接口函數,實現對驅動的控制。

      這里open函數定位到驅動程序的chr_drv_open函數,read函數定位到驅動程序的chr_drv_read函數(參考驅動程序中my_fops結構體的初始化)。就像文件IO函數那樣使用,只不過我們驅動程序里對應的函數沒有具體的實現,能看到一些打印信息。

      //chr_test.c

      #include

      #include

      #include

      #include

      #include

      #include

      #include

      int main(int argc, char *argv[])

      {

      int fd;

      int value = 0;

      //打開設備結點

      fd = open("/dev/chr2", O_RDWR);

      if(fd < 0)

      {

      perror("open");

      exit(1);

      }

      //讀操作

      read(fd, &value, 4);

      while(1)

      {

      //寫操作

      value = 0;

      write(fd, &value, 4);

      sleep(1);

      //寫操作

      value = 1;

      write(fd, &value, 4);

      sleep(1);

      }

      嵌入式內核及驅動開發之學習筆記(二) 實現應用控制驅動

      close(fd);

      return 0;

      }

      Makefile文件負責整個工程的編譯與管理

      相比于之前,要多編譯了chr_test.c這個文件,APP_NAME 指定目標文件名,CROSS_COMPILE 指定交叉編譯工具鏈。下面還要修改添加一下編譯規則

      ROOTFS_DIR = /nfs/rootfs

      APP_NAME = chr_test

      CROSS_COMPILE = /home/linux/soft/gcc-4.6.4/bin/arm-none-linux-gnueabi-

      CC = $(CROSS_COMPILE)gcc

      ifeq ($(KERNELRELEASE), )

      KERNEL_DIR = /mnt/hgfs/sharefolder/kernel/linux-3.14-fs4412

      CUR_DIR = $(shell pwd)

      all :

      make -C $(KERNEL_DIR) M=$(CUR_DIR) modules

      $(CC) $(APP_NAME).c -o $(APP_NAME)

      clean :

      make -C $(KERNEL_DIR) M=$(CUR_DIR) clean

      install:

      cp -raf *.ko $(APP_NAME) $(ROOTFS_DIR)/drv_module

      else

      obj-m += chr_drv.o

      endif

      查看實驗結果

      編譯并移動文件到nfs根目錄

      root@linux:/mnt/hgfs/sharefolder/kernel/linux-3.14-fs4412/drivers/mydrivers/chr_drv# make

      root@linux:/mnt/hgfs/sharefolder/kernel/linux-3.14-fs4412/drivers/mydrivers/chr_drv# make install

      開發板加載模塊,執行應用程序

      [root@farsight drv_module]# ls

      chr_drv.ko ? chr_test ? ? chr_test.ko ?hello.ko ? ? math.ko

      [root@farsight drv_module]# insmod chr_drv.ko

      [ 3036.170000] -------chr_drv_init-------------

      [ 3036.175000] register ok

      [root@farsight drv_module]# ./chr_test

      [ 3041.255000] -------chr_drv_open-------

      [ 3041.255000] -------chr_drv_read-------

      [ 3041.260000] -------chr_drv_write-------

      [ 3042.265000] -------chr_drv_write-------

      [ 3043.265000] -------chr_drv_write-------

      嵌入式

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Spark3.0主要特性(1)—— Adaptive Query Execution
      下一篇:快速入門RDS【玩轉華為云】
      相關文章
      亚洲国产精品久久丫| 亚洲AV无码成人网站久久精品大| 亚洲综合日韩中文字幕v在线| 亚洲日产无码中文字幕| 久久亚洲国产精品五月天婷| 毛片亚洲AV无码精品国产午夜| 亚洲熟妇AV乱码在线观看| 亚洲最大成人网色香蕉| 亚洲AV男人的天堂在线观看| 亚洲Av高清一区二区三区| 精品亚洲国产成人| 久久亚洲精品国产亚洲老地址| 国产色在线|亚洲| 亚洲日韩精品无码专区加勒比| 亚洲精品国产av成拍色拍| 亚洲.国产.欧美一区二区三区| 亚洲AV成人无码久久WWW| 另类图片亚洲校园小说区| 亚洲免费在线观看| 久久久久久A亚洲欧洲AV冫| 国产亚洲av人片在线观看| 国产成人综合亚洲AV第一页| 亚洲熟妇丰满多毛XXXX| 亚洲av无码乱码国产精品| 精品亚洲成AV人在线观看| 亚洲成人黄色在线| 日韩亚洲国产综合高清| 亚洲国产精华液2020| 亚洲精品97久久中文字幕无码| 中文字幕日韩亚洲| 亚洲阿v天堂在线| 亚洲美女免费视频| 久久亚洲国产最新网站| 风间由美在线亚洲一区| 亚洲日韩VA无码中文字幕| 精品亚洲综合久久中文字幕| 久久久久亚洲av无码专区喷水 | 亚洲精品国产手机| 亚洲AV无码无限在线观看不卡| 精品无码专区亚洲| 国产亚洲精品拍拍拍拍拍|