sonydevworld / spresense

Spresense SDK source code
https://developer.sony.com/develop/spresense/docs/home_en.html
Other
149 stars 106 forks source link

Why RTC lower-half driver calls a function from upper-half one? #498

Closed takumiando closed 11 months ago

takumiando commented 2 years ago

My understanding, RTC drivers are designed that it can be separated by upper-half and lower-half in NuttX. https://nuttx.apache.org/docs/latest/components/drivers/character/rtc.html

But the up_rtc_gettime() implemented in nuttx/arch/arm/src/cxd56_rtc.c is called by cxd56_rdtime() in nuttx/arch/arm/src/cxd56_rtc_lowerhalf.c.

Why is a upper-half function called in lower-half one?
I'd like to understand these design and implementation.

I cannot switch two or more lower-half drivers with a generic upper-half driver(nuttx/drivers/timers/arch_rtc.c) in current SDK.

takumiando commented 2 years ago

I(actually our team) develop two editions of the IoT devices with SPRESENSE. The version A uses onboard RTC and the version B should use external one.

But I don't want to release two firmware binaries for each editions(for costs!). So I want to switch RTCs in a same firmware by EEPROM, status of GPIO, etc.

Do you have any good ideas?

https://github.com/apache/incubator-nuttx/issues/7089

SPRESENSE commented 2 years ago

@takumiando san As the incubator-nuttx issue comment, arch_rtc.c is introduced very later, and is not used by Spresense. Spresense is using drivers/timers/rtc.c as the upper-half driver. And, the lower-half driver is implemented in cxd56_rtc_lowerhalf.c using the chip-internal RTC.

  graph TD;
      drivers/timers/rtc.c-->cxd56_rtc_lowerhalf.c;
      cxd56_rtc_lowerhalf.c-->cxd56_rtc.c;

If you want to switch RTC device drivers via /dev/rtc, you can implement another external lower-half driver and switch the lower-half driver to register with rtc_initialize().

  graph TD;
      drivers/timers/rtc.c-->cxd56_rtc_lowerhalf.c;
      cxd56_rtc_lowerhalf.c-->cxd56_rtc.c;
      drivers/timers/rtc.c-->External_lowerhalf_driver;

On the other hand, up_rtc_xxx() functions are also used from sched/clock. I think that even in cases where an external RTC is used, sched/clock can continue to use the internal RTC.

If you want to also switch the RTC used from sched/clock, the up_rtc_xxx function will be conflicted as you know.

It may be easier to dynamically switch between RTC internal or external on the up_rtc_xxx() functions.