1. 程式人生 > 其它 >【北京迅為】i.MX6ULL終結者Linux併發與競爭實驗互斥體實驗

【北京迅為】i.MX6ULL終結者Linux併發與競爭實驗互斥體實驗

技術標籤:# 第四部分 Linux驅動開發【北京迅為】IMX6ULL終結者開發板嵌入式linux開發平臺

1 編寫驅動程式

本實驗例程路徑:i.MX6UL終結者光碟資料/06_Linux驅動例程/07_gpioled_mutex
建立gpioled_mutex.c,內容如下(有省略) :

1 #include <linux/types.h>
  2 #include <linux/kernel.h>
......
 23 /* gpioled 裝置結構體 */
 24 struct gpioled_dev{
 25         dev_t devid; /* 裝置號 */
 26
struct cdev cdev; /* cdev */ 27 struct class *class; /* 類 */ 28 struct device *device; /* 裝置 */ 29 int major; /* 主裝置號 */ 30 int minor; /* 次裝置號 */ 31 struct device_node *nd; /* 裝置節點 */ 32 int led_gpio; /* led 所使用的 GPIO 編號*/ 33 struct mutex lock;
/* 互斥體 */ 34 }; 35 36 struct gpioled_dev gpioled; /* led 裝置 */ 37 38 /* 39 * @description : 開啟裝置 40 * @param – inode : 傳遞給驅動的 inode 41 * @param - filp : 裝置檔案,file 結構體有個叫做 private_data 的成員變數 42 * 一般在 open 的時候將 private_data 指向裝置結構體。 43 * @return : 0 成功;其他 失敗 44 */ 45 static int led_open(struct
inode *inode, struct file *filp) 46 { 47 filp->private_data = &gpioled; /* 設定私有資料 */ 48 49 /* 獲取互斥體,可以被訊號打斷 */ 50 if (mutex_lock_interruptible(&gpioled.lock)) { 51 return -ERESTARTSYS; 52 } 53 #if 0 54 mutex_lock(&gpioled.lock); /* 不能被訊號打斷 */ 55 #endif 56 57 return 0; 58 } ...... 104 /* 105 * @description : 關閉/釋放裝置 106 * @param – filp : 要關閉的裝置檔案(檔案描述符) 107 * @return : 0 成功;其他 失敗 108 */ 109 static int led_release(struct inode *inode, struct file *filp) 110 { 111 struct gpioled_dev *dev = filp->private_data; 112 113 /* 釋放互斥鎖 */ 114 mutex_unlock(&dev->lock); 115 116 return 0; 117 } 118 119 /* 裝置操作函式 */ 120 static struct file_operations gpioled_fops = { 121 .owner = THIS_MODULE, 122 .open = led_open, 123 .read = led_read, 124 .write = led_write, 125 .release = led_release, 126 }; 127 128 /* 129 * @description : 驅動入口函式 130 * @param : 無 131 * @return : 無 132 */ 133 static int __init led_init(void) 134 { 135 int ret = 0; 136 137 /* 初始化互斥體 */ 138 mutex_init(&gpioled.lock); ...... 198 return 0; 199 } ...... 214 215 module_init(led_init); 216 module_exit(led_exit); 217 MODULE_LICENSE("GPL"); 218 MODULE_AUTHOR("topeet");

第 33 行,定義互斥體 lock。
第 45~58 行,在 open 函式中呼叫 mutex_lock_interruptible 或者 mutex_lock 獲取 mutex,成功的話就表示可以使用 LED 燈,失敗的話就會進入休眠狀態,和訊號量一樣。
第 114 行,在 release 函式中呼叫 mutex_unlock 函式釋放 mutex,這樣其他應用程式就可以獲取 mutex 了。
第 138 行,在驅動入口函式中呼叫 mutex_init 初始化 mutex。
互斥體和二值訊號量類似,只不過互斥體是專門用於互斥訪問的。

2 編寫應用測試程式

應用測試程式使用38.1.2中的應用測試程式即可。

3 執行測試

1、編譯驅動程式
新增Makefile檔案,修改obj-m的值為 gpioled_mutex.o,內容如下:

KERNELDIR := /home/topeet/kernel
CURRENT_PATH := $(shell pwd)
obj-m := gpioled_mutex.o

build: kernel_modules

kernel_modules: 
        $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
clean:
        $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

首先我們在終端輸入兩個命令(設定兩個環境變數):
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
然後使用“make”命令進行編譯,生成gpioled_mutex.ko驅動模組檔案。
2、執行測試
將編譯好的gpioled_mutex.ko驅動模組檔案拷貝到/lib/modules/4.1.15目錄下(檢查開發板根檔案系統中有沒有“/lib/modules/4.1.15”這個目錄,如果沒有的話需要自行建立一下。開發板中使用的是光碟資料裡面提供的busybox檔案系統,光碟資料的“i.MX6UL終結者光碟資料\08_開發板系統映象\03_檔案系統映象\01_Busybox檔案系統”目錄下)。輸入下面命令載入模組:
depmod
modprobe gpioled_mutex
驅動模組載入成功如圖 3.1所示:
在這裡插入圖片描述

圖 3.1

驅動模組載入成功後,使用gpioled_atomic_test應用測試程式進行測試,測試流程和原子變數測試一樣。使用下面的命令開啟LED燈:
./gpioled_atomic_test /dev/gpioled 1 &
然後緊接著輸入LED燈關閉命令:
./gpioled_atomic_test /dev/gpioled 0 &
執行結果如下:
在這裡插入圖片描述

圖 3.2

可以看出和訊號量的測試結果一樣。
解除安裝模組命令:
rmmod gpioled_mutex