Transitioning to C++ with KDS, KSDK, and Processor Expert

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

Transitioning to C++ with KDS, KSDK, and Processor Expert

Transitioning to C++ with KDS, KSDK, and Processor Expert

I have definitely experienced some of the growing pains of using the Kinetis tools as they have underdone some changes.  I started tinkering with KDS last year when KSDK and MQX were separate packages.  I didn't mess around with it much, other than to prove that I could toggle some GPIO.  I then got more serious with KDS 2.0 and KSDK 1.1 when MQX was integrated into the installer.  I started with simple projects, and eventually got a pretty good demo put together that incorporated ethernet (using lwIP), RS485, Modbus TCP/RTU, motion control, and barcode reading.  Unfortunately, at that time there were some small issues with the KSDK 1.1 which prevented us from being able to easily write applications in C++.  I definitely think better in C++ than in C, so this was a bummer.

I was quite excited when the C++ issues were fixed in KSDK 1.2.  So now I need to port my application from C to C++.  At this point, I am faced with two hurdles:

  1. Directly porting my currently-working application (written for KDS 2 / KSDK 1.1) doesn't work.  I have written some posts here about it and could use some help solving those problems.
    1. lwIP project that was working in KDS 2.0 with MQX and PEx no longer works in KDS 3.0
    2. How do you force PEx to be totally C++ compatible?
    3. Adding HardFault handlers in KDS3/KSDK1.2?
  2. Figuring out how to call into C++ wrappers

This post is about #2, where I believe I have a usable solution.  It's basically covered in Re: How to call C functions that use "restrict" keyword from C ?  but with a small twist or two.  I am currently using KDS 3, KSDK 1.2, and my project requires MQX Standard as well as Processor Expert.When you create a project like mine, you will likely go through the following basic steps:

  1. Create new project
  2. Enable KSDK and Processor Expert
  3. Change osa from BareMetal to MQX
  4. Change MQX from Lite to Standard
  5. Disable DbgCs1
  6. Enable new fsl_uart in MQX settings and disable its pins
  7. Add OS_Task components and other PEx components
  8. Specify your CPU type in the C++ compiler settings, as shown below
    pastedImage_0.png
  9. Generate code

In addition to main.c, after you generate code, you'll also end up with os_tasks.c.  Your PEx components will have C code added to the Generated Code folder.  At this point, it should be possible to wrap components in C++ classes.  Tonight, I ran a simple test where I wanted one of my MQX tasks to blink an LED.  The LED blink code was wrapped in a simple C++ class, and in order to be able to create the C++ object to call into, you have to call it from C++ code!

The solution ends up being pretty simple.  Rename main.c to main.cpp, and rename os_tasks.c to os_tasks.cpp.  Then generate code again.  Click on your Sources folder and hit F5.  You will see that main.c and os_tasks.cpp reappear, because they get re-created.  Right click on each of them and click Resource Configuration -> Exclude from Build.

pastedImage_12.png

Click Select All, then Close.  This will prevent those files from being compiled.  Note that if you add more OS_Task components, you will need to manually update os_tasks.cpp accordingly.

At this point, it's very simple to create a wrapper class and call it.  I wrote one called DebugLed.cpp:

#include <DebugLed.h>

#include "Cpu.h"

#include "gpio_comp.h"

namespace Peripherals {

DebugLed::DebugLed() {

  // TODO Auto-generated constructor stub

}

DebugLed::~DebugLed() {

  // TODO Auto-generated destructor stub

}

void DebugLed::BlinkGreen()

{

  GPIO_DRV_SetPinOutput( LEDRGB_GREEN);

  OSA_TimeDelay(150);                 /* Example code (for task release) */

  GPIO_DRV_ClearPinOutput( LEDRGB_GREEN);

  OSA_TimeDelay(150);                 /* Example code (for task release) */

}

} /* namespace Peripherals */

(hopefully all of the code shows up when I post this!  I don't see all of it in the preview)

Then you can instantiate the DebugLed object before the while(1) in your OS_Task:

void Blink_task(os_task_param_t task_init_data)

{

  /* Write your local variable definition here */

  Peripherals::DebugLed led;

#ifdef PEX_USE_RTOS

  while (1) {

#endif

    /* Write your code here ... */

   led.BlinkGreen();

#ifdef PEX_USE_RTOS  

  }

#endif   

}

/* END os_tasks */

#ifdef __cplusplus

}  /* extern "C" */

#endif

Build, debug, and set a breakpoint on your call into your C++ object, and it should hit it!

It's a lot easier than I thought it would be.  I figured there would be more manual labor involved with the code generation aspect of it, but it seems to basically boil down to two files, and you don't even need to disable code generation for any of the PEx components, which means you can still use the GUI to change settings if necessary (even though manually changing the header is just as simple).

When I get to the office tomorrow, I'll probably start wrapping more complex peripherals, but I really need to figure out the HardFault problem with my lwIP project.  If you have any suggestions, please visit my post: Adding HardFault handlers in KDS3/KSDK1.2? and comment if you can.  Smiley Happy

I hope my first document here on the Freescale Community was helpful to someone here!

Comments

Thank you Dave!!! This is a great document :smileyhappy:.

You bet!  :smileyhappy:  I'm glad it was helpful to you.

I tried to make a new Kinetis Project using the TWR-K6F180M evaluation board using the default settings. The project compiled okay.

The Events.c and main.c files were created and I renamed them to cpp files. I regenerated the code and they were re-created and I excluded from build.

I received numerous errors in files such as fsl_port_hal.h, fsl.clock_manager.h and fsl_interrupt_manager.h.

Is there something I sould do to fix those?

Calvin

Hi Calvin, sorry for the late reply -- can you post more information about the errors that you have seen?  Don't forget to delete the unused .c files, because in my experience, main.c and os_tasks.c still either get compiled or linked, because when you run the debugger, the starting breakpoint will be in the .c file, which you obviously don't want.  I don't know if this is a KDS / Eclipse bug or not.

No ratings
Version history
Last update:
‎09-10-2020 03:00 AM
Updated by: