Well, I tried the rv32m1 but at the moment, I can't get its nsh config to compile. Apparently, Debian version of GCC for Risc-V does not contain math.h for some reason and changing the configuration to NuttX internal math library failed as well. (Picolibc has math.h, if I find the time, I may try that one too but I think it's not going to be as easy either.)

Anyway, hiding the generic up_udelay behind a configuration option seems straightforward enough so I'll give it a try.

Thanks for the help.

On 2026-03-02 19:47, Alan C. Assis wrote:
Hi KR,

I'm not expert on this issue, but I took a look and have an idea about this
issue (please take my advice with a grain of salt) :

Looking at arch/ I see only other 3 archs implement it:

$ git grep "void up_udelay"
arm/src/cxd56xx/cxd56_delay.c:void up_udelay(useconds_t microseconds)
risc-v/src/mpfs/mpfs_perf.c:void up_udelay(useconds_t microseconds)
risc-v/src/rv32m1/rv32m1_delay.c:void up_udelay(useconds_t microseconds)

So, chances are that none of these archs are in fact using these functions (please double check, but I think they are facing the same issue as you).

Why? Because normally a weak function is not extracted from the .a lib
unless the linked can't find a definition to it.

And because it is already finding it at libsched.a (coming
from sched/clock/clock_delay.c) it will not try to extract another one from
libarch.a (even although your implementation doesn't have a week).

So, I think the proper solution should be creating
a CONFIG_ARCH_HAVE_UDELAY to be added to ARCHs that support it and
surround the up_udelay() at clock_delay.c with it.

#ifndef CONFIG_ARCH_HAVE_UDELAY
void weak_function up_udelay(useconds_t microseconds)
{
  udelay_coarse(microseconds);
}
#endif

(same to mdelay and ndelay functions)

BR,

Alan


On Mon, Mar 2, 2026 at 1:00 PM <[email protected]> wrote:

Hello,

I would like to ask for help regarding the build process. It seems to be
ignoring functions defined in a source code file for some reason and I
can't figure it out.

I am attempting to reimplement up_udelay for AVR, so I created file
arch/avr/src/avrdx/avrdx_delay.c . To my understanding, since the
function is defined as weak in sched/clock/clock_delay.c , the only
thing needed is to define another function with the same name and it
will override the weak one. I also added CHIP_CSRCS += avrdx_delay.c to
arch/avr/src/avrdx/Make.defs . Tried to build everything, build
succeeded but - looking at the disassembly - the original implementation
was used.

So then I started experimenting:

1. I tried if the source file avrdx_delay.c is actually being compiled
by adding #error test . The compiler issued an error, as expected.

2. I tried to remove weak attribute from up_udelay in clock_delay.c to
force "multiple definition" error in linking step to verify that my code
is getting to the linker. No error though, build completed.

3. I also tried to force the same error with different function,
randomly picked nxtask_start and added a dummy implementation of it to
avrdx_delay.c. Still no error.

4. Still thinking there may be something wrong with the new file, I
moved my implementation of nxtask_start to already existing and
relatively well-tested arch/avr/src/avrdx/avrdx_serial.c . The build
failed, multiple definition of `nxtask_init' (finally)

5. I then put my implementation of up_udelay to avrdx_serial.c (and
removed nxtask_init from there.) The build succeeded and up_udelay used
my implementation.

6. Now the really strange part (for me at least) - I added
somerandomfunc() to avrdx_delay.c and called it from my application.
Attempted to build and it failed because multiple definition of
nxtask_init which was left there from previous experiments. To verify, I kept somerandomfunc in avrdx_delay.c but removed the call to it from my
application. The build succeeded. I added the call to somerandomfunc
back to the application, got build error again.

So now I am at loss. From what I see, the linker is ignoring duplicate
functions in an source code/object file unless the file also contains a
function that is not a duplicate and that is actually called from
somewhere.

Could anyone shed some light on this? I am out of my league here
unfortunately. Did some web search, found --whole-archive flag for the
linker but experimenting with it led to nowhere (couldn't even make it
to work, makes the build fail because linker then finds duplicates
between libgcc and NuttX code and even within libgcc itself.)

Tested with avr-gcc 14.2 and 5.4

Reply via email to