From mboxrd@z Thu Jan 1 00:00:00 1970 Date: Tue, 21 Mar 2006 15:03:14 +0100 From: "Petr Cervenka" MIME-Version: 1.0 Message-ID: <200603211503.22918@domain.hid> References: 00603201434.15258@domain.hid> <200603201434.15258@domain.hid> <441ED657.1080405@domain.hid> <200603201901.3123@domain.hid> <441F3476.1080003@domain.hid> In-Reply-To: <441F3476.1080003@domain.hid> Subject: Re: [Xenomai-help] rtdm_event_timedwait hang-up - SOLVED Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7BIT List-Id: Help regarding installation and common use of Xenomai List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: jan.kiszka@domain.hid Cc: xenomai@xenomai.org The problem was in my calling "RT" task. I forgot to switch the new created task to PRIMARY MODE, because I didn't know it's neccessary. I still have same problems with porting the driver, but I think I can handle them myself. Thanks for your help. Petr Cervenka > Petr Cervenka wrote: > > I' tried to create user realtime task, and after all effort (and > > many related partial problems solved) I still cannot do blocking > > variant of rtdm_event_timedwait. > > 1) How can I recognize, that the function is called within proper > > context / ie. is there an rtdm equivalent to xnpod_unblockable_p? > > First of all, there is the concept of the dual entry points, one for RT > (xxx_rt), the other for non-RT (xxx_nrt). If your driver only registers > a handler on xxx_rt, it will never get called in unblockable context. If > it registers different functions on those entry points, it can easily > tell the contexts apart. > > Given that you have some significant amount of code to share between a > RT and a non-RT invocation, you can register the same handler on both > entry points. Then rtdm_in_rt_context() will tell you in which context > you currently are. > > > 2) Could be the problem elsewhere? > > I prepared the attached patch that catches illegal service > invocations. It will get checked in as soon as we decided how to switch > XENO_ASSERTs on. For now this is done via CONFIG_XENO_OPT_DEBUG. Feel > free to apply it on your Xenomai code and check if it's useful. I tested > it a bit, and it didn't break anything of RTDM in an obvious way. :) > > > 3) My General Standards PCI-24DSI-12 card is not supported by comedi. > > And I'm not familiar with it either. The original driver is not so > > complicated and the port looked as easy work ;-) But waiting inside > > I can understand that you do not want to complicate your job with comedi > when there is no support for your hardware anyway. > > > ioctl or read handler for an interrupt is critical for proper > > functionality. > > This must work. See the 16550A driver e.g., it has a similar design, > specifically for handling RTSER_RTIOC_WAIT_EVENT. > > > 4) I realized when I make a realtime task (prio 1 ~ lowest, I hope) > > and in my main (nrt) task I call sleep(1), It will fall asleep > > forever (or maybe to some signal). > > Sounds like something is blocking the Linux timer. Did you accidentally > register your driver on it? See /proc/interrupts for the timer IRQ > counter, in contrast to /proc/xenomai/irq. > > > 5) Is it possible to set some event or to send signal/message/... > > from rt to nrt and back? > > rt->nrt: rtdm_nrtsig_xxx > nrt->rt: any blocking rtdm-IPC service (except for mutexes of course) > can be signalled also from non-rt > > > 6) Is there some easy-to-understand documentation? What I can or > > cannot...? > > Did you browse the API documentation of RTDM, maybe also had a look at > the related RTDM-and-Applications.pdf (hmm, were does a user get this > from? At least, it's in the SVN, but the homepage still requires an > update...)? If yes, please let us know what remains unclear and what > would be additionally desirable. A tour on RTDM, like Philippe already > wrote for other subsystems, would be nice - it just takes someone to > write it... > > > Petr Cervenka > > > > Jan > > Index: include/rtdm/rtdm_driver.h > =================================================================== > --- include/rtdm/.svn/text-base/rtdm_driver.h.svn-base 2006-03-09 > 22:16:03.000000000 +0100 > +++ include/rtdm/rtdm_driver.h 2006-03-20 17:55:10.000000000 +0100 > @@ -38,6 +38,7 @@ > #include > #include > #include > +#include > #include > > > @@ -890,6 +891,7 @@ static inline rtdm_task_t *rtdm_task_cur > > static inline int rtdm_task_wait_period(void) > { > + XENO_ASSERT(!xnpod_unblockable_p(), return -EPERM;); > return xnpod_wait_thread_period(NULL); > } > > Index: include/nucleus/assert.h > =================================================================== > --- include/nucleus/.svn/text-base/assert.h.svn-base 2006-03-08 > 00:48:14.000000000 +0100 > +++ include/nucleus/assert.h 2006-03-20 20:04:10.000000000 +0100 > @@ -22,18 +22,14 @@ > > #include > > -#ifndef CONFIG_XENO_OPT_DEBUG_LEVEL > -#define CONFIG_XENO_OPT_DEBUG_LEVEL 0 > -#endif > - > -#if CONFIG_XENO_OPT_DEBUG_LEVEL > 0 > +#if CONFIG_XENO_OPT_DEBUG > #define XENO_ASSERT(cond,action) do { \ > if (unlikely((cond) != 0)) \ > do { action; } while(0); \ > } while(0) > -#else /* CONFIG_XENO_OPT_DEBUG_LEVEL == 0 */ > +#else /* !CONFIG_XENO_OPT_DEBUG */ > #define XENO_ASSERT(cond,action) do { } while(0) > -#endif /* CONFIG_XENO_OPT_DEBUG_LEVEL > 0 */ > +#endif /* CONFIG_XENO_OPT_DEBUG */ > > #define XENO_BUGON(cond) \ > XENO_ASSERT(cond,xnpod_fatal("assertion failed at > %s:%d",__FILE__,__LINE__)) > Index: ksrc/skins/rtdm/drvlib.c > =================================================================== > --- ksrc/skins/rtdm/.svn/text-base/drvlib.c.svn-base 2006-03-13 > 23:13:19.000000000 +0100 > +++ ksrc/skins/rtdm/drvlib.c 2006-03-20 20:11:38.000000000 +0100 > @@ -279,6 +279,8 @@ void rtdm_task_join_nrt(rtdm_task_t *tas > spl_t s; > > > + XENO_ASSERT(xnpod_root_p(), return;); > + > xnlock_get_irqsave(&nklock, s); > > while (!xnthread_test_flags(task, XNZOMBIE)) { > @@ -305,6 +307,9 @@ EXPORT_SYMBOL(rtdm_task_join_nrt); > * - -EINTR is returned if calling task has been unblock by a signal or > * explicitely via rtdm_task_unblock(). > * > + * - -EPERM @e may be returned if an illegal invocation environment is > + * detected. > + * > * Environments: > * > * This service can be called from: > @@ -319,6 +324,8 @@ int rtdm_task_sleep(uint64_t delay) > xnthread_t *thread = xnpod_current_thread(); > > > + XENO_ASSERT(!xnpod_unblockable_p(), return -EPERM;); > + > xnpod_suspend_thread(thread, XNDELAY, xnpod_ns2ticks(delay), NULL); > > return xnthread_test_flags(thread, XNBREAK) ? -EINTR : 0; > @@ -337,6 +344,9 @@ EXPORT_SYMBOL(rtdm_task_sleep); > * - -EINTR is returned if calling task has been unblock by a signal or > * explicitely via rtdm_task_unblock(). > * > + * - -EPERM @e may be returned if an illegal invocation environment is > + * detected. > + * > * Environments: > * > * This service can be called from: > @@ -354,6 +364,8 @@ int rtdm_task_sleep_until(uint64_t wakeu > int err = 0; > > > + XENO_ASSERT(!xnpod_unblockable_p(), return -EPERM;); > + > xnlock_get_irqsave(&nklock, s); > > delay = xnpod_ns2ticks(wakeup_time) - xnpod_get_time(); > @@ -626,6 +638,9 @@ EXPORT_SYMBOL(rtdm_event_signal); > * > * - -EIDRM is returned if @a event has been destroyed. > * > + * - -EPERM @e may be returned if an illegal invocation environment is > + * detected. > + * > * Environments: > * > * This service can be called from: > @@ -641,6 +656,8 @@ int rtdm_event_wait(rtdm_event_t *event) > int err = 0; > > > + XENO_ASSERT(!xnpod_unblockable_p(), return -EPERM;); > + > xnlock_get_irqsave(&nklock, s); > > if (testbits(event->synch_base.status, SYNCH_DELETED)) > @@ -689,6 +706,9 @@ EXPORT_SYMBOL(rtdm_event_wait); > * > * - -EIDRM is returned if @a event has been destroyed. > * > + * - -EPERM @e may be returned if an illegal invocation environment is > + * detected. > + * > * Environments: > * > * This service can be called from: > @@ -706,6 +726,8 @@ int rtdm_event_timedwait(rtdm_event_t *e > int err = 0; > > > + XENO_ASSERT(!xnpod_unblockable_p(), return -EPERM;); > + > xnlock_get_irqsave(&nklock, s); > > if (unlikely(testbits(event->synch_base.status, SYNCH_DELETED))) > @@ -810,6 +832,9 @@ void rtdm_sem_destroy(rtdm_sem_t *sem); > * > * - -EIDRM is returned if @a sem has been destroyed. > * > + * - -EPERM @e may be returned if an illegal invocation environment is > + * detected. > + * > * Environments: > * > * This service can be called from: > @@ -825,6 +850,8 @@ int rtdm_sem_down(rtdm_sem_t *sem) > int err = 0; > > > + XENO_ASSERT(!xnpod_unblockable_p(), return -EPERM;); > + > xnlock_get_irqsave(&nklock, s); > > if (testbits(sem->synch_base.status, SYNCH_DELETED)) > @@ -878,6 +905,9 @@ EXPORT_SYMBOL(rtdm_sem_down); > * > * - -EIDRM is returned if @a sem has been destroyed. > * > + * - -EPERM @e may be returned if an illegal invocation environment is > + * detected. > + * > * Environments: > * > * This service can be called from: > @@ -895,6 +925,8 @@ int rtdm_sem_timeddown(rtdm_sem_t *sem, > int err = 0; > > > + XENO_ASSERT(!xnpod_unblockable_p(), return -EPERM;); > + > xnlock_get_irqsave(&nklock, s); > > if (testbits(sem->synch_base.status, SYNCH_DELETED)) > @@ -1035,6 +1067,9 @@ void rtdm_mutex_destroy(rtdm_mutex_t *mu > * > * - -EIDRM is returned if @a mutex has been destroyed. > * > + * - -EPERM @e may be returned if an illegal invocation environment is > + * detected. > + * > * Environments: > * > * This service can be called from: > @@ -1050,6 +1085,8 @@ int rtdm_mutex_lock(rtdm_mutex_t *mutex) > int err = 0; > > > + XENO_ASSERT(!xnpod_unblockable_p(), return -EPERM;); > + > xnlock_get_irqsave(&nklock, s); > > if (testbits(mutex->synch_base.status, SYNCH_DELETED)) > @@ -1097,6 +1134,9 @@ EXPORT_SYMBOL(rtdm_mutex_lock); > * > * - -EIDRM is returned if @a mutex has been destroyed. > * > + * - -EPERM @e may be returned if an illegal invocation environment is > + * detected. > + * > * Environments: > * > * This service can be called from: > @@ -1114,6 +1154,8 @@ int rtdm_mutex_timedlock(rtdm_mutex_t *m > int err = 0; > > > + XENO_ASSERT(!xnpod_unblockable_p(), return -EPERM;); > + > xnlock_get_irqsave(&nklock, s); > > if (testbits(mutex->synch_base.status, SYNCH_DELETED)) > @@ -1179,6 +1221,8 @@ void rtdm_mutex_unlock(rtdm_mutex_t *mut > spl_t s; > > > + XENO_ASSERT(!xnpod_asynch_p(), return;); > + > xnlock_get_irqsave(&nklock, s); > > __clear_bit(0, &mutex->locked); > @@ -1426,6 +1470,9 @@ static struct file_operations rtdm_mmap_ > * - -EAGAIN is returned if too much memory has been already locked by > the > * user process. > * > + * - -EPERM @e may be returned if an illegal invocation environment is > + * detected. > + * > * @note RTDM supports two models for unmapping the user memory range > again. > * One is explicite unmapping via rtdm_munmap(), either performed when > the > * user requests it via an IOCTL etc. or when the related device is > closed. > @@ -1457,6 +1504,9 @@ int rtdm_mmap_to_user(rtdm_user_info_t * > void *old_priv_data; > void *user_ptr; > > + > + XENO_ASSERT(xnpod_root_p(), return -EPERM;); > + > filp = filp_open("/dev/zero", O_RDWR, 0); > if (IS_ERR(filp)) > return PTR_ERR(filp); > @@ -1499,6 +1549,9 @@ EXPORT_SYMBOL(rtdm_mmap_to_user); > * > * - -EINVAL is returned if an invalid address or size was passed. > * > + * - -EPERM @e may be returned if an illegal invocation environment is > + * detected. > + * > * Environments: > * > * This service can be called from: > @@ -1512,6 +1565,9 @@ int rtdm_munmap(rtdm_user_info_t *user_i > { > int err; > > + > + XENO_ASSERT(xnpod_root_p(), return -EPERM;); > + > down_write(&user_info->mm->mmap_sem); > err = do_munmap(user_info->mm, (unsigned long)ptr, len); > up_write(&user_info->mm->mmap_sem); > >