Linux簡易驅動程式範例word_count-Android深度探索HAL與驅動開發

Linux簡易驅動程式範例word_count-Android深度探索HAL與驅動開發

Linux簡易驅動程式範例word_count-Android深度探索HAL與驅動開發

 

Android深度探索HAL與驅動開發的word_count範例趕緊整理,歡迎有興趣同好一起來C/P一下。

 

step_help.txt

01.     cd Driver_Code/ch06_05/             //切換到工作目錄

02.     make             //產生驅動程式globalmem.ko

        02_1. modinfo word_count.ko             //查看驅動程式資訊

        02_2. depmod ./word_count.ko           //相依性(可不做)

03.     ls                                 //查看檔案變化

04.     cat /proc/devices           //查看硬體設備有哪些

05.     sudo /sbin/insmod ./word_count.ko            //核心模組的載入

06.     lsmod |grep word_count           //查看核心模組

        06_1. ls -a /dev           //查看驅動設備

        06_2. ls -l /dev           //查看驅動版號

        06_3. sudo chmod 666 /dev/wordcount           //改變權限(全部可讀寫)預設600,660會失敗

        06_4. ls -l /dev            //查看驅動版號

        06_5. gcc ./test_word_count.c -o test_word_count           //編譯測試程式

        06_6. ./test_word_count “hello jash.liao”           //執行測試程式

07.     sudo /sbin/rmmod word_count           //卸載核心模組

08.     lsmod |grep word_count           //查看核心模組

 word_count.c

#include <linux/module.h>

#include <linux/init.h>

#include <linux/kernel.h>

#include <linux/fs.h>

#include <linux/miscdevice.h>

#include <asm/uaccess.h>

 

//  定義設備檔案名

#define DEVICE_NAME “wordcount”

static unsigned char mem[10000]; // 保存向設備檔寫入的資料

static int word_count = 0;

#define TRUE 255

#define FALSE 0

 

//  判斷指定字元是否為空格(包括空白字元、跳位字元、回車符和換行符)

static unsigned char is_spacewhite(char c)

{

        if (c == 32 || c == 9 || c == 13 || c == 10)

                return TRUE;

        else

                return FALSE;

}

 

static int get_word_count(const char *buf)

{

        int n = 1;

        int i = 0;

        char c = ‘ ‘;

 

        char flag = 0; // 處理多個空格分隔的情況,0:正常情況,1:已遇到一個空格

        if (*buf == ‘\0’)

                return 0;

        //  第1個字元是空格,從0開始計數

        if (is_spacewhite(*buf) == TRUE)

                n–;

 

        //  掃描字串中的每一個字元

        for (; (c = *(buf + i)) != ‘\0’; i++)

        {

                //  只由一個空格分隔單詞的情況

                if (flag == 1 && is_spacewhite(c) == FALSE)

                {

 

                        flag = 0;

                }

                //  由多個空格分隔單詞的情況,忽略多餘的空格

                else if (flag == 1 && is_spacewhite(c) == TRUE)

                {

 

                        continue;

                }

                //  當前字元為空格是單詞數加1

                if (is_spacewhite(c) == TRUE)

                {

                        n++;

                        flag = 1;

                }

        }

        //  如果字串以一個或多個空格結尾,不計數(單詞數減1)

        if (is_spacewhite(*(buf + i – 1)) == TRUE)

                n–;

        return n;

}

 

//當設備文件讀取時會被呼叫的函數

//file:指向設備文件 buf:保存可讀取的資訊 count:可讀取的字數 ppos:讀取的偏移量

static ssize_t word_count_read(struct file *file, char __user *buf,size_t count, loff_t *ppos)

{

        unsigned char temp[4];

 

        temp[0] = word_count >> 24;

        temp[1] = word_count >> 16;  

        temp[2] = word_count >> 8;

        temp[3] = word_count;

        if (copy_to_user(buf, (void*) temp, 4))

        {

                return -EINVAL;

        }

        printk(“read:word count:%d”, (int) count);

 

        return count;

}

//當設備文件寫入時會被呼叫的函數

//file:指向設備文件 buf:保存可讀取的資訊 count:可讀取的字數 ppos:讀取的偏移量

static ssize_t word_count_write(struct file *file, const char __user *buf,size_t count, loff_t *ppos)

{

        ssize_t written = count;

 

        if (copy_from_user(mem, buf, count))

        {

                return -EINVAL;

        }

        mem[count] = ‘\0’;

        word_count = get_word_count(mem);

        printk(“write:word count:%d\n”, (int) word_count);

 

        return written;

}

 

//  描述與設備檔觸發的事件對應的回調函數指標

// owner 指定整個模組都是驅動程式

//read API對應函數設定

//write API對應函數設定

static struct file_operations dev_fops =

{ .owner = THIS_MODULE, .read = word_count_read, .write = word_count_write };

 

//  描述設備檔的資訊  

//name 指定驅動程式名稱

//minor 動態版號

static struct miscdevice misc =

{ .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops };

 

//  初始化Linux驅動

static int __init word_count_init(void)

{

        int ret;

        //  建立設備檔

        ret = misc_register(&misc);

        //  輸出日誌資訊

        printk(“word_count_init_success\n”);

        return ret;

}

 

// 卸載Linux驅動

static void __exit word_count_exit(void)

{

        //  刪除設備檔 

        misc_deregister(&misc);

        //  輸出日誌資訊

        printk(“word_count_init_exit_success\n”);

}

//  註冊初始化Linux驅動的函數

module_init( word_count_init);

//  註冊卸載Linux驅動的函數

module_exit( word_count_exit);

 

MODULE_AUTHOR(“jash.liao”);

MODULE_DESCRIPTION(“statistics of word count.”);

MODULE_ALIAS(“word count module.”);

MODULE_LICENSE(“GPL”);

 

 Makefile

obj-m := word_count.o

 

all:

                make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

 

clean:

                make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

test_word_count.c

#include <stdio.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdlib.h>

#include <string.h>

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

{

        int testdev;

        unsigned char buf[4];

 

        testdev = open(“/dev/wordcount”, O_RDWR);

        if (testdev == -1)

        {

                printf(“Cann’t open file \n”);

                return 0;

        }

        if (argc > 1)

        {

 

                write(testdev, argv[1], strlen(argv[1]));

                printf(“string:%s\n”, argv[1]);

        }

 

        read(testdev, buf, 4);

 

        int n = 0;

        //  將4個位元組還原成int類型的值

        n = ((int) buf[0]) << 24 | ((int) buf[1]) << 16 | ((int) buf[2]) << 8

                | ((int) buf[3]);

        printf(“word byte display:%d,%d,%d,%d\n”, buf[0], buf[1], buf[2], buf[3]);

        printf(“word count:%d\n”, n);

        close(testdev);

        return 0;

}

 

 

 

 

 

 


發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *