• 正文
    • 在mydevice-auto.c源码的基础上进行添加,重命名为copy_to_user.c
    • 完整的copy_to_user.c示例源码
    • 编译
    • 编写测试应用源码copy_to_user.c
    • 编译应用
    • 测试
  • 相关推荐
申请入驻 产业图谱

飞凌嵌入式ElfBoard ELF 1板卡-内核空间与用户空间的数据拷贝之获取内核空间数据

03/20 17:52
450
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

例程代码路径:ELF 1开发板资料包3-例程源码3-2 驱动例程源码3_内核空间与用户空间的数据拷贝copy_to_user

在mydevice-auto.c源码的基础上进行添加,重命名为copy_to_user.c

(一)添加头文件

#include <linux/uaccess.h>

(二)定义变量

#define DEVICE_NAME "copy_to_user"  // 设备名称

#define BUFFER_SIZE 1024

static char kernel_buffer[BUFFER_SIZE] = "Hello, User! This is kernel_buffer!";

(三)在device_read()函数添加拷贝操作,用户空间使用read函数时,会进入此函数。

static ssize_t device_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)

{

ssize_t bytes_read = 0;

// 在这里处理设备读取的操作

printk(KERN_INFO "This is device_read.n");

if (*offset >= BUFFER_SIZE)

return 0;

if (*offset + length > BUFFER_SIZE)

length = BUFFER_SIZE - *offset;

if (copy_to_user(buffer, kernel_buffer + *offset, length))

return -EFAULT;

*offset += length;

bytes_read = length;

return bytes_read;

}

offset参数表示当前文件位置的偏移量。它用于跟踪读取或写入操作在文件中的位置。

对于device_read函数来说,offset指向一个loff_t类型的变量,表示当前读取操作的文件偏移量。在读取数据之前,可以通过检查offset来确定从文件的哪个位置开始读取数据。读取完成后,可以通过更新offset来指示下一次读取操作应该从哪个位置开始。

在使用copy_to_user()函数将数据复制到用户空间之前,通常会更新offset的值,以确保下一次读取操作从正确的位置开始。这样可以实现逐步读取大文件或在多次读取中定位到不同位置的功能。

完整的copy_to_user.c示例源码

#include <linux/module.h>       // 包含模块相关函数的头文件

#include <linux/fs.h>           // 包含文件系统相关函数的头文件

#include <linux/uaccess.h>      // 包含用户空间数据访问函数的头文件

#include <linux/cdev.h>         //包含字符设备头文件

#include <linux/device.h>

#include <linux/uaccess.h>

#define DEVICE_NAME "copy_to_user"  // 设备名称

static dev_t dev_num;   //分配的设备号

struct  cdev my_cdev;          //字符设备指针

int major;  //主设备号

int minor;  //次设备号

static struct class *my_class;

static struct device *my_device;

#define BUFFER_SIZE 1024

static char kernel_buffer[BUFFER_SIZE] = "Hello, User! This is kernel_buffer!";

static int device_open(struct inode *inode, struct file *file)

{

// 在这里处理设备打开的操作

printk(KERN_INFO "This is device_open.n");

return 0;

}

static int device_release(struct inode *inode, struct file *file)

{

// 在这里处理设备关闭的操作

printk(KERN_INFO "This is device_release.n");

return 0;

}

static ssize_t device_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)

{

ssize_t bytes_read = 0;

// 在这里处理设备读取的操作

printk(KERN_INFO "This is device_read.n");

if (*offset >= BUFFER_SIZE)

return 0;

if (*offset + length > BUFFER_SIZE)

length = BUFFER_SIZE - *offset;

if (copy_to_user(buffer, kernel_buffer + *offset, length))

return -EFAULT;

*offset += length;

bytes_read = length;

return bytes_read;

}

static ssize_t device_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)

{

// 在这里处理设备写入的操作

printk(KERN_INFO "This is device_write.n");

return 0;

}

static struct file_operations fops = {

.owner = THIS_MODULE,

.open = device_open,

.release = device_release,

.read = device_read,

.write = device_write,

};

static int __init mydevice_init(void)

