在ok6410 Androdi开发板运行c程序,添加驱动模块,并测试android驱动

1.在pc linux上安装arm-none-linux-gnueabi 交叉编译器,此编译器为android专用。而不同于arm-linux-gcc.

2.编写驱动代码:word_count.c

#include 
#include 
#include 
#include 
#include 
#include 

#define DEVICE_NAME "wordcount"       	//  定义设备文件名
static unsigned char mem[10000];        	 	//  保存向设备文件写入的数据
static char read_flag = 'y';                 	//  y:已从设备文件读取数据   n:未从设备文件读取数据
static int written_count = 0;                	// 向设备文件写入数据的字节数

//  从设备文件读取数据时调用该函数
//  file:指向设备文件、buf:保存可读取的数据   count:可读取的字节数  ppos:读取数据的偏移量
static ssize_t word_count_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{   
    //  如果还没有读取设备文件中的数据,可以进行读取
    if(read_flag == 'n')
    {   
        //  将内核空间的数据复制到用户空间,buf中的数据就是从设备文件中读出的数据
        copy_to_user(buf, (void*) mem, written_count);
        //  向日志输出已读取的字节数
        printk("read count:%d", (int) written_count);
        //  设置数据已读状态
        read_flag = 'y';
        return written_count;
    }
    //  已经从设备文件读取数据,不能再次读取数据
    else
    {   
        return 0;
    }
}
//  向设备文件写入数据时调用该函数
//  file:指向设备文件、buf:保存写入的数据   count:写入数据的字节数  ppos:写入数据的偏移量
static ssize_t word_count_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{   
    //  将用户空间的数据复制到内核空间,mem中的数据就是向设备文件写入的数据
    copy_from_user(mem, buf, count);
    //  设置数据的未读状态
    read_flag = 'n';
    //  保存写入数据的字节数
    written_count = count;
    //  向日志输出已写入的字节数
    printk("written count:%d", (int)count);
    return count;
}
//  描述与设备文件触发的事件对应的回调函数指针
//  需要设置read和write成员变量,系统才能调用处理读写设备文件动作的函数
static struct file_operations dev_fops =
{ .owner = THIS_MODULE, .read = word_count_read, .write = word_count_write };

//  描述设备文件的信息
static struct miscdevice misc =
{ .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops };

//  初始化Linux驱动
static int word_count_init(void)
{
    int ret;
    //  建立设备文件
    ret = misc_register(&misc);
    //  输出日志信息
    printk("word_count_init_success\n");
    return ret;
}

// 卸载Linux驱动
static void word_count_exit(void)
{
    //  删除设备文件
    misc_deregister(&misc);
    //  输出日志信息
    printk("word_init_exit_success\n");
}

//  注册初始化Linux驱动的函数
module_init( word_count_init);
//  注册卸载Linux驱动的函数
module_exit( word_count_exit);

MODULE_AUTHOR("lining");
MODULE_DESCRIPTION("statistics of word count.");
MODULE_ALIAS("word count module.");
MODULE_LICENSE("GPL");

3.参考上一篇编译生成对应ok6410 android 开发板内核的驱动文件,生成word_count.ko文件,并移植到开发板。
4.编写测试程序:test_word_count.c

#include 
#include 
#include 
#include 
#include 
int main(int argc, char *argv[])
{
    int testdev;     //  打开设备文件(/dev/wordcount)的句柄
    unsigned char buf[4];          //  表示单词数的4个字节
    //  打开设备文件
    testdev = open("/dev/wordcount", O_RDWR);
    //  如果open函数返回-1,表示打开设备文件失败
    if (testdev == -1)
    {
        printf("Cann't open file \n");
        return 0;
    }
    //  如果test_word_count后面跟有命令行参数,程序会将第1个参数值当作待统计的字符串
    //  如果没有命令行参数,则只读取设备文件中的值
    if (argc > 1)
    {
        //  向设备文件写入待统计的字符串
        write(testdev, argv[1], strlen(argv[1]));
        //  输出待统计的字符串
        printf("string:%s\n", argv[1]);
    }
    //  读取设备文件中的单词数(4个字节)
    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]);
     //  分别输出从设备文件获取的4个字节的值
    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;
}


 

5.使用交叉编译工具编译
# arm-none-linux-gnueabi-gcc test_word_count.c -o test_word_count  -static
生成test_word_count  ,并把test_word_count  移植到开发板。
-static选项在这里是必须的,否则会出现”not found”的错误。
6.在开发板执行
/ # insmod word_count.ko
word_count_init_success
/ # ./test_word_count wangben
written count:7read count:7string:wangben
word byte display:119,97,110,103
word count:2002873959
/ # rmmod word_count
word_init_exit_success
/ #
好了,驱动已经测试完毕。

你可能感兴趣的:(android,驱动)