Interrupt working under C but not C++

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

Interrupt working under C but not C++

Jump to solution
1,583 Views
eriklea
Contributor I

I've got code extracted and modified from an LPCOpen example code for the LPC4088 evaluation board, and the interrupt in it works as C code, but not as C++, although both build and start running happily on the LPC4088. When running as C++ it ends up at the place with this code:

void IntDefaultHandler(void)
{ while(1) {}
}

in cr_startup_lpc407x_8x.cpp. (The C project has the same file called cr_startup_lpc407x_8x.c)

The two projects were both set up with default settings with the "New C/C++ Wizard" in MCUXpresso 10.3.1_2233, and I changed the preprocessor settings to

DEBUG
__CODE_RED
__NEWLIB__
CORE_M4
__USE_LPCOPEN
NO_BOARD_LIB
CPP_USE_HEAP
__LPC407X_8X__

so that it should be identical for both projects. Then I put the exact same code, which is found further down in this message, into the main files, and left everything else as default settings. Why does the C project work with the interrupt, while the C++ doesn't? Do I need to set up a link to "CAN_IRQHandler" somewhere?

Here is the code, which is mostly taken from the "periph_can" example:

#include "chip.h"

#define CAN_TX_MSG_STD_ID (0x200)
#define CAN_TX_MSG_EXT_ID (0x10000200)
#define CAN_RX_MSG_ID (0x100)

/* Reply message received */
static void ReplyNormalMessage(CAN_MSG_T *pRcvMsg)
{
CAN_MSG_T SendMsgBuf = *pRcvMsg;
CAN_BUFFER_ID_T TxBuf;
SendMsgBuf.ID = CAN_TX_MSG_STD_ID;
TxBuf = Chip_CAN_GetFreeTxBuf(LPC_CAN1);
Chip_CAN_Send(LPC_CAN1, TxBuf, &SendMsgBuf);
}


/*****************************************************************************
* Public functions
****************************************************************************/
void CAN_IRQHandler(void)
{

uint32_t IntStatus;
CAN_MSG_T RcvMsgBuf;
IntStatus = Chip_CAN_GetIntStatus(LPC_CAN1);

/* New Message came */
if (IntStatus & CAN_ICR_RI) {
Chip_CAN_Receive(LPC_CAN1, &RcvMsgBuf);

ReplyNormalMessage(&RcvMsgBuf);

}

}

int main(void)
{
CAN_BUFFER_ID_T TxBuf;
CAN_MSG_T SendMsgBuf;

SystemCoreClockUpdate();
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 0, (IOCON_FUNC1 | 0));
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 1, (IOCON_FUNC1 | 0));
Chip_GPIO_Init(LPC_GPIO);
Chip_IOCON_Init(LPC_IOCON);
Chip_CAN_Init(LPC_CAN1, LPC_CANAF, LPC_CANAF_RAM);
Chip_CAN_SetBitRate(LPC_CAN1, 500000);
Chip_CAN_EnableInt(LPC_CAN1, CAN_IER_BITMASK);
Chip_CAN_SetAFMode(LPC_CANAF, CAN_AF_BYBASS_MODE);
NVIC_EnableIRQ(CAN_IRQn);

SendMsgBuf.ID = CAN_EXTEND_ID_USAGE | CAN_TX_MSG_EXT_ID;
SendMsgBuf.Type = 0;
SendMsgBuf.Data[0] = 'E';
SendMsgBuf.Data[1] = 'F';
SendMsgBuf.Data[2] = 'G';
SendMsgBuf.Data[3] = 'H';
SendMsgBuf.Data[4] = 'I';
SendMsgBuf.Data[5] = 'J';
SendMsgBuf.Data[6] = 'K';
SendMsgBuf.Data[7] = 'L';
TxBuf = Chip_CAN_GetFreeTxBuf(LPC_CAN1);

Chip_CAN_Send(LPC_CAN1, TxBuf, &SendMsgBuf);
while ((Chip_CAN_GetStatus(LPC_CAN1) & CAN_SR_TCS(TxBuf)) == 0) {}

}

Labels (1)
1 Solution
1,388 Views
converse
Senior Contributor V

Use

extern “C”

to declare your interrupt handler. This is a common FAQ. Look it up if you don’t understand why.

View solution in original post

2 Replies
1,389 Views
converse
Senior Contributor V

Use

extern “C”

to declare your interrupt handler. This is a common FAQ. Look it up if you don’t understand why.

1,388 Views
eriklea
Contributor I

Oh, it was that simple. Worked straight away. Thank you.

0 Kudos
Reply