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

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、测试程序会以所在运行路径去查找文件节点。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值