AnsweredAssumed Answered

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

Question asked by Max Vilimpoc on Dec 10, 2016
Latest reply on Dec 13, 2016 by Max Vilimpoc

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:

 

 

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

 

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

Outcomes