* [Xenomai-core] [PATCH] add tut02-skeleton
@ 2007-05-28 15:23 trem
2007-05-28 17:40 ` Jan Kiszka
2007-05-28 18:26 ` Gilles Chanteperdrix
0 siblings, 2 replies; 7+ messages in thread
From: trem @ 2007-05-28 15:23 UTC (permalink / raw)
To: xenomai
[-- Attachment #1: Type: text/plain, Size: 283 bytes --]
Hi
Here is the second part of the tutorial serie about rtdm. I've just
added rt-task and semaphore. It's still a very very simple example.
Now, I don't know how to continue, have you got any idea of
"topic/subject" that could help people to understand xenomai ?
regards,
Philippe
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: tut02-skeleton.patch --]
[-- Type: text/x-patch; name="tut02-skeleton.patch", Size: 12175 bytes --]
Index: tut02-skeleton-app.c
===================================================================
--- tut02-skeleton-app.c (r���vision 0)
+++ tut02-skeleton-app.c (r���vision 0)
@@ -0,0 +1,114 @@
+/***************************************************************************
+ * Copyright (C) 2007 by trem (Philippe Reynes) *
+ * tremyfr@domain.hid *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/**
+ * This is an example that shows how RTDM devices can be used
+ * with a user space program in realtime context.
+ *
+ * The device tut02-skeleton-drv01 stores data that you write into.
+ * When you read from this device, previously stored data is returned,
+ * and the internal buffer is erased. But you can only do a read once per
+ * write. If you try to read more than you have written, the read is
+ * blocked unless a write is done.
+ *
+ * This program does the following:
+ * - If you give an argument to the command line, this argument is written
+ * in the device (with rt_dev_write)
+ * - If you don't give an argument to the command line, the progam read
+ * in the device (with rt_dev_read).
+ *
+ * To test this application, you just need to:
+ *
+ * $ export LD_LIBRARY_PATH=<path of xenomai>/lib
+ * $ insmod tut02-skeleton-drv.ko
+ * $ ./tut02-skeleton-app "Hello Master"
+ * $ ./tut02-skeleton-app
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/mman.h> /* for MCL_CURRENT and MCL_FUTURE */
+#include <string.h>
+#include <rtdm/rtdm.h>
+#include <native/task.h>
+
+#define DEVICE_NAME "tut02-skeleton-drv01"
+
+RT_TASK rt_task_desc;
+
+int main(int argc, char *argv[])
+{
+ char buf[1024];
+ ssize_t size;
+ int device;
+ int ret;
+
+ /* no memory-swapping for this programm */
+ mlockall(MCL_CURRENT | MCL_FUTURE);
+
+ /*
+ change the current task to RT-task
+ the task has no name to allow this program to be run several times
+ */
+ ret = rt_task_shadow(&rt_task_desc, NULL, 1, 0);
+ if (ret)
+ {
+ fprintf(stderr, "ERROR : rt_task_shadow: %s\n", strerror(-ret));
+ fflush(stdout);
+ exit(1);
+ }
+
+ /* open the device */
+ device = rt_dev_open(DEVICE_NAME, 0);
+ if (device < 0) {
+ printf("ERROR : can't open device %s (%s)\n",
+ DEVICE_NAME, strerror(-device));
+ fflush(stdout);
+ exit(1);
+ }
+
+ /*
+ if an argument was given on the command line, write it to the device,
+ otherwise, read in the device.
+ */
+ if (argc == 2)
+ {
+ sprintf(buf, "%s", argv[1]);
+ size = rt_dev_write (device, (const void *)buf, strlen(buf) + 1);
+ printf("Write from device %s\t: %d bytes\n", DEVICE_NAME, size);
+ }
+ else
+ {
+ size = rt_dev_read (device, (void *)buf, 1024);
+ printf("Read in device %s\t: %s\n", DEVICE_NAME, buf);
+ }
+
+ /* close the device */
+ ret = rt_dev_close(device);
+ if (ret < 0) {
+ printf("ERROR : can't close device %s (%s)\n",
+ DEVICE_NAME, strerror(-ret));
+ fflush(stdout);
+ exit(1);
+ }
+
+ return 0;
+}
Modification de propri���t���s sur tut02-skeleton-app.c
___________________________________________________________________
Nom : svn:eol-style
+ native
Index: tut02-skeleton-drv.c
===================================================================
--- tut02-skeleton-drv.c (r���vision 0)
+++ tut02-skeleton-drv.c (r���vision 0)
@@ -0,0 +1,245 @@
+/***************************************************************************
+ * Copyright (C) 2007 by trem (Philippe Reynes) *
+ * tremyfr@domain.hid *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/**
+ * This kernel driver demonstrates how an RTDM device can be set up.
+ *
+ * It is a simple device, only 4 operation are provided:
+ * - open: start device usage
+ * - close: ends device usage
+ * - write: store transfered data in an internal buffer (realtime context)
+ * - read: return previously stored data and erase buffer (realtime context)
+ *
+ */
+
+#include <linux/module.h>
+#include <rtdm/rtdm_driver.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("trem");
+
+#define SIZE_MAX 1024
+#define DEVICE_NAME "tut02-skeleton-drv01"
+#define SOME_SUB_CLASS 4711
+
+/**
+ * The structure of the buffer
+ *
+ */
+typedef struct buffer_s {
+ int size;
+ char data[SIZE_MAX];
+} buffer_t;
+
+/**
+ * The global buffer
+ *
+ */
+buffer_t buffer;
+
+/**
+ * The global semaphore
+ *
+ */
+rtdm_sem_t sem;
+
+/**
+ * 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)
+{
+ return 0;
+}
+
+/**
+ * Open the device
+ *
+ * This function is called when the device shall be opened in realtime-context.
+ *
+ */
+static int simple_rtdm_open_rt(struct rtdm_dev_context *context,
+ rtdm_user_info_t * user_info, int oflags)
+{
+ 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;
+}
+
+/**
+ * Close the device
+ *
+ * This function is called when the device shall be closed in realtime-context.
+ *
+ */
+static int simple_rtdm_close_rt(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)
+{
+ rtdm_printk("DEBUG : read is not implemented in non-realtime context\n");
+ return 0;
+}
+
+/**
+ * Read from the device
+ *
+ * This function is called when the device is read in realtime context.
+ *
+ */
+static ssize_t simple_rtdm_read_rt(struct rtdm_dev_context *context,
+ rtdm_user_info_t * user_info, void *buf,
+ size_t nbyte)
+{
+ int size;
+
+ /* take the semaphore */
+ rtdm_sem_down(&sem);
+
+ /* read the kernel buffer and sent it to user space */
+ size = (buffer.size > nbyte) ? nbyte : buffer.size;
+ if (rtdm_safe_copy_to_user(user_info, buf, buffer.data, size))
+ rtdm_printk("ERROR : can't copy data from driver\n");
+
+ /* clean the kernel buffer */
+ buffer.size = 0;
+
+ 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)
+{
+ rtdm_printk("DEBUG : write is not implemented in non-realtime context\n");
+ return 0;
+}
+
+/**
+ * Write in the device
+ *
+ * This function is called when the device is written in realtime context.
+ *
+ */
+static ssize_t simple_rtdm_write_rt(struct rtdm_dev_context *context,
+ rtdm_user_info_t * user_info,
+ const void *buf, size_t nbyte)
+{
+ /* release the semaphore */
+ rtdm_sem_up(&sem);
+
+ /* write the user buffer in the kernel buffer */
+ 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;
+}
+
+/**
+ * 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 = 0,
+ .device_name = DEVICE_NAME,
+
+ .open_nrt = simple_rtdm_open_nrt,
+ .open_rt = simple_rtdm_open_rt,
+
+ .ops = {
+ .close_nrt = simple_rtdm_close_nrt,
+ .close_rt = simple_rtdm_close_rt,
+ .read_nrt = simple_rtdm_read_nrt,
+ .read_rt = simple_rtdm_read_rt,
+ .write_nrt = simple_rtdm_write_nrt,
+ .write_rt = simple_rtdm_write_rt,
+ },
+
+ .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)
+{
+ buffer.size = 0; /* clear the buffer */
+ rtdm_sem_init(&sem, 0); /* init the global semaphore */
+
+ 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);
Modification de propri���t���s sur tut02-skeleton-drv.c
___________________________________________________________________
Nom : svn:eol-style
+ native
Index: Makefile
===================================================================
--- Makefile (r���vision 2484)
+++ Makefile (copie de travail)
@@ -1,13 +1,13 @@
###### CONFIGURATION ######
### List of applications to be build
-APPLICATIONS = tut01-skeleton-app
+APPLICATIONS = tut01-skeleton-app tut02-skeleton-app
### Note: to override the search path for the xeno-config script, use "make XENO=..."
### List of modules to be build
-MODULES = heartbeat-x86 tut01-skeleton-drv
+MODULES = heartbeat-x86 tut01-skeleton-drv tut02-skeleton-drv
### Note: to override the kernel source path, use "make KSRC=..."
@@ -86,6 +86,6 @@
clean::
$(RM) $(CLEANMOD) *.o *.ko *.mod.c Module*.symvers
- $(RM) -R .tmp*
+ $(RM) -R *~ .tmp*
endif
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [Xenomai-core] [PATCH] add tut02-skeleton
2007-05-28 15:23 [Xenomai-core] [PATCH] add tut02-skeleton trem
@ 2007-05-28 17:40 ` Jan Kiszka
2007-05-28 18:26 ` Gilles Chanteperdrix
1 sibling, 0 replies; 7+ messages in thread
From: Jan Kiszka @ 2007-05-28 17:40 UTC (permalink / raw)
To: trem; +Cc: xenomai
[-- Attachment #1: Type: text/plain, Size: 10671 bytes --]
trem wrote:
> Hi
>
> Here is the second part of the tutorial serie about rtdm. I've just
> added rt-task and semaphore. It's still a very very simple example.
Thanks again for your contribution. I have a few comments below.
>
> Now, I don't know how to continue, have you got any idea of
> "topic/subject" that could help people to understand xenomai ?
I think it would be good to dive into IRQ handling as this is part of
most drivers. Have a look at irqbench, specifically the UART part of it,
and the 16550A serial driver. Maybe you can try to create some topics
around a basic null-modem link between a Xenomai box and some other PC.
That would give you an IRQ source, a data source (the transmitted
characters), and enough food for things like synchronisation (mutexes,
spinlocks). Don't reimplement the full 16550A driver, only pick simple
aspects.
>
> regards,
> Philippe
>
>
> ------------------------------------------------------------------------
>
...
> Index: tut02-skeleton-drv.c
> ===================================================================
> --- tut02-skeleton-drv.c (révision 0)
> +++ tut02-skeleton-drv.c (révision 0)
> @@ -0,0 +1,245 @@
> +/***************************************************************************
> + * Copyright (C) 2007 by trem (Philippe Reynes) *
> + * tremyfr@domain.hid *
> + * *
> + * This program is free software; you can redistribute it and/or modify *
> + * it under the terms of the GNU General Public License as published by *
> + * the Free Software Foundation; either version 2 of the License, or *
> + * (at your option) any later version. *
> + * *
> + * This program is distributed in the hope that it will be useful, *
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of *
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
> + * GNU General Public License for more details. *
> + * *
> + * You should have received a copy of the GNU General Public License *
> + * along with this program; if not, write to the *
> + * Free Software Foundation, Inc., *
> + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
> + ***************************************************************************/
> +
> +/**
> + * This kernel driver demonstrates how an RTDM device can be set up.
This sounds familiar, like the first example. Doesn't this emphasis a
new, different topic?
> + *
> + * It is a simple device, only 4 operation are provided:
> + * - open: start device usage
> + * - close: ends device usage
> + * - write: store transfered data in an internal buffer (realtime context)
> + * - read: return previously stored data and erase buffer (realtime context)
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <rtdm/rtdm_driver.h>
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("trem");
> +
> +#define SIZE_MAX 1024
> +#define DEVICE_NAME "tut02-skeleton-drv01"
> +#define SOME_SUB_CLASS 4711
> +
> +/**
> + * The structure of the buffer
> + *
> + */
> +typedef struct buffer_s {
> + int size;
> + char data[SIZE_MAX];
> +} buffer_t;
> +
> +/**
> + * The global buffer
> + *
> + */
> +buffer_t buffer;
> +
> +/**
> + * The global semaphore
> + *
> + */
> +rtdm_sem_t sem;
Having plain global variables doesn't scale well. That actually makes me
think of further topcis for tutorials:
o Handling multiple devices with one driver
o Making use of device context buffers (rtdm_device::context_size)
> +
> +/**
> + * 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)
> +{
> + return 0;
> +}
> +
> +/**
> + * Open the device
> + *
> + * This function is called when the device shall be opened in realtime-context.
> + *
> + */
> +static int simple_rtdm_open_rt(struct rtdm_dev_context *context,
> + rtdm_user_info_t * user_info, int oflags)
> +{
> + return 0;
> +}
Don't register separate handlers for the same operation if they are
identical.
> +
> +/**
> + * 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;
> +}
> +
> +/**
> + * Close the device
> + *
> + * This function is called when the device shall be closed in realtime-context.
> + *
> + */
> +static int simple_rtdm_close_rt(struct rtdm_dev_context *context,
> + rtdm_user_info_t * user_info)
> +{
> + return 0;
> +}
Same here.
> +
> +/**
> + * 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)
> +{
> + rtdm_printk("DEBUG : read is not implemented in non-realtime context\n");
> + return 0;
Don't do this. If there is no nrt handler registered, Xenomai will
nicely switch a shadowed caller into RT mode (when required) and call
simple_rtdm_read_rt instead. With this handler registered, nothing
useful happens. Rather demonstrate context-sensitive handlers by doing
different things with them (but that's advanced stuff anyway).
> +}
> +
> +/**
> + * Read from the device
> + *
> + * This function is called when the device is read in realtime context.
> + *
> + */
> +static ssize_t simple_rtdm_read_rt(struct rtdm_dev_context *context,
> + rtdm_user_info_t * user_info, void *buf,
> + size_t nbyte)
> +{
> + int size;
> +
> + /* take the semaphore */
> + rtdm_sem_down(&sem);
> +
> + /* read the kernel buffer and sent it to user space */
> + size = (buffer.size > nbyte) ? nbyte : buffer.size;
> + if (rtdm_safe_copy_to_user(user_info, buf, buffer.data, size))
> + rtdm_printk("ERROR : can't copy data from driver\n");
Send the error code to the user instead of dumping it to the log. The
user will then be able to react on it.
> +
> + /* clean the kernel buffer */
> + buffer.size = 0;
> +
> + 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)
> +{
> + rtdm_printk("DEBUG : write is not implemented in non-realtime context\n");
> + return 0;
> +}
See above.
> +
> +/**
> + * Write in the device
> + *
> + * This function is called when the device is written in realtime context.
> + *
> + */
> +static ssize_t simple_rtdm_write_rt(struct rtdm_dev_context *context,
> + rtdm_user_info_t * user_info,
> + const void *buf, size_t nbyte)
> +{
> + /* release the semaphore */
> + rtdm_sem_up(&sem);
Oops, that creates a race: Data will be written to the buffer AFTER you
signal some reader that there is data available...
> +
> + /* write the user buffer in the kernel buffer */
> + 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;
> +}
> +
> +/**
> + * 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 = 0,
> + .device_name = DEVICE_NAME,
> +
> + .open_nrt = simple_rtdm_open_nrt,
> + .open_rt = simple_rtdm_open_rt,
> +
> + .ops = {
> + .close_nrt = simple_rtdm_close_nrt,
> + .close_rt = simple_rtdm_close_rt,
> + .read_nrt = simple_rtdm_read_nrt,
> + .read_rt = simple_rtdm_read_rt,
> + .write_nrt = simple_rtdm_write_nrt,
> + .write_rt = simple_rtdm_write_rt,
> + },
> +
> + .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)
> +{
> + buffer.size = 0; /* clear the buffer */
> + rtdm_sem_init(&sem, 0); /* init the global semaphore */
> +
> + 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);
>
> Modification de propriétés sur tut02-skeleton-drv.c
> ___________________________________________________________________
> Nom : svn:eol-style
> + native
>
> Index: Makefile
> ===================================================================
> --- Makefile (révision 2484)
> +++ Makefile (copie de travail)
> @@ -1,13 +1,13 @@
> ###### CONFIGURATION ######
>
> ### List of applications to be build
> -APPLICATIONS = tut01-skeleton-app
> +APPLICATIONS = tut01-skeleton-app tut02-skeleton-app
>
> ### Note: to override the search path for the xeno-config script, use "make XENO=..."
>
>
> ### List of modules to be build
> -MODULES = heartbeat-x86 tut01-skeleton-drv
> +MODULES = heartbeat-x86 tut01-skeleton-drv tut02-skeleton-drv
>
> ### Note: to override the kernel source path, use "make KSRC=..."
>
> @@ -86,6 +86,6 @@
>
> clean::
> $(RM) $(CLEANMOD) *.o *.ko *.mod.c Module*.symvers
> - $(RM) -R .tmp*
> + $(RM) -R *~ .tmp*
This last hunk looks unrelated.
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [Xenomai-core] [PATCH] add tut02-skeleton
2007-05-28 15:23 [Xenomai-core] [PATCH] add tut02-skeleton trem
2007-05-28 17:40 ` Jan Kiszka
@ 2007-05-28 18:26 ` Gilles Chanteperdrix
2007-05-28 20:08 ` trem
1 sibling, 1 reply; 7+ messages in thread
From: Gilles Chanteperdrix @ 2007-05-28 18:26 UTC (permalink / raw)
To: trem; +Cc: xenomai
trem wrote:
> + mlockall(MCL_CURRENT | MCL_FUTURE);
Please show people the right way to code, check the return value of
mlockall here.
> + if (rtdm_safe_copy_to_user(user_info, buf, buffer.data, size))
> + rtdm_printk("ERROR : can't copy data from driver\n");
> +
> + /* clean the kernel buffer */
> + buffer.size = 0;
> +
> + return size;
Same here, if rtdm_safe_copy_to_user returns an error, return that error
to user-space.
--
Gilles Chanteperdrix.
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [Xenomai-core] [PATCH] add tut02-skeleton
2007-05-28 18:26 ` Gilles Chanteperdrix
@ 2007-05-28 20:08 ` trem
2007-05-28 20:17 ` Gilles Chanteperdrix
0 siblings, 1 reply; 7+ messages in thread
From: trem @ 2007-05-28 20:08 UTC (permalink / raw)
To: xenomai
[-- Attachment #1: Type: text/plain, Size: 653 bytes --]
Hi
Thanks for the reply (jan too). I've tried to use all of your feedback,
and I send you the new release of this tut02.
regards,
Philippe
Gilles Chanteperdrix wrote:
> trem wrote:
> > + mlockall(MCL_CURRENT | MCL_FUTURE);
>
> Please show people the right way to code, check the return value of
> mlockall here.
>
> > + if (rtdm_safe_copy_to_user(user_info, buf, buffer.data, size))
> > + rtdm_printk("ERROR : can't copy data from driver\n");
> > +
> > + /* clean the kernel buffer */
> > + buffer.size = 0;
> > +
> > + return size;
>
> Same here, if rtdm_safe_copy_to_user returns an error, return that error
> to user-space.
>
>
>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: tut02-skeleton-v2.patch --]
[-- Type: text/x-patch; name="tut02-skeleton-v2.patch", Size: 10967 bytes --]
Index: tut02-skeleton-app.c
===================================================================
--- tut02-skeleton-app.c (r���vision 0)
+++ tut02-skeleton-app.c (r���vision 0)
@@ -0,0 +1,119 @@
+/***************************************************************************
+ * Copyright (C) 2007 by trem (Philippe Reynes) *
+ * tremyfr@domain.hid *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/**
+ * This is an example that shows how RTDM devices can be used
+ * with a user space program in realtime context.
+ *
+ * The device tut02-skeleton-drv01 stores data that you write into.
+ * When you read from this device, previously stored data is returned,
+ * and the internal buffer is erased. But you can only do a read once per
+ * write. If you try to read more than you have written, the read is
+ * blocked unless a write is done.
+ *
+ * This program does the following:
+ * - If you give an argument to the command line, this argument is written
+ * in the device (with rt_dev_write)
+ * - If you don't give an argument to the command line, the progam read
+ * in the device (with rt_dev_read).
+ *
+ * To test this application, you just need to:
+ *
+ * $ export LD_LIBRARY_PATH=<path of xenomai>/lib
+ * $ insmod tut02-skeleton-drv.ko
+ * $ ./tut02-skeleton-app "Hello Master"
+ * $ ./tut02-skeleton-app
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/mman.h> /* for MCL_CURRENT and MCL_FUTURE */
+#include <string.h> /* for strerror */
+#include <rtdm/rtdm.h>
+#include <native/task.h>
+
+#define DEVICE_NAME "tut02-skeleton-drv01"
+
+RT_TASK rt_task_desc;
+
+int main(int argc, char *argv[])
+{
+ char buf[1024];
+ ssize_t size;
+ int device;
+ int ret;
+
+ /* no memory-swapping for this programm */
+ ret = mlockall(MCL_CURRENT | MCL_FUTURE);
+ if (ret) {
+ fprintf(stderr, "ERROR : mlockall failled: %s\n", strerror(-ret));
+ fflush(stdout);
+ exit(1);
+ }
+
+ /*
+ change the current task to RT-task
+ the task has no name to allow this program to be run several times
+ */
+ ret = rt_task_shadow(&rt_task_desc, NULL, 1, 0);
+ if (ret)
+ {
+ fprintf(stderr, "ERROR : rt_task_shadow: %s\n", strerror(-ret));
+ fflush(stdout);
+ exit(1);
+ }
+
+ /* open the device */
+ device = rt_dev_open(DEVICE_NAME, 0);
+ if (device < 0) {
+ printf("ERROR : can't open device %s (%s)\n",
+ DEVICE_NAME, strerror(-device));
+ fflush(stdout);
+ exit(1);
+ }
+
+ /*
+ if an argument was given on the command line, write it to the device,
+ otherwise, read in the device.
+ */
+ if (argc == 2)
+ {
+ sprintf(buf, "%s", argv[1]);
+ size = rt_dev_write (device, (const void *)buf, strlen(buf) + 1);
+ printf("Write from device %s\t: %d bytes\n", DEVICE_NAME, size);
+ }
+ else
+ {
+ size = rt_dev_read (device, (void *)buf, 1024);
+ printf("Read in device %s\t: %s\n", DEVICE_NAME, buf);
+ }
+
+ /* close the device */
+ ret = rt_dev_close(device);
+ if (ret < 0) {
+ printf("ERROR : can't close device %s (%s)\n",
+ DEVICE_NAME, strerror(-ret));
+ fflush(stdout);
+ exit(1);
+ }
+
+ return 0;
+}
Modification de propri���t���s sur tut02-skeleton-app.c
___________________________________________________________________
Nom : svn:eol-style
+ native
Index: tut02-skeleton-drv.c
===================================================================
--- tut02-skeleton-drv.c (r���vision 0)
+++ tut02-skeleton-drv.c (r���vision 0)
@@ -0,0 +1,198 @@
+/***************************************************************************
+ * Copyright (C) 2007 by trem (Philippe Reynes) *
+ * tremyfr@domain.hid *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/**
+ * This kernel driver demonstrates how an RTDM device can be called from
+ * a RT task and how to use a semaphore.
+ *
+ * It is a simple device, only 4 operation are provided:
+ * - open: start device usage
+ * - close: ends device usage
+ * - write: store transfered data in an internal buffer (realtime context)
+ * - read: return previously stored data and erase buffer (realtime context)
+ *
+ */
+
+#include <linux/module.h>
+#include <rtdm/rtdm_driver.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("trem");
+
+#define SIZE_MAX 1024
+#define DEVICE_NAME "tut02-skeleton-drv01"
+#define SOME_SUB_CLASS 4711
+
+/**
+ * The structure of the buffer
+ *
+ */
+typedef struct buffer_s {
+ int size;
+ char data[SIZE_MAX];
+} buffer_t;
+
+/**
+ * The global buffer
+ *
+ */
+buffer_t buffer;
+
+/**
+ * The global semaphore
+ *
+ */
+rtdm_sem_t sem;
+
+/**
+ * Open the device
+ *
+ * This function is called when the device shall be opened.
+ *
+ */
+static int simple_rtdm_open(struct rtdm_dev_context *context,
+ rtdm_user_info_t * user_info, int oflags)
+{
+ return 0;
+}
+
+/**
+ * Close the device
+ *
+ * This function is called when the device shall be closed.
+ *
+ */
+static int simple_rtdm_close(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 realtime context.
+ *
+ */
+static ssize_t simple_rtdm_read_rt(struct rtdm_dev_context *context,
+ rtdm_user_info_t * user_info, void *buf,
+ size_t nbyte)
+{
+ int ret, size;
+
+ /* take the semaphore */
+ rtdm_sem_down(&sem);
+
+ /* read the kernel buffer and sent it to user space */
+ size = (buffer.size > nbyte) ? nbyte : buffer.size;
+ ret = rtdm_safe_copy_to_user(user_info, buf, buffer.data, size);
+
+ /* if an error has occured, send it to user */
+ if (ret) return ret;
+
+ /* clean the kernel buffer */
+ buffer.size = 0;
+
+ return size;
+}
+
+/**
+ * Write in the device
+ *
+ * This function is called when the device is written in realtime context.
+ *
+ */
+static ssize_t simple_rtdm_write_rt(struct rtdm_dev_context *context,
+ rtdm_user_info_t * user_info,
+ const void *buf, size_t nbyte)
+{
+ int ret;
+
+ /* write the user buffer in the kernel buffer */
+ buffer.size = (nbyte > SIZE_MAX) ? SIZE_MAX : nbyte;
+ ret = rtdm_safe_copy_from_user(user_info, buffer.data, buf, buffer.size);
+
+ /* if an error has occured, send it to user */
+ if (ret) return ret;
+
+ /* release the semaphore */
+ rtdm_sem_up(&sem);
+
+ return nbyte;
+}
+
+/**
+ * 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 = 0,
+ .device_name = DEVICE_NAME,
+
+ .open_nrt = simple_rtdm_open,
+ .open_rt = simple_rtdm_open,
+
+ .ops = {
+ .close_nrt = simple_rtdm_close,
+ .close_rt = simple_rtdm_close,
+ .read_rt = simple_rtdm_read_rt,
+ .write_rt = simple_rtdm_write_rt,
+ },
+
+ .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)
+{
+ buffer.size = 0; /* clear the buffer */
+ rtdm_sem_init(&sem, 0); /* init the global semaphore */
+
+ 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);
Modification de propri���t���s sur tut02-skeleton-drv.c
___________________________________________________________________
Nom : svn:eol-style
+ native
Index: Makefile
===================================================================
--- Makefile (r���vision 2484)
+++ Makefile (copie de travail)
@@ -1,13 +1,13 @@
###### CONFIGURATION ######
### List of applications to be build
-APPLICATIONS = tut01-skeleton-app
+APPLICATIONS = tut01-skeleton-app tut02-skeleton-app
### Note: to override the search path for the xeno-config script, use "make XENO=..."
### List of modules to be build
-MODULES = heartbeat-x86 tut01-skeleton-drv
+MODULES = heartbeat-x86 tut01-skeleton-drv tut02-skeleton-drv
### Note: to override the kernel source path, use "make KSRC=..."
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [Xenomai-core] [PATCH] add tut02-skeleton
2007-05-28 20:08 ` trem
@ 2007-05-28 20:17 ` Gilles Chanteperdrix
2007-05-28 21:58 ` trem
0 siblings, 1 reply; 7+ messages in thread
From: Gilles Chanteperdrix @ 2007-05-28 20:17 UTC (permalink / raw)
To: trem; +Cc: xenomai
trem wrote:
> Hi
>
> Thanks for the reply (jan too). I've tried to use all of your feedback,
> and I send you the new release of this tut02.
>
> (...)
> + /* no memory-swapping for this programm */
> + ret = mlockall(MCL_CURRENT | MCL_FUTURE);
> + if (ret) {
> + fprintf(stderr, "ERROR : mlockall failled: %s\n", strerror(-ret));
> + fflush(stdout);
> + exit(1);
> + }
Some further comment, mlockall returns its error in errno, so you should
replace strerror(-ret) with strerror(errno), or to make it short, use
perror.
Also note that since you fflush stdout after having printed the error
message, if there are any non printed message in stdout, they will only
appear after the error message, which will make it hard for the user to
catch the error message. Besides, exit already flushes the file
descriptors, so flushing stdout before calling exit is useless. IMHO,
you should call fflush(stdout) before printing the error message.
--
Gilles Chanteperdrix.
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [Xenomai-core] [PATCH] add tut02-skeleton
2007-05-28 20:17 ` Gilles Chanteperdrix
@ 2007-05-28 21:58 ` trem
2007-05-29 9:37 ` Jan Kiszka
0 siblings, 1 reply; 7+ messages in thread
From: trem @ 2007-05-28 21:58 UTC (permalink / raw)
To: xenomai
[-- Attachment #1: Type: text/plain, Size: 1292 bytes --]
Hi
You're right, perror could be used instead of strerror(-ret), it's
simpler. And I've remoded all "fflush", as you said, there are useless
and it's a tutorial about xenomai. So I think that those "fflush" aren't
necessary.
Thanks for feedback,
Philippe
Gilles Chanteperdrix wrote:
> trem wrote:
> > Hi
> >
> > Thanks for the reply (jan too). I've tried to use all of your feedback,
> > and I send you the new release of this tut02.
> >
> > (...)
> > + /* no memory-swapping for this programm */
> > + ret = mlockall(MCL_CURRENT | MCL_FUTURE);
> > + if (ret) {
> > + fprintf(stderr, "ERROR : mlockall failled: %s\n", strerror(-ret));
> > + fflush(stdout);
> > + exit(1);
> > + }
>
> Some further comment, mlockall returns its error in errno, so you should
> replace strerror(-ret) with strerror(errno), or to make it short, use
> perror.
> Also note that since you fflush stdout after having printed the error
> message, if there are any non printed message in stdout, they will only
> appear after the error message, which will make it hard for the user to
> catch the error message. Besides, exit already flushes the file
> descriptors, so flushing stdout before calling exit is useless. IMHO,
> you should call fflush(stdout) before printing the error message.
>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: tut02-skeleton-v3.patch --]
[-- Type: text/x-patch; name="tut02-skeleton-v3.patch", Size: 10823 bytes --]
Index: tut02-skeleton-app.c
===================================================================
--- tut02-skeleton-app.c (r���vision 0)
+++ tut02-skeleton-app.c (r���vision 0)
@@ -0,0 +1,114 @@
+/***************************************************************************
+ * Copyright (C) 2007 by trem (Philippe Reynes) *
+ * tremyfr@domain.hid *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/**
+ * This is an example that shows how RTDM devices can be used
+ * with a user space program in realtime context.
+ *
+ * The device tut02-skeleton-drv01 stores data that you write into.
+ * When you read from this device, previously stored data is returned,
+ * and the internal buffer is erased. But you can only do a read once per
+ * write. If you try to read more than you have written, the read is
+ * blocked unless a write is done.
+ *
+ * This program does the following:
+ * - If you give an argument to the command line, this argument is written
+ * in the device (with rt_dev_write)
+ * - If you don't give an argument to the command line, the progam read
+ * in the device (with rt_dev_read).
+ *
+ * To test this application, you just need to:
+ *
+ * $ export LD_LIBRARY_PATH=<path of xenomai>/lib
+ * $ insmod tut02-skeleton-drv.ko
+ * $ ./tut02-skeleton-app "Hello Master"
+ * $ ./tut02-skeleton-app
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/mman.h> /* for MCL_CURRENT and MCL_FUTURE */
+#include <rtdm/rtdm.h>
+#include <native/task.h>
+
+#define DEVICE_NAME "tut02-skeleton-drv01"
+
+RT_TASK rt_task_desc;
+
+int main(int argc, char *argv[])
+{
+ char buf[1024];
+ ssize_t size;
+ int device;
+ int ret;
+
+ /* no memory-swapping for this programm */
+ ret = mlockall(MCL_CURRENT | MCL_FUTURE);
+ if (ret) {
+ perror("ERROR : mlockall has failled");
+ exit(1);
+ }
+
+ /*
+ change the current task to RT-task
+ the task has no name to allow this program to be run several times
+ */
+ ret = rt_task_shadow(&rt_task_desc, NULL, 1, 0);
+ if (ret)
+ {
+ fprintf(stderr, "ERROR : rt_task_shadow: %s\n", strerror(-ret));
+ exit(1);
+ }
+
+ /* open the device */
+ device = rt_dev_open(DEVICE_NAME, 0);
+ if (device < 0) {
+ printf("ERROR : can't open device %s (%s)\n",
+ DEVICE_NAME, strerror(-device));
+ exit(1);
+ }
+
+ /*
+ if an argument was given on the command line, write it to the device,
+ otherwise, read in the device.
+ */
+ if (argc == 2)
+ {
+ sprintf(buf, "%s", argv[1]);
+ size = rt_dev_write (device, (const void *)buf, strlen(buf) + 1);
+ printf("Write from device %s\t: %d bytes\n", DEVICE_NAME, size);
+ }
+ else
+ {
+ size = rt_dev_read (device, (void *)buf, 1024);
+ printf("Read in device %s\t: %s\n", DEVICE_NAME, buf);
+ }
+
+ /* close the device */
+ ret = rt_dev_close(device);
+ if (ret < 0) {
+ printf("ERROR : can't close device %s (%s)\n",
+ DEVICE_NAME, strerror(-ret));
+ exit(1);
+ }
+
+ return 0;
+}
Modification de propri���t���s sur tut02-skeleton-app.c
___________________________________________________________________
Nom : svn:eol-style
+ native
Index: tut02-skeleton-drv.c
===================================================================
--- tut02-skeleton-drv.c (r���vision 0)
+++ tut02-skeleton-drv.c (r���vision 0)
@@ -0,0 +1,198 @@
+/***************************************************************************
+ * Copyright (C) 2007 by trem (Philippe Reynes) *
+ * tremyfr@domain.hid *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/**
+ * This kernel driver demonstrates how an RTDM device can be called from
+ * a RT task and how to use a semaphore.
+ *
+ * It is a simple device, only 4 operation are provided:
+ * - open: start device usage
+ * - close: ends device usage
+ * - write: store transfered data in an internal buffer (realtime context)
+ * - read: return previously stored data and erase buffer (realtime context)
+ *
+ */
+
+#include <linux/module.h>
+#include <rtdm/rtdm_driver.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("trem");
+
+#define SIZE_MAX 1024
+#define DEVICE_NAME "tut02-skeleton-drv01"
+#define SOME_SUB_CLASS 4711
+
+/**
+ * The structure of the buffer
+ *
+ */
+typedef struct buffer_s {
+ int size;
+ char data[SIZE_MAX];
+} buffer_t;
+
+/**
+ * The global buffer
+ *
+ */
+buffer_t buffer;
+
+/**
+ * The global semaphore
+ *
+ */
+rtdm_sem_t sem;
+
+/**
+ * Open the device
+ *
+ * This function is called when the device shall be opened.
+ *
+ */
+static int simple_rtdm_open(struct rtdm_dev_context *context,
+ rtdm_user_info_t * user_info, int oflags)
+{
+ return 0;
+}
+
+/**
+ * Close the device
+ *
+ * This function is called when the device shall be closed.
+ *
+ */
+static int simple_rtdm_close(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 realtime context.
+ *
+ */
+static ssize_t simple_rtdm_read_rt(struct rtdm_dev_context *context,
+ rtdm_user_info_t * user_info, void *buf,
+ size_t nbyte)
+{
+ int ret, size;
+
+ /* take the semaphore */
+ rtdm_sem_down(&sem);
+
+ /* read the kernel buffer and sent it to user space */
+ size = (buffer.size > nbyte) ? nbyte : buffer.size;
+ ret = rtdm_safe_copy_to_user(user_info, buf, buffer.data, size);
+
+ /* if an error has occured, send it to user */
+ if (ret) return ret;
+
+ /* clean the kernel buffer */
+ buffer.size = 0;
+
+ return size;
+}
+
+/**
+ * Write in the device
+ *
+ * This function is called when the device is written in realtime context.
+ *
+ */
+static ssize_t simple_rtdm_write_rt(struct rtdm_dev_context *context,
+ rtdm_user_info_t * user_info,
+ const void *buf, size_t nbyte)
+{
+ int ret;
+
+ /* write the user buffer in the kernel buffer */
+ buffer.size = (nbyte > SIZE_MAX) ? SIZE_MAX : nbyte;
+ ret = rtdm_safe_copy_from_user(user_info, buffer.data, buf, buffer.size);
+
+ /* if an error has occured, send it to user */
+ if (ret) return ret;
+
+ /* release the semaphore */
+ rtdm_sem_up(&sem);
+
+ return nbyte;
+}
+
+/**
+ * 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 = 0,
+ .device_name = DEVICE_NAME,
+
+ .open_nrt = simple_rtdm_open,
+ .open_rt = simple_rtdm_open,
+
+ .ops = {
+ .close_nrt = simple_rtdm_close,
+ .close_rt = simple_rtdm_close,
+ .read_rt = simple_rtdm_read_rt,
+ .write_rt = simple_rtdm_write_rt,
+ },
+
+ .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)
+{
+ buffer.size = 0; /* clear the buffer */
+ rtdm_sem_init(&sem, 0); /* init the global semaphore */
+
+ 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);
Modification de propri���t���s sur tut02-skeleton-drv.c
___________________________________________________________________
Nom : svn:eol-style
+ native
Index: Makefile
===================================================================
--- Makefile (r���vision 2484)
+++ Makefile (copie de travail)
@@ -1,13 +1,13 @@
###### CONFIGURATION ######
### List of applications to be build
-APPLICATIONS = tut01-skeleton-app
+APPLICATIONS = tut01-skeleton-app tut02-skeleton-app
### Note: to override the search path for the xeno-config script, use "make XENO=..."
### List of modules to be build
-MODULES = heartbeat-x86 tut01-skeleton-drv
+MODULES = heartbeat-x86 tut01-skeleton-drv tut02-skeleton-drv
### Note: to override the kernel source path, use "make KSRC=..."
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2007-05-29 9:37 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-28 15:23 [Xenomai-core] [PATCH] add tut02-skeleton trem
2007-05-28 17:40 ` Jan Kiszka
2007-05-28 18:26 ` Gilles Chanteperdrix
2007-05-28 20:08 ` trem
2007-05-28 20:17 ` Gilles Chanteperdrix
2007-05-28 21:58 ` trem
2007-05-29 9:37 ` Jan Kiszka
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.