us_ticker_api.c implicit declaration of __disable_irq

15 Mar 2013

Hi Emilio et al, I'm having issues compiling the Mbed SDK using Code Red Suite. Although I can compile and download some test programs (e.g., Hello World), anything with a ticker does not compile.

I've pasted below the output on my machine, showing warnings in us_ticker_api.c:

Compile: us_ticker_api.c
/usr/local/redsuite_5.1.2_2065/redsuite//tools/bin/arm-none-eabi-gcc -std=gnu99 -c -O2 -Wall -fmessage-length=0 -fno-exceptions -fno-builtin -ffunction-sections -fdata-sections -MMD -save-temps -mcpu=cortex-m3 -mthumb -D__NEWLIB__ -D__CODE_RED -D__USE_CMSIS -DCPP_USE_HEAP -DTARGET_LPC1768 -DTOOLCHAIN_GCC_CR -D__CORTEX_M3 -DARM_MATH_CM3 -I/home/hazard/workspace/mbed_pure/mbed/libraries/mbed/capi -I/home/hazard/workspace/mbed_pure/build/mbed -I/home/hazard/workspace/mbed_pure/build/mbed/LPC1768 -I/home/hazard/workspace/mbed_pure/build/mbed/LPC1768/GCC_CR -o /home/hazard/workspace/mbed_pure/build/mbed/.temp/LPC1768/GCC_CR/us_ticker_api.o /home/hazard/workspace/mbed_pure/mbed/libraries/mbed/capi/us_ticker_api.c
[Warning] us_ticker_api.c@58: In function 'us_ticker_insert_event': implicit declaration of function '__disable_irq' [-Wimplicit-function-declaration]
[Warning] us_ticker_api.c@87: In function 'us_ticker_insert_event': implicit declaration of function '__enable_irq' [-Wimplicit-function-declaration]

