Nicolas BLANCHARD wrote:
> Hi,
>  
> I've write an rtdm driver and i have a problem.
> I use ioctl (rt_dev_ioctl) to read and write data (RTC time) on cmos. 
> (I know it could better to use _rt_dev_read or rt_dev_write 
>  but it was my first rtdm driver, and i' think that it's not the cause
> of my problem).
>  
> My user application (Native xenomai task) use this rt_dev_ioctl each
> 100 ms to read data on cmos.
> But, sometime (each 3 or 4 days), i read bad values.
>  
> this is the code to read the cmos (call in an rt_dev_ioctl) : 
>  
> //---------------------------------------------------------------------------------------------
> static unsigned char get_cmos_time(struct rtc146818drv_context *ctx,
>            struct rtc_time *rtc_tm)
> {
>  unsigned char uip;
>  rtdm_lockctx_t  lock_ctx;
>  
>  rtdm_lock_get_irqsave(&ctx->lock, lock_ctx); 
>  
>  uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
>  
>  if(uip == 0)
>  {
>       rtc_tm->tm_year = CMOS_READ(RTC_YEAR);
>       rtc_tm->tm_mon = CMOS_READ(RTC_MONTH);
>       rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
>       rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
>       rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
>       rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
>       rtc_tm->tm_wday = CMOS_READ(RTC_DAY_OF_WEEK);
> }
> rtc_tm->tm_yday = 0;
> rtc_tm->tm_isdst = 0;
> 
> rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx); 
>  
> return uip;
> }
> //---------------------------------------------------------------------------------------------
>  
> Data are read on MC146818A chipset, documentaton of this chipset
> explain that an update cycle is execute
> once per second and during this update  RTC_values or not fully
> available.
> So, we test the uip,when uip==0 the update cycle is not in progress and
> will not be for at least 244 us (for all time bases).
>  
> So to be sure that in thoses 244 us i've time to execute my code, i've
> disable the premption with rtdm_lock_get_irqsave.
> But sometime, like if the update cycle begin in the midle of my code, i
> read bad value (value 165 exactly).
>  
> For example i read this bad time : 
> "19/04/07 11:165:165 day 165" (like if i've been prempt after
> CMOS_READ(RTC_HOURS) instructions).
> or
> "19//04/165 165:165:165 day 165" (like if i've been prempt after
> CMOS_READ(RTC_MONTH) instructions).
>  
> We use the same hardware with other system (RTLinux), with same test on
> uip bit and we have no problem ( problem isn't on the chipset .. ).
>  
> So Is my rtdm_lock_get_irqsave and restore use correct ?
> Is it sure that my critical section is protected from any premption
> with this lock ?

rtdm_lock_get_irqsave protects against preemption, but did you check

 o how CMOS_READ is realised internally?
 o if there are other CMOS_xxx users in the stock kernel that can bite
   you?

As I already explained to you earlier, the CMOS access itself is
problematic because it contains non-atomic operations that must be
protected against re-entrance. Linux does this via
local_irq_save/restore etc. Xenomai breaks this mechanism by making
Linux fully preemptible. Even worse, your invocation of CMOS_READ in
Xenomai context also invokes Linux local_irq_restore, potentially
causing unwanted side effects.

The Linux preemptibility issue applies to RTLinux as well, just how
local_irq_save/restore behaves when being invoked from incorrect
context may differ and explain the observed behaviour.

Jan

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Xenomai-help mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-help

Reply via email to