{

int ret;

// 在这里执行驱动程序的初始化操作

// 注册字符设备驱动程序

ret = alloc_chrdev_region(&dev_num,0,1,DEVICE_NAME);

if (ret < 0) {

printk(KERN_ALERT "Failed to allocate device number: %dn", ret);

return ret;

}

major=MAJOR(dev_num);

minor=MINOR(dev_num);

printk(KERN_INFO "major number: %dn",major);

printk(KERN_INFO "minor number: %dn",minor);

my_cdev.owner = THIS_MODULE;

cdev_init(&my_cdev,&fops);

cdev_add(&my_cdev,dev_num,1);

// 创建设备类

my_class = class_create(THIS_MODULE, "my_class");

if (IS_ERR(my_class)) {

pr_err("Failed to create classn");

return PTR_ERR(my_class);

}

// 创建设备节点并关联到设备类

my_device = device_create(my_class, NULL, MKDEV(major, minor), NULL, DEVICE_NAME);

if (IS_ERR(my_device)) {

pr_err("Failed to create devicen");

class_destroy(my_class);

return PTR_ERR(my_device);

}

printk(KERN_INFO "Device registered successfully.n");

return 0;

}

static void __exit mydevice_exit(void)

{

// 在这里执行驱动程序的清理操作

// 销毁设备节点

device_destroy(my_class, MKDEV(major, minor));

// 销毁设备类

class_destroy(my_class);

// 删除字符设备

cdev_del(&my_cdev);

// 注销字符设备驱动程序

unregister_chrdev(0, DEVICE_NAME);

printk(KERN_INFO "Device unregistered.n");

}

module_init(mydevice_init);

module_exit(mydevice_exit);

MODULE_LICENSE("GPL");      // 指定模块的许可证信息

MODULE_AUTHOR("Your Name"); // 指定模块的作者信息

MODULE_DESCRIPTION("A simple character device driver"); // 指定模块的描述信息

编译

复制7.3.4驱动中的Makefile文件,将其中的mydevice-auto.o修改为copy_to_user.o,效果如下:

. /opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi

elf@ubuntu:~/work/test/03_内核空间与用户空间的数据拷贝/copy_to_user$ make

将驱动模块编译成.ko并拷贝到开发板中。

编写测试应用源码copy_to_user.c

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/ioctl.h>

#include <errno.h>

#include <fcntl.h>

#include <string.h>

#define DEV_NAME "/dev/copy_to_user"

#define BUFFER_SIZE 1024

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

{

int reg;

int fd = 0;

char read_buffer[BUFFER_SIZE];

fd = open (DEV_NAME, O_RDWR);

if (fd < 0) {

perror("Open "DEV_NAME" Failed!n");

exit(1);

}

if (read(fd, read_buffer, BUFFER_SIZE) < 0) {

printf("Failed to read from device file: %sn", DEV_NAME);

close(fd);

exit(1);

}

printf("Read from device file: %sn", read_buffer);

close(fd);

return 0;

}

编译应用

. /opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi

elf@ubuntu:~/work/test/03_内核空间与用户空间的数据拷贝/copy_to_user_app$ $CC copy_to_user.c -o copy_to_user

将编译好的应用程序拷贝到开发板中。

测试

root@ELF1:~# insmod copy_to_user.ko

major number: 249

minor number: 0

Device registered successfully.

root@ELF1:~# ./copy_to_user

This is device_open.

This is device_read.

Read from device file: Hello, UseThis is device_release.

r! This is kernel_buffer!

root@ELF1:~# rmmod copy_to_user.ko

Device unregistered.

可以看到运行测试程序后,把内核空间中kernel_buffer[]中的数据打印了出来。

飞凌嵌入式

飞凌嵌入式

保定飞凌嵌入式技术有限公司,创建于2006年,是一家专注嵌入式核心控制系统研发、设计和生产的高新技术企业,是国内较早专业从事嵌入式技术的企业之一。 经过十几年的发展与积累,公司拥有业内优秀的软硬件研发团队,在北京及保定建立两大研发基地,在苏州、深圳设有华东、华南技术服务中心,并在北美、欧洲以及亚太等其他国家和地区拥有国际业务网络。公司研发的智能设备核心平台广泛应用于物联网、工控、轨道交通、医疗、电力、商业电子、智能家居、安防、机器人、环境监测等诸多领域。

保定飞凌嵌入式技术有限公司,创建于2006年,是一家专注嵌入式核心控制系统研发、设计和生产的高新技术企业,是国内较早专业从事嵌入式技术的企业之一。 经过十几年的发展与积累,公司拥有业内优秀的软硬件研发团队,在北京及保定建立两大研发基地,在苏州、深圳设有华东、华南技术服务中心,并在北美、欧洲以及亚太等其他国家和地区拥有国际业务网络。公司研发的智能设备核心平台广泛应用于物联网、工控、轨道交通、医疗、电力、商业电子、智能家居、安防、机器人、环境监测等诸多领域。收起

查看更多
点赞
收藏
评论
分享
加入交流群
举报

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录