您的位置:首页 > 其它

测试程序中系统调用如何调用到驱动程序函数

2016-05-18 10:53 381 查看
linux操作系统,分为kernel层和user层,那么user层是如何通过系统调用最终调用到底层驱动接口呢?下面将以实测案例进行讲解。

底层驱动代码:

----------------------------------------------------------------start--------------------------------------------------------------------

#include <linux/kernel.h>

#include <linux/unistd.h>

#include <linux/types.h>

#include <linux/string.h>

#include <linux/module.h>

#include <linux/init.h>

#include <linux/i2c.h>

#include <linux/input.h>

#include <linux/workqueue.h>

#include <linux/mutex.h>

#include <linux/slab.h>

#include <linux/mutex.h>

#include <linux/interrupt.h>

#include <linux/delay.h>

#include <asm/irq.h>

#include <linux/cdev.h>

#include <linux/uaccess.h>

#include <linux/device.h>

#include <linux/kobject.h>

#include <linux/fs.h>

#include <../../../include/linux/sysfs.h>

#include <linux/dcache.h>

#include <linux/namei.h>

#include <linux/err.h>

#include <linux/proc_fs.h>

#define NAME "fyl_test"

#define MAX_SIZE 255

#define TEST_BUF "Welcome to LongCheer"

static struct kobject *kobj = NULL;

static int major = 100;

static struct cdev *test_cdev = NULL;

#define SYSFS "The message is sent by sysfs "

static ssize_t fyl_test_show(struct device *dev, struct device_attribute *attr, char *buf)

{

int ret = 0;

printk(KERN_ALERT"[fyl] %s %d\n", __func__, __LINE__);

ret = sprintf(buf, SYSFS);

ret = strlen(buf) + 1;

printk(KERN_ALERT"[fyl] ret = %d \n", ret);

return 0;

}

static ssize_t fyl_test_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count )

{

printk(KERN_ALERT"[fyl] %s %d\n", __func__, __LINE__);

return 0;

}

DEVICE_ATTR(fyl_test, S_IRUGO | S_IWUSR | S_IWGRP | S_IWOTH, fyl_test_show, fyl_test_store);

static struct attribute * attr_test[] = {

&dev_attr_fyl_test.attr,

NULL

};

static struct attribute_group test_attgrp = {

.attrs = attr_test,

//.name = NAME

};

static int test_open(struct inode *inode, struct file *filp)

{

printk(KERN_ALERT"%s\n", __func__);

return 0;

}

static int test_close(struct inode *inode, struct file *filp)

{

printk(KERN_ALERT"%s\n", __func__);

return 0;

}

static int test_read(struct file *filp, char __user* buf, size_t size, loff_t * lof)

{

int cnt = 0;

char buffer[MAX_SIZE] = TEST_BUF;

cnt = copy_to_user(buf, buffer, size);

if (cnt)

printk("the buffer has %d left\n", cnt);

printk(KERN_ALERT"%s cnt = %d\n", __func__, cnt);

printk(KERN_ALERT"%s , send buf:%s\n", __func__, buffer);

printk(KERN_ALERT"%s\n", __func__);

return 0;

}

static int test_write(struct file *filp, const char __user* buf, size_t size, loff_t * lof)

{

int cnt = 0;

char buffer[MAX_SIZE] = {0};

cnt = copy_from_user(buffer, buf, size);

if (cnt)

printk("the buffer has %d left\n", cnt);

printk(KERN_ALERT"%s cnt = %d\n", __func__, cnt);

printk(KERN_ALERT"%s , receive buf:%s\n", __func__, buffer);

printk(KERN_ALERT"%s\n", __func__);

return 0;

}

static struct file_operations file_ops = {

.owner = THIS_MODULE,

.open = test_open,

.release = test_close,

.read = test_read,

.write = test_write,

};

static struct class *test_class = NULL;

static struct proc_dir_entry *proc_test = NULL;

static int __init fyl_init(void)

