Extern variables (OscRateIn and RTCOscRateIn) not set in board.h

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Extern variables (OscRateIn and RTCOscRateIn) not set in board.h

Jump to solution
2,638 Views
d_m_
Contributor II

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:

  • Custom PCB with a LPC11U6X chip, and a design very close to the OM13058 LPC Xpresso v2 (Rev C) board (based on LPC11U68).

IDE/firmware setup:

  • I am using MCUXpresso IDE v10.0.0 [Build 344] [2017-03-21],
  • I already tested with success different project examples from LPCOpen (v3.01), and different custom tests, (all using the "LPC board library" included with #include "board.h")
  • I started the development of a firmware with a copy/paste from the blinky example:
    • As for LPCOpen projects, the "custom_firmware" project includes and is linked to "lpc_board_nxp_lpcxpresso_11u68" and "lpc_chip_11u6x" projects (in the same workspace),
    • I included "board.h" in my main file to use the base configuration (pin muxing, clock, IO) of the LPCXpresso11U68,

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

Labels (2)
0 Kudos
Reply
1 Solution
2,033 Views
d_m_
Contributor II

@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:

  • (Don’t include of “board.h” in my main file),
  • Define “OscRateIn” and “RTCOscRateIn” in my main file,
  • Use the “sysinit.c” that calls “Board_SystemInit();”,
  • Call “SystemCoreClockUpdate(); Chip_GPIO_Init(LPC_GPIO);” at the beginning of the main procedure.

+
David

View solution in original post

0 Kudos
Reply
6 Replies
2,033 Views
baltobor
Contributor I

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

2,033 Views
d_m_
Contributor II

Indeed a better solution to set "NO_BOARD_LIB" or switch to Release mode.

Thanks for the comment.

David

0 Kudos
Reply
2,033 Views
jeremyzhou
NXP Employee
NXP Employee

Hi David Meignan ,

Thank you for your interest in NXP Semiconductor products and 
the opportunity to serve you.

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!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply
2,033 Views
d_m_
Contributor II

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.

  1. Copy/paste the blinky example project "demos_switch_blinky",
  2. Modification of the main file "switch_blinky.c" with the following code (BTW, any option for formatted code in the post editor?):

/** 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

0 Kudos
Reply
2,033 Views
jeremyzhou
NXP Employee
NXP Employee

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

2017-06-16_10-46-24.jpg

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply
2,034 Views
d_m_
Contributor II

@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:

  • (Don’t include of “board.h” in my main file),
  • Define “OscRateIn” and “RTCOscRateIn” in my main file,
  • Use the “sysinit.c” that calls “Board_SystemInit();”,
  • Call “SystemCoreClockUpdate(); Chip_GPIO_Init(LPC_GPIO);” at the beginning of the main procedure.

+
David

0 Kudos
Reply