Hannes Mayer wrote:
> Ciao Philippe et al.!
> 
> Philippe Gerum wrote:
> [...]
>> http://download.gna.org/xenomai/stable/xenomai-2.2.0.tar.bz2
> 
> Congratulations on the newest release! :-)
> 
> I've encountered a probably minor problem:
> I compiled the 16550A driver as module (everything else into
> the kernel), but when modprobing it said:
> couldn't find the kernel version the module was compiled for
> 
> I then recompiled the module with an own makefile, then it
> worked.

When you THEN try compiling the driver within the kernel build again,
does it still work? I bet it will, because this was likely some issue of
a half-baked kernel. I also re-checked this and noticed no problems
loading the driver.

> 
> Jan, I also updated the serial port example (I got my devel
> machine working again, so I tested on 2.2.0 today :-).
> Re. "mode-change explanation in your original email":
> I read thru them again and couldn't find what important
> stuff I left out. Please enlighten. Thanks :-)

Ok, let's go through the code I just collected from your side:

> void write_task_proc(void *arg) {
>   int ret;
>   ssize_t sz = sizeof(RTIME);
>   ssize_t written = 0;
>   unsigned char buf[17] = "CAPTAIN WAS HERE\0";
>   unsigned long overrun;
> 
>   ret = rt_task_set_periodic(NULL, TM_NOW, 
> rt_timer_ns2ticks(write_task_period_ns));
>   if (ret) {
>     printf(WTASK_PREFIX "error while set periodic, code %d\n",ret);
>     goto exit_write_task;
>   }
> 
>   while (1) {
>     /* switch to primary mode */
>     ret = rt_task_set_mode(0, T_PRIMARY, NULL);

Not needed because...

>     if (ret) {
>       printf(WTASK_PREFIX "error while rt_task_set_mode, code %d\n",ret);
>       goto exit_write_task;
>     }
>     ret = rt_task_wait_period(&overrun);

...this call requires primary mode anyway and will take care for a
switch back.

>     if (ret) {
>       printf(WTASK_PREFIX "error while rt_task_wait_period, code %d\n",ret);
>       goto exit_write_task;
>     }
>     sz = sizeof(buf);
>     written = rt_dev_write(my_fd, &buf, sizeof(buf));
>     printf(WTASK_PREFIX "rt_dev_write written=%d sz=%d\n", written, sz);
>     if (written != sz ) {
>       if (written < 0 ) {
>         printf(WTASK_PREFIX "error while rt_dev_write, code %d\n",written);
>       } else {
>         printf(WTASK_PREFIX "only %d / %d byte transmitted\n",written, sz);
>       }
>       goto exit_write_task;
>     }
>   }
> exit_write_task:
>   if (my_state & STATE_FILE_OPENED) {
>     if (!close_file( my_fd, RTSER_FILE " (write)")) {
>       my_state &= ~STATE_FILE_OPENED;
>     }
>   }
>   printf(WTASK_PREFIX "exit\n");
> }
>
> void read_task_proc(void *arg) {
>   int ret;
> //  RTIME irq_time   = 0;
>   ssize_t sz = sizeof(RTIME);
>   ssize_t red = 0;
>   struct rtser_event rx_event;
>   unsigned char buf[17];
> 
>   // we are in secondary mode now

Why? I suspect this comment is some kind of left-over of older code
(also given the dead variable irq_time above).

Keep in mind that real-time tasks always start in primary mode (I once
suggested to invert this for SCHED_OTHER / prio-0 tasks, but that's only
a concept yet).

>   while (1) {
>     /* switch to primary mode */
>     ret = rt_task_set_mode(0, T_PRIMARY, NULL);
>     if (ret) {
>       printf(RTASK_PREFIX "error while rt_task_set_mode, code %d\n",ret);
>       goto exit_read_task;
>     }
>     /* waiting for event */
>     // be careful not to do printf or so here. Otherwise rt_dev_ioctl
>     //    returns with an error, because we're not in hard real time
>     //    anymore (primary mode)

Partially true. Older revisions of Xenomai and this particular driver
(16550A) did fail this way. But now we simply switch over automatically
if some service is called from the "wrong" context.

The only still existing exception are (very rare!) services that are
provided for both contexts. In the 16550A driver: RTSER_RTIOC_SET_CONFIG
with RTSER_SET_TIMESTAMP_HISTORY set in the config mask must run in
non-RT context if the open call did so as well - consistent buffer
allocation from the same type of memory pool.

So, this means you can kill the set_mode, just like in my version I
suggested to cross-check. :)

>     ret = rt_dev_ioctl(my_fd, RTSER_RTIOC_WAIT_EVENT, &rx_event );
>     if (ret) {
>       printf(RTASK_PREFIX "error while RTSER_RTIOC_WAIT_EVENT, code 
> %d\n",ret);
>       goto exit_read_task;
>     }
>     //irq_time = rx_event.rxpend_timestamp;
>     sz = sizeof(buf);
>     red = rt_dev_read(my_fd, &buf, sizeof(buf));
>     if (red == sz ) {
>               printf(RTASK_PREFIX "rt_dev_read=%s\n",buf);
>     } else {
>       if (red < 0 ) {
>         printf(RTASK_PREFIX "error while rt_dev_read, code %d\n",red);
>       } else {
>         printf(RTASK_PREFIX "only %d / %d byte received \n",red,sz);
>       }
>       goto exit_read_task;
>     }
>   }
> exit_read_task:
>   if (my_state & STATE_FILE_OPENED) {
>     if (!close_file( my_fd, READ_FILE " (rtser)")) {
>       my_state &= ~STATE_FILE_OPENED;
>     }
>   }
>   printf(RTASK_PREFIX "exit\n");
> }

Jan


Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core

Reply via email to