Hi,
I have a "linker" problem in a project that use the LPCOpen board configuration (board.c and board.h) on a LPC11U6X.
The physical setup:
IDE/firmware setup:
The problem:
Everything works fine until I start working with extern variables defined for the board or chip (e.g. IRQ handler). For no apparent reason, the linker raise two errors:
liblpc_chip_11u6x.a(clock_11u6x.o): In function `Chip_Clock_GetMainOscRate':
clock_11u6x.h:518: undefined reference to `OscRateIn'
liblpc_chip_11u6x.a(clock_11u6x.o): In function `Chip_Clock_GetRTCOscRate':
clock_11u6x.h:536: undefined reference to `RTCOscRateIn'
The two variables "OscRateIn" and "RTCOscRateIn" are extern in "chip.h" , and defined in "board.c":
const uint32_t OscRateIn = 12000000;
const uint32_t RTCOscRateIn = 32768;
Since I include "board.h", I see no reason that these variables are considered as not defined. For the moment (as a quick fix) I added the definition of the two variables in my main file, but I am afraid that there is a larger problem, and I am not sure if the board configuration is really taken into account or if the default chip configuration is used instead.
Thanks for your help,
Best
David
Solved! Go to Solution.
@jeremyzhou Thanks for the response.
I found the reason of the behavior I described. In fact, since I am not calling “Board_Init” or another function in “board.c” (I don’t need the debug and LED initialization and call directly “Chip_GPIO_Init(LPC_GPIO);”), the file “board.c” is not considered as a required unit in the compilation procedure. Therefore, “board.c” is not compiled and definitions of “OscRateIn” and “RTCOscRateIn” in “board.c” are not considered.
In fact, as I am only interested in clock and pin configuration from the board, I can simply:
+
David
I think know this kind of error. Have you tried to disable the usage of the board lib in the project settings?
In MCU XPresso (or older) go to
"Edit project settings" / "C/C++ Build" / "Settings" / "Tool Settings" Tab / "MCU C Compiler" / "Preprocessor"
Add Symbol "NO_BOARD_LIB" in Debug AND/OR Release mode, whatever you need.
Now the whole board.h branch should be disabled and the chip library is doing the rest.
If you look into the code of the libs then you'll see that "OscRateIn” and “RTCOscRateIn” will be excluded if
NO_BOARD_LIB is defined.
Jack
Indeed a better solution to set "NO_BOARD_LIB" or switch to Release mode.
Thanks for the comment.
David
Hi David Meignan ,
According to your statement, I got that the original project would change after copy/paste operation, whether my consideration is right.
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hello Jeremy,
jeremyzhou wrote:
According to your statement, I got that the original project would change after copy/paste operation, whether my consideration is right.
Yes you're right. I reproduce this with a very simple example code.
/** Simple template with 1ms timer */
// For reusing clock configuration and pin-muxing
#include "board.h"
// Timer
#define TIMER_PRESCALE_2KHZ (0x5DC0)
// Function declarations
void setup_1ms_timer();
void start_1ms_timer();
void stop_1ms_timer();
/** Handle interrupt from 16-bit timer 0 */
void TIMER16_0_IRQHandler(void)
{
static uint16_t counter_500ms = 0;
if (Chip_TIMER_MatchPending(LPC_TIMER16_0, 1)) {
// 1ms tick
Chip_TIMER_ClearMatch(LPC_TIMER16_0, 1);
// Process 1ms
//...
// Pseudo-timer
if (counter_500ms >= 500) {
// 500ms tick
counter_500ms = 0;
// Process 500ms
// ...
} else {
counter_500ms++;
}
}
}
/** Setup 1ms timer */
void setup_1ms_timer() {
/* Initialize 16-bit timer 0 clock */
Chip_TIMER_Init(LPC_TIMER16_0);
/* Timer setup for match and interrupt at TICKRATE_HZ */
Chip_TIMER_Reset(LPC_TIMER16_0);
/* Enable timer to generate interrupts when time matches */
Chip_TIMER_MatchEnableInt(LPC_TIMER16_0, 1);
/* Setup prescale value on 16-bit timer to extend range */
Chip_TIMER_PrescaleSet(LPC_TIMER16_0, TIMER_PRESCALE_2KHZ);
/* Setup 16-bit timer's duration (16-bit match time) */
Chip_TIMER_SetMatch(LPC_TIMER16_0, 1, 0x0001);
/* Setup timer to restart when match occurs */
Chip_TIMER_ResetOnMatchEnable(LPC_TIMER16_0, 1);
/* Clear both timers of any pending interrupts */
NVIC_ClearPendingIRQ(TIMER_16_0_IRQn);
/* Enable timer interrupts */
NVIC_EnableIRQ(TIMER_16_0_IRQn);
}
/** Starts the 1ms timer */
void start_1ms_timer() {
/* Reset timer counts */
Chip_TIMER_Reset(LPC_TIMER16_0);
/* Clear match interrupt */
Chip_TIMER_ClearMatch(LPC_TIMER16_0, 1);
/* Start timer */
Chip_TIMER_Enable(LPC_TIMER16_0);
}
/**
* Stops 1ms timer */
void stop_1ms_timer() {
/* Stop timer */
Chip_TIMER_Disable(LPC_TIMER16_0);
}
/** Main routine */
int main(void)
{
SystemCoreClockUpdate();
// Initialize GPIO (and set system clock)
Chip_GPIO_Init(LPC_GPIO);
while (1) {
__WFI();
// Process after interrupt routine
// ...
}
return 0;
}
I expect that the "sysinit.c" procedure do the board config with no problem but I have the following error:
13:07:04 **** Incremental Build of configuration Debug for project copy_demos_switch_blinky ****
make -r -j4 all
Building file: ../src/switch_blinky.c
Invoking: MCU C Compiler
arm-none-eabi-gcc -D__REDLIB__ -DDEBUG -D__CODE_RED -D__USE_LPCOPEN -DCORE_M0PLUS -D__USE_ROMDIVIDE -I"D:\MCUXpresso_LPCOpen_workspace\lpc_chip_11u6x\inc" -I"D:\MCUXpresso_LPCOpen_workspace\lpc_board_nxp_lpcxpresso_11u68\inc" -O0 -g3 -Wall -c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -mcpu=cortex-m0 -mthumb -D__REDLIB__ -specs=redlib.specs -MMD -MP -MF"src/switch_blinky.d" -MT"src/switch_blinky.o" -MT"src/switch_blinky.d" -o "src/switch_blinky.o" "../src/switch_blinky.c"
Finished building: ../src/switch_blinky.c
Building target: copy_demos_switch_blinky.axf
Invoking: MCU Linker
arm-none-eabi-gcc -nostdlib -L"D:\MCUXpresso_LPCOpen_workspace\lpc_chip_11u6x\Debug" -L"D:\MCUXpresso_LPCOpen_workspace\lpc_board_nxp_lpcxpresso_11u68\Debug" -Xlinker -Map="copy_demos_switch_blinky.map" -Xlinker --gc-sections -Xlinker --allow-multiple-definition -mcpu=cortex-m0 -mthumb -T "demos_switch_blinky_Debug.ld" -o "copy_demos_switch_blinky.axf" ./src/cr_startup_lpc11u6x.o ./src/crp.o ./src/switch_blinky.o ./src/sysinit.o -llpc_board_nxp_lpcxpresso_11u68 -llpc_chip_11u6x
D:\MCUXpresso_LPCOpen_workspace\lpc_chip_11u6x\Debug\liblpc_chip_11u6x.a(clock_11u6x.o): In function `Chip_Clock_GetMainOscRate':
D:\MCUXpresso_workspace\lpc_chip_11u6x\inc/clock_11u6x.h:518: undefined reference to `OscRateIn'
D:\MCUXpresso_LPCOpen_workspace\lpc_chip_11u6x\Debug\liblpc_chip_11u6x.a(clock_11u6x.o): In function `Chip_Clock_GetRTCOscRate':
D:\MCUXpresso_workspace\lpc_chip_11u6x\inc/clock_11u6x.h:536: undefined reference to `RTCOscRateIn'
collect2.exe: error: ld returned 1 exit status
make: *** [copy_demos_switch_blinky.axf] Error 1
Hi David M.,
Thanks for your reply.
I'd like to exemplify the steps of fix the error message.
1. First, I just use your code to replace the original code directly, the error happened as you mentioned before.
2. I think it must be something wrong, even I didn't figure it out, so I used another way to replace the code: insert the new codes bit by bit, the error doesn't happen again. It's a little weird.
Please have try.
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
@jeremyzhou Thanks for the response.
I found the reason of the behavior I described. In fact, since I am not calling “Board_Init” or another function in “board.c” (I don’t need the debug and LED initialization and call directly “Chip_GPIO_Init(LPC_GPIO);”), the file “board.c” is not considered as a required unit in the compilation procedure. Therefore, “board.c” is not compiled and definitions of “OscRateIn” and “RTCOscRateIn” in “board.c” are not considered.
In fact, as I am only interested in clock and pin configuration from the board, I can simply:
+
David