Hello,
I decided to try NuttX out - just as a hobbyist for learning experience.
I am currently attempting to create port for DA/DB family of AVR
architecture with support for tickless OS. My initial implementation
worked sort-of well: I created a simple application with a LED blinking
in 1/2 second interval using usleep() and tried it with USEC_PER_TICK
set to 62500. There was some imprecision in the frequency but that is to
be expected. However, when I tried to tweak USEC_PER_TICK, the results
became weird. NuttX requested (via up_alarm_start) to set the alarm in
nonsensical intervals - 29 seconds, a day... or a few microseconds.
After some debugging I found out that up_alarm_tick_cancel in
sched/sched/sched_timerexpiration.c reads an incorrect ticks value from
clock_time2ticks macro. It received 0 seconds, 0x77358ns as a parameter,
which - rounded up - should yield 1 tick with USEC_PER_TICK set to 1000.
Instead, it was returning 29 ticks. I tried to make a simple standalone
reimplementation of clock_time2ticks and NSEC2TICK from
include/nuttx/clock.h to see what exactly is going on and it worked
well, returned correct result of 1. I then tried to compare the
generated assembly and found out the difference: while the
reimplementation was calculating (nsec + 999999) / 1000000, NuttX was
counting (nsec + 16959) / 16960. The former is 0xf423f and 0xf4240 in
hex, the latter is 0x423f and 0x4240 which led me to the idea that the
compiler truncates something to 16bit - that something turned to be
NSEC_PER_TICK.
I then changed NSEC_PER_USEC to 1000L, the calculation in
clock_time2ticks corrected itself and the timer seems to work like a
charm. (I can't explain why the reimplementation worked corectly though,
it was setting NSEC_PER_USEC to 1000 without the "L" as well. Yet in
this case, the compiler did the right thing.)
In case I ever decided that my code is actually worth contributing(*),
is this change (and to be safe, same thing for USEC_PER_MSEC and
MSEC_PER_SEC) acceptable? I have to admit that I have little clue what
it can do (ie. break) for other architectures.
Thanks for any input
(*) which may be problematic in itself - as far as I found on the NuttX
website, PR on GitHub is the only listed way contributions are accepted.
I can provide publicly accessible Git repo but I don't have a GitHub
account and am not willing to make one for a few reasons.
- Can NSEC_PER_USEC in clock.h be changed to 1000L? kr . git
-