>>>> Jan
Kiszka <jan.kiszka@domain.hid> 19.04 13:55 >>>
>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.
>
Ok, that right.
CMOS_READ call local_irq_save and local_irq_restore.
I've write my CMOS_READ function ... without those local_irq_ call. It's on
test.
>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
>
With RtLinux we used rtl_crtical and rtl_end_crtical functions,
after some define and macro
i can see that it corresponding on cli ans sti processor instructions. In
this case, if local_irq_ call
on CMOS_READ have no negative effect it's perhaps because those
calls have been changed by the rtlinux patch.
I was thinking that with xenomai, all local_irq_ call are catch by the
adeos layer and just the rtdm_lock_irq could
make cli and sti processor instructions ... But it seems to be different.
I'm not very experimented with thoses concepts
(that why i' have not understand your previous explanation :-) ).
thanks a lot.
blanchard nicolas