When test applications (e.g., 'Ticker' (#29) and 'Ticker2' (#40)) are compiled, GCC throws undefined reference errors to the same functions:

>>> BUILD PROJECT: TICKER (LPC1768, GCC_CR)
Compile: main.cpp
/usr/local/redsuite_5.1.2_2065/redsuite//tools/bin/arm-none-eabi-g++ -std=gnu++98 -c -O2 -Wall -fmessage-length=0 -fno-exceptions -fno-builtin -ffunction-sections -fdata-sections -MMD -save-temps -mcpu=cortex-m3 -mthumb -D__NEWLIB__ -D__CODE_RED -D__USE_CMSIS -DCPP_USE_HEAP -DTARGET_LPC1768 -DTOOLCHAIN_GCC_CR -D__CORTEX_M3 -DARM_MATH_CM3 -I/home/hazard/workspace/mbed_pure/mbed/libraries/tests/mbed/ticker -I/home/hazard/workspace/mbed_pure/build/mbed -I/home/hazard/workspace/mbed_pure/build/mbed/LPC1768 -I/home/hazard/workspace/mbed_pure/build/mbed/LPC1768/GCC_CR -o /home/hazard/workspace/mbed_pure/build/test/LPC1768/GCC_CR/MBED_11/main.o /home/hazard/workspace/mbed_pure/mbed/libraries/tests/mbed/ticker/main.cpp
Link: ticker
/usr/local/redsuite_5.1.2_2065/redsuite//tools/bin/arm-none-eabi-gcc -Wl,--gc-sections -mcpu=cortex-m3 -mthumb -nostdlib -T/home/hazard/workspace/mbed_pure/build/mbed/LPC1768/GCC_CR/LPC1768.ld -o /home/hazard/workspace/mbed_pure/build/test/LPC1768/GCC_CR/MBED_11/ticker.elf /home/hazard/workspace/mbed_pure/build/test/LPC1768/GCC_CR/MBED_11/main.o /home/hazard/workspace/mbed_pure/build/mbed/LPC1768/GCC_CR/cmsis_nvic.o /home/hazard/workspace/mbed_pure/build/mbed/LPC1768/GCC_CR/startup_LPC17xx.o /home/hazard/workspace/mbed_pure/build/mbed/LPC1768/GCC_CR/core_cm3.o /home/hazard/workspace/mbed_pure/build/mbed/LPC1768/GCC_CR/system_LPC17xx.o -L/home/hazard/workspace/mbed_pure/build/mbed/LPC1768/GCC_CR -lmbed -lstdc++ -lsupc++ -lm -lc -lgcc -lmbed -lstdc++ -lsupc++ -lm -lc -lgcc

[ERROR] /home/hazard/workspace/mbed_pure/build/mbed/LPC1768/GCC_CR/libmbed.a(us_ticker_api.o): In function `us_ticker_insert_event':
us_ticker_api.c:(.text.us_ticker_insert_event+0x8): undefined reference to `__disable_irq'
us_ticker_api.c:(.text.us_ticker_insert_event+0x38): undefined reference to `__enable_irq'
/home/hazard/workspace/mbed_pure/build/mbed/LPC1768/GCC_CR/libmbed.a(us_ticker_api.o): In function `us_ticker_remove_event':
us_ticker_api.c:(.text.us_ticker_remove_event+0x4): undefined reference to `__disable_irq'
us_ticker_api.c:(.text.us_ticker_remove_event+0x2a): undefined reference to `__enable_irq'
collect2: ld returned 1 exit status

I'd be happy to test any fixes.

Cheers,

Matt

15 Mar 2013

Adding #include "LPC17XX.h" to the top of us_ticker_api.c at least eliminates the undefined reference warning and lets me compile the test programs without error. Of course, this breaks the portability of the API, but I hope it's a helpful clue to where the real problem lies :)

Matt

18 Mar 2013

Hi Matt, thank you for reporting this issue with the GCC toolchains.

We did not spot this problem immediately, because in ARMCC "__disable_irq" and "__enable_irq" are two intrinsic functions.

We have now fixed this problem without "breaking the portability of the API": Revision 6

The CMSIS layer handles much of the source compatibility among the different toolchains, defining many of the useful ARMCC intrinsics.

Cheers, Emilio

18 Mar 2013

Great!

Thanks to the mbed team for opening the library source! First on my to-do list is to add CTI interrupt handling to the Serial backend so the internal FIFO will actually be usable...

Thanks again, Matt

18 Mar 2013

Hi Matt,

Matt Hazard wrote:

First on my to-do list is to add CTI interrupt handling to the Serial backend so the internal FIFO will actually be usable...

That sounds interesting.

To allow us to pull your code in the mbed official library, it would be great if you could also add a small test program showing what your code is fixing/improving.

Cheers, Emilio

22 Aug 2013

Sorry I never followed up on this post. I haven't kept my source updated with the mbed SDK and I don't have time to get synced up right now, so here's the text version.

The FIFO is critical because at high baud rates (e.g., 460800) firing one interrupt per received character causes too many context switches, especially when multiple serial streams are being received.

However, in the current implementation, interrupt driven serial communications (e.g., with MODSERIAL library) hangs whenever UART FIFO depth is greater than 1, because the CTI (character timeout indication) interrupt is unhandled in serial_api.c . The CTI interrupt should be fired whenever the FIFO is partially filled for longer than a few 'character times'. From the datasheet, exactly [(word length) × 7 - 2] × 8 + [(trigger level - number of characters) × 8 + 1] RCLKs. Because there is valid data in the buffer this interrupt should be handled as if it was a normal read.

So, adding support for the CTI interrupt (for 1768 at least) is a one line fix

serial_api.c snippet

switch (iir) {
        case 1: irq_type = TxIrq; break;
        case 2: irq_type = RxIrq; break;
+      case 6: irq_type = RxIrq; break;
        default: return;
    }

Because the exact number of bytes read into the FIFO is unknown, interrupt based serial drivers (e.g., MODSERIAL) must also ensure they loop on .readable() to ensure all bytes are read out to empty the buffer.

An associated feature request would be to add FIFO depth control to the API and document the default initialization to 1 byte length.

Thanks, Matt