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);
    
    posted @   相对维度  阅读(233)  评论(0编辑  收藏  举报
    相关博文:
    阅读排行:
    · 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
    · 地球OL攻略 —— 某应届生求职总结
    · 周边上新:园子的第一款马克杯温暖上架
    · 提示词工程——AI应用必不可少的技术
    · Open-Sora 2.0 重磅开源!
    点击右上角即可分享
    微信分享提示