Using C++ with Kinetis Design Studio 3.2.0 and MKW41Z_ConnSw_1.0.2

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

Using C++ with Kinetis Design Studio 3.2.0 and MKW41Z_ConnSw_1.0.2

Jump to solution
1,517 Views
maxv
Contributor I

Hi,

There's a problem with using C++ and KDS 3.2.0 and the provided device drivers on an FRDM-KW41Z kit.

If I create a new project using the Kinetis SDK 2.x Project wizard:

 

172207_172207.PNGkds-2.PNG

172259_172259.PNGkds-3.PNG

 

Now, if I replace the contents of main.c with those from the gpio_input_interrupt_frdmkw41z example:

/*
 * Copyright (c) 2015, Freescale Semiconductor, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 * of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 * list of conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.
 *
 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "fsl_debug_console.h"
#include "fsl_port.h"
#include "fsl_gpio.h"
#include "fsl_common.h"
#include "board.h"
#include "pin_mux.h"
#include "clock_config.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define BOARD_LED_GPIO BOARD_LED_RED_GPIO
#define BOARD_LED_GPIO_PIN BOARD_LED_RED_GPIO_PIN

#define BOARD_SW_GPIO BOARD_SW3_GPIO
#define BOARD_SW_PORT BOARD_SW3_PORT
#define BOARD_SW_GPIO_PIN BOARD_SW3_GPIO_PIN
#define BOARD_SW_IRQ BOARD_SW3_IRQ
#define BOARD_SW_IRQ_HANDLER BOARD_SW3_IRQ_HANDLER
#define BOARD_SW_NAME BOARD_SW3_NAME

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Variables
 ******************************************************************************/
/* Whether the SW button is pressed */
volatile bool g_ButtonPress = false;

/*******************************************************************************
 * Code
 ******************************************************************************/
/*!
 * @brief Interrupt service fuction of switch.
 *
 * This function toggles the LED
 */
void BOARD_SW_IRQ_HANDLER(void)
{
 /* Clear external interrupt flag. */
 GPIO_ClearPinsInterruptFlags(BOARD_SW_GPIO, 1U << BOARD_SW_GPIO_PIN);
 /* Change state of button. */
 g_ButtonPress = true;
 /* Toggle LED. */
 GPIO_TogglePinsOutput(BOARD_LED_GPIO, 1U << BOARD_LED_GPIO_PIN);
}

/*!
 * @brief Main function
 */
int main(void)
{
 /* Define the init structure for the input switch pin */
 gpio_pin_config_t sw_config = {
 kGPIO_DigitalInput, 0,
 };

 /* Define the init structure for the output LED pin */
 gpio_pin_config_t led_config = {
 kGPIO_DigitalOutput, 0,
 };

 BOARD_InitPins();
 BOARD_BootClockRUN();
 BOARD_InitDebugConsole();

 /* Print a note to terminal. */
 PRINTF("\r\n GPIO Driver example\r\n");
 PRINTF("\r\n Press %s to turn on/off a LED \r\n", BOARD_SW_NAME);

 /* Init input switch GPIO. */
 PORT_SetPinInterruptConfig(BOARD_SW_PORT, BOARD_SW_GPIO_PIN, kPORT_InterruptFallingEdge);
 EnableIRQ(BOARD_SW_IRQ);
 GPIO_PinInit(BOARD_SW_GPIO, BOARD_SW_GPIO_PIN, &sw_config);

 /* Init output LED GPIO. */
 GPIO_PinInit(BOARD_LED_GPIO, BOARD_LED_GPIO_PIN, &led_config);

 while (1)
 {
 if (g_ButtonPress)
 {
 PRINTF(" %s is pressed \r\n", BOARD_SW_NAME);
 /* Reset state of button. */
 g_ButtonPress = false;
 }
 }
}

 

And set the pinmux.c settings to those of the gpio_input_interrupt_frdmkw41z example:

void BOARD_InitPins(void)
{
 /* Initialize LPUART0 pins below */
 /* Ungate the port clock */
 CLOCK_EnableClock(kCLOCK_PortC);
 /* Affects PORTC_PCR6 register */
 PORT_SetPinMux(PORTC, 6U, kPORT_MuxAlt4);
 /* Affects PORTC_PCR7 register */
 PORT_SetPinMux(PORTC, 7U, kPORT_MuxAlt4);

 /* Affects PORTC_PCR4 register */
 port_pin_config_t config;
 config.pullSelect = kPORT_PullUp;
 config.mux = kPORT_MuxAsGpio;
 PORT_SetPinConfig(PORTC, 4U, &config);

 /* LED PIN_MUX Configuration */
 PORT_SetPinMux(PORTC, 1U, kPORT_MuxAsGpio);
}

If I then rename main.c to main.cpp and recompile, everything builds fine.

 

However, when I then debug the program and press SW3 on the FRDM-KW41Z board, it always jumps to the wrong interrupt handler (which is by default an endless loop):

 

172260_172260.PNGkds-4.PNG

I'm not sure why this is the case, but this isn't something I would have expected.

 

If I build and run the program as main.c, everything works correctly.

 

I've attached a ZIP file with the example project. Basically it's gpio_input_interrupt_frdmkw41z but using C++ to build it instead of C.

 

This problem makes it effectively impossible to use C++ instead of C, since the only difference in builds is the compiler involved!

 

Thanks,

Max

Original Attachment has been moved to: Test.zip

Labels (1)
0 Kudos
Reply
1 Solution
923 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Max,

Sorry for i haven't this board , so i can not test your project.

I test a simple project include interrupt on other kenitis chip, only change the name main.c to main.cpp,

 it can work well.

Could you please test a bare board project , without RTOS .

if still can not work, please add the below code  in the interrupt function :

#ifdef __cplusplus
extern "C" {
#endif               
                     
    " interrupt function " 
       


#ifdef __cplusplus
} /* extern "C" */
#endif‍‍‍‍‍‍

 or

extern "C" {

             "interrupt function"

}  /* extern "C" */

BR

Alice

View solution in original post

0 Kudos
Reply
2 Replies
923 Views
maxv
Contributor I

Hi Alice,

Thanks for the suggestion, it worked.

I guess it would be good for future versions of the Kinetis SDK to make sure that all interrupt handlers are wrapped to use C linkage.

Cheers,

Max

0 Kudos
Reply
924 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Max,

Sorry for i haven't this board , so i can not test your project.

I test a simple project include interrupt on other kenitis chip, only change the name main.c to main.cpp,

 it can work well.

Could you please test a bare board project , without RTOS .

if still can not work, please add the below code  in the interrupt function :

#ifdef __cplusplus
extern "C" {
#endif               
                     
    " interrupt function " 
       


#ifdef __cplusplus
} /* extern "C" */
#endif‍‍‍‍‍‍

 or

extern "C" {

             "interrupt function"

}  /* extern "C" */

BR

Alice

0 Kudos
Reply