{

int ret = 0;

dev_t dev_num = 0;

struct device *dev = NULL;

/* sysfs operation */

kobj = kobject_create_and_add(NAME, NULL);

if (IS_ERR(kobj) || !kobj) {

printk(KERN_ALERT"[fyl] %s %d allocate kobj faild\n", __func__, __LINE__);

return 0;

}

ret = sysfs_create_group(kobj, &test_attgrp);

/* proc operation */

proc_test = proc_create(NAME, 0666, NULL, &file_ops);

if (IS_ERR(proc_test) || !proc_test) {

printk(KERN_ALERT"[fyl]%d ,proc_create failed\n", __LINE__);

return -ENOMEM;

}

/* dev node operation */

dev_num = MKDEV(major, 0);

ret = register_chrdev_region(dev_num, 1, NAME);

if (ret != 0) {

printk(KERN_ALERT"[fyl] %s %d register_chrdev_region failed\n", __func__, __LINE__);

return 0;

}

test_cdev = cdev_alloc();

if (IS_ERR(test_cdev) || !test_cdev) {

printk(KERN_ALERT"[fyl] %s %d allocate cdev failed\n", __func__, __LINE__);

return 0;

}

cdev_init(test_cdev, &file_ops);

ret = cdev_add(test_cdev, dev_num, 1);

if (ret != 0) {

printk(KERN_ALERT"[fyl] %s %d cdev_add failed\n", __func__, __LINE__);

return 0;

}

test_class = class_create(THIS_MODULE, "test_class");

if (IS_ERR(test_class) || !test_class) {

printk(KERN_ALERT"[fyl] %s %d allocate class faild\n", __func__, __LINE__);

return 0;

}

dev = device_create(test_class, NULL, dev_num, NULL, NAME);

if (IS_ERR(dev) || !dev) {

printk(KERN_ALERT"[fyl] %s %d generate dev/fyl_test faild\n", __func__, __LINE__);

return 0;

}

printk(KERN_ALERT"fyl_init\n");

return 0;

}

static void __exit fyl_exit(void)

{

printk(KERN_ALERT"fyl_exit\n");

}

module_init(fyl_init);

module_exit(fyl_exit);

MODULE_AUTHOR("fanyanlai@blongcheer.net");

MODULE_DESCRIPTION("fyl driver test");

MODULE_LICENSE("GPL v2");

----------------------------------------------------------------end---------------------------------------------------------------------

用户层测试程序:

----------------------------------------------------------------start--------------------------------------------------------------------

#include <stdio.h>

#include <string.h>

#include <strings.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <unistd.h>

#include <fcntl.h>

#define NAME "/dev/fyl_test"

#define MAX_SIZE 255

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

{

int cnt = argc;

int i = 0;

int ret = 0;

char buf_r[MAX_SIZE] = {0};

char buf_w[] = "Get the information";

printf("fyl test \n");

printf("[fyl] cnt = %d\n", cnt);

for(i=cnt; i > 0 && argv[--i]; )

printf("[fyl]argv[%d]:%s\n", i, argv[i]);

int fd = 0;

fd = open(NAME, O_RDWR);

if (fd < 0) {

printf("open faild\n");

return 0;

}

ret = read(fd, buf, 21);

if (ret)

printf("the buffer has %d left\n", ret);

printf("buf_r:%s ,ret = %d\n", buf_r, ret);

sleep(1);

ret = write(fd, buf_w, sizeof(buf_w));

if (ret)

printf("the buffer has %d left\n", ret);

printf("buf_w:%s ,ret = %d\n", buf_w, ret);

sleep(2);

close(fd);

return 0;

}

----------------------------------------------------------------end---------------------------------------------------------------------

测试结果:

root@vegetalte:/system/bin # ./fyl_main_test

./fyl_main_test

fyl test

[fyl] cnt = 1

[fyl]argv[0]:./fyl_main_test

buf_r:Welcome to LongCheer ,ret = 0

buf_w:Get the information ,ret = 0

将测试程序中的宏定义

#define NAME "/dev/fyl_test"

换成

#define NAME "dev/fyl_test"

然后进行测试:

测试结果一:

root@vegetalte:/system/bin # ./fyl_main_test

./fyl_main_test

fyl test

[fyl] cnt = 1

[fyl]argv[0]:./fyl_main_test

open faild

测试结果二:

root@vegetalte:/ # ./system/bin/fyl_main_test

./system/bin/fyl_main_test

fyl test

[fyl] cnt = 1

[fyl]argv[0]:./system/bin/fyl_main_test

buf_r:Welcome to LongCheer ,ret = 0

buf_w:Get the information ,ret = 0

分析:

1、如果测试程序中文件节点不是绝对路径,运行程序就会报错;

2、测试程序会以所在运行路径去查找文件节点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: