xenomai驱动开发-参考博文-2驱动编写实例
作者:互联网
根据xenomai代码里面的example修改出一个字符驱动代码及其驱动对应的测试程序。
点击查看代码
#include <linux/module.h>
#include <rtdm/rtdm_driver.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("ziv,<woshidahuaidan2011@hotmail.com>");
#define SIZE_MAX 1024
#define DEVICE_NAME "mydriver"
#define SOME_SUB_CLASS 4711
/**
* The context of a device instance
*
* A context is created each time a device is opened and passed to
* other device handlers when they are called.
*
*/
typedef struct buffer_s {
int size;
char data[SIZE_MAX];
} buffer_t;
/**
* Open the device
*
* This function is called when the device shall be opened.
*
*/
static int simple_rtdm_open_nrt(struct rtdm_dev_context *context,
rtdm_user_info_t * user_info, int oflags)
{
buffer_t * buffer = (buffer_t *) context->dev_private;
buffer->size = 0; /* clear the buffer */
return 0;
}
/**
* Close the device
*
* This function is called when the device shall be closed.
*
*/
static int simple_rtdm_close_nrt(struct rtdm_dev_context *context,
rtdm_user_info_t * user_info)
{
return 0;
}
/**
* Read from the device
*
* This function is called when the device is read in non-realtime context.
*
*/
static ssize_t simple_rtdm_read_nrt(struct rtdm_dev_context *context,
rtdm_user_info_t * user_info, void *buf,
size_t nbyte)
{
buffer_t * buffer = (buffer_t *) context->dev_private;
int size = (buffer->size > nbyte) ? nbyte : buffer->size;
buffer->size = 0;
if (rtdm_safe_copy_to_user(user_info, buf, buffer->data, size))
rtdm_printk("ERROR : can't copy data from driver\n");
return size;
}
/**
* Write in the device
*
* This function is called when the device is written in non-realtime context.
*
*/
static ssize_t simple_rtdm_write_nrt(struct rtdm_dev_context *context,
rtdm_user_info_t * user_info,
const void *buf, size_t nbyte)
{
buffer_t * buffer = (buffer_t *) context->dev_private;
buffer->size = (nbyte > SIZE_MAX) ? SIZE_MAX : nbyte;
if (rtdm_safe_copy_from_user(user_info, buffer->data, buf, buffer->size))
rtdm_printk("ERROR : can't copy data to driver\n");
return nbyte;
}
int simple_rtdm_ioctl_nrt(struct rtdm_dev_context *context,
rtdm_user_info_t * user_info,
unsigned int request, void *arg)
{
int *return_size = (int *)arg;
int max_size = SIZE_MAX;
int valid_size = 0;
int err = 0;
buffer_t * buffer = (buffer_t *) context->dev_private;
valid_size = buffer->size;
switch (request) {
case 0x01:
err =
rtdm_safe_copy_to_user(user_info, return_size,
&max_size,
sizeof(int));
break;
case 0x02:
err =
rtdm_safe_copy_to_user(user_info, return_size,
&valid_size,
sizeof(int));
break;
default:
err = -ENOTTY;
}
return err;
}
/**
* This structure describe the simple RTDM device
*
*/
static struct rtdm_device device = {
.struct_version = RTDM_DEVICE_STRUCT_VER,
.device_flags = RTDM_NAMED_DEVICE,
.context_size = sizeof(buffer_t),
.device_name = DEVICE_NAME,
.open_nrt = simple_rtdm_open_nrt,
.ops = {
.close_nrt = simple_rtdm_close_nrt,
.read_nrt = simple_rtdm_read_nrt,
.write_nrt = simple_rtdm_write_nrt,
.ioctl_nrt = simple_rtdm_ioctl_nrt,
},
.device_class = RTDM_CLASS_EXPERIMENTAL,
.device_sub_class = SOME_SUB_CLASS,
.profile_version = 1,
.driver_name = "SimpleRTDM",
.driver_version = RTDM_DRIVER_VER(0, 1, 2),
.peripheral_name = "Simple RTDM example",
.provider_name = "trem",
.proc_name = device.device_name,
};
/**
* This function is called when the module is loaded
*
* It simply registers the RTDM device.
*
*/
int __init simple_rtdm_init(void)
{
return rtdm_dev_register(&device);
}
/**
* This function is called when the module is unloaded
*
* It unregister the RTDM device, polling at 1000 ms for pending users.
*
*/
void __exit simple_rtdm_exit(void)
{
rtdm_dev_unregister(&device, 1000);
}
module_init(simple_rtdm_init);
module_exit(simple_rtdm_exit);
标签:buffer,博文,rtdm,device,user,context,xenomai,驱动,size 来源: https://www.cnblogs.com/wangjirui/p/16486745.html