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
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Xenomai-help mailing list [email protected] https://mail.gna.org/listinfo/xenomai-help
