nuttx
nuttx copied to clipboard
How to use multiple RTC drivers?
Does not NuttX support multiple RTCs?
I want to use the internal and external RTCs, but the definitions of functions conflict each other at building.
/path/to/nuttx/arch/arm/src/chip/cxd56_rtc.c:433: multiple definition of `up_rtc_settime'; /path/to/nuttx/staging/libdrivers.a(ds3231.o):/path/to//nuttx/drivers/timers/ds3231.c:387: first defined here
Can I specify that which I use with any interfaces?
@masayuki2009 @jerpelea any idea?
From the arch perspective, yes you can just have one RTC hook up_rtc_xxx api. But you can expose multiple RTC through /dev/rtcx by: https://github.com/apache/incubator-nuttx/blob/master/include/nuttx/timers/rtc.h
@takumiando Could you tell us your intention to use multiple RTCs?
@masayuki2009
I(actually our team) develop two editions of the IoT devices(same SoC) running NuttX.
The version A uses internal 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.
So you don't have two RTC hardware at the same time, but want to hook the different RTC hardware to up_rtc_xxx at runtime. One approach is:
- Implement two RTC drivers by follow https://github.com/apache/incubator-nuttx/blob/master/include/nuttx/timers/rtc.h
- Let arch_rtc.c implement up_xxx for you by call up_rtc_set_lowerhalf: https://github.com/apache/incubator-nuttx/blob/master/include/nuttx/timers/arch_rtc.h#L45
In step 2, you check which RTC hardware exist and pass the different rtc_lowerhalf_s instance to up_rtc_set_lowerhalf.
@xiaoxiang781216
Thank you for your kind explanation! I understand your idea.
But many internal RTC lower-half drivers are enabled with each up_rtc_xxx()
implementations at the same time.
For example: /arch/arm/src/stm32/Make.defs
ifeq ($(CONFIG_STM32_RTC),y)
CHIP_CSRCS += stm32_rtc.c
ifeq ($(CONFIG_RTC_ALARM),y)
CHIP_CSRCS += stm32_exti_alarm.c
endif
ifeq ($(CONFIG_RTC_PERIODIC),y)
CHIP_CSRCS += stm32_exti_wakeup.c
endif
ifeq ($(CONFIG_RTC_DRIVER),y)
CHIP_CSRCS += stm32_rtc_lowerhalf.c
endif
endif
In this case, I think that stm32_rtc.c
(up_rtc_xxx()
implementations) and arch_rtc.c
conflict because of same function names.
Should I modify each Make.defs
to build only lower-half drivers and arch_rtc.c
?
@xiaoxiang781216
Thank you for your kind explanation! I understand your idea.
But many internal RTC lower-half drivers are enabled with each
up_rtc_xxx()
implementations at the same time.For example:
/arch/arm/src/stm32/Make.defs
ifeq ($(CONFIG_STM32_RTC),y) CHIP_CSRCS += stm32_rtc.c ifeq ($(CONFIG_RTC_ALARM),y) CHIP_CSRCS += stm32_exti_alarm.c endif ifeq ($(CONFIG_RTC_PERIODIC),y) CHIP_CSRCS += stm32_exti_wakeup.c endif ifeq ($(CONFIG_RTC_DRIVER),y) CHIP_CSRCS += stm32_rtc_lowerhalf.c endif endif
In this case, I think that
stm32_rtc.c
(up_rtc_xxx()
implementations) andarch_rtc.c
conflict because of same function names.Should I modify each
Make.defs
to build only lower-half drivers andarch_rtc.c
?
Yes, you can:
- Enable CONFIG_RTC_DRIVER but disable CONFIG_STM32_RTC to include stm32 lower-half driver only
- Enable your external RTC driver
- Enable arch_rtc driver by CONFIG_RTC_ARCH
- Check which hardware exist in your board file, and pass the exist instance to up_rtc_set_lowerhalf
@xiaoxiang781216
Thank you, I will try them!
By the way,
- Why do lower-half drivers depend on
up_rtc_xxx()
implementations inMake.defs
? We cannot enable only lower-half in current codes. - Why are NOT lower-half drivers for external RTCs(under
/drivers/timers/
) implemented? What is difference between internals and externals?
I don't understand these policies...
@xiaoxiang781216
Thank you, I will try them!
By the way,
- Why do lower-half drivers depend on
up_rtc_xxx()
implementations inMake.defs
?
arch_rtc.c is introduced very later. Before that, all RTC driver need not only implement rtc_lowerhalf_s, but also up_rtc_xxx.
We cannot enable only lower-half in current codes.
- Why are NOT lower-half drivers for external RTCs(under
/drivers/timers/
) implemented? What is difference between internals and externals?I don't understand these policies...
Since internal RTC is part of SoC, which code should put into arch/xxx/yyy/. External RTC connected to SoC through I2C/1wire/SPI, which code should put into drivers/timer/.
arch_rtc.c is introduced very later. Before that, all RTC driver need not only implement rtc_lowerhalf_s, but also up_rtc_xxx.
So, lower-half drivers for external RTCs(under /drivers/timers/
) are JUST NOT implemented yet, correct?