element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Embedded and Microcontrollers
  • Technologies
  • More
Embedded and Microcontrollers
Blog Port an MBED design to non-MBED - Phase 1: compile without errors
  • Blog
  • Forum
  • Documents
  • Quiz
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Embedded and Microcontrollers to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 9 Nov 2019 7:25 PM Date Created
  • Views 1802 views
  • Likes 8 likes
  • Comments 7 comments
  • mbed
Related
Recommended

Port an MBED design to non-MBED - Phase 1: compile without errors

Jan Cumps
Jan Cumps
9 Nov 2019

There are many good MBED examples. It's a popular platform, supported by many manufacturers.

Here's my story on how to port one of those excellent MBED example program to another platform.

 

The program I want to port is the SemTech LoRa Ping-Pong example.

The goal is to get a reusable C++ library that can be used on micro controllers, Raspberry Pi, BeagleBone etc...

I need to find what part of the code is dependent on MBED and factor that out.

The factored-out part is the one that will have to be implemented for the target non-MBED platform.

If I get this working, in the end I have to provide an abstract C++ library that only depends on standard libraries, and a document that specs, for the missing parts, what extra functionality is needed.

I expect that the missing  (to be ported) parts are GIO, SPI and UART (optional image).

 

As test bed, I'm using a Texas Instruments Hercules micro controller. It could be any platform that supports SPI and GPIO.

I selected this one because I have two identical boards and my example is a radio Send + Receive scenario (two SemTech radios pinging and ponging each other).

 

There are several ways to replace one utility/service library by another.

In the case where there is documentation of dependencies, one can start from that.

In the case where the dependencies are to be detected from sources, there are also a few options.

You can walk through the code and flag all constructs that are dependent on the library you want to replace.

Another option is to hide that library from the build process and let the build log point out what's broken.

That's the approach I'm using here.

 

 

 

Task 1: Break the Dependency with MBED

 

The easiest way to find dependencies is to cut away the MBED sources and libraries. Then use the tool chain build errors to point at the gaps. Tools are more efficient than a full manual gap analysis in many cases.

You can start from an empty project for your target platform.

For a Pi, that could be a "Hello, world!" Linux project in Eclipse. For my platform, I used a minimal Hercules project.

As long as you have a project that successfully runs on your target (it does not have to do anything functional), you are good to go.

If you do that, you have broken the MBED link. You now have a non-MBED project as starting point.

Take care that you don't have any build errors or warnings left. We'll use the build error log in the next step to help replace the functions provided by MBED.

 

Task 2:  Integrate the MBED Example Code in your Project

 

This is the step where you copy the sources (h and cpp) from the MBED example to your project.

Usually, the library code can just be copied and pasted into your project.

You'll have to do some manual work to merge your project's main file with the main from the MBED example.

Take care that you take over all includes, move all declarations above your project's main() declaration, and add the example's main() functionality to that of your project.

Save everything. Then, just for kicks, build the example. You'll have many errors.

 

Task 3: Collect Unresolved MBED Dependencies

 

For all the errors that you have now during compilation, you'll have to provide a replacement.

My approach is to create a honeypot to put all the unresolved issues. I use a header file called missing.h for that.

First, I replace any occurance of mbed.h with missing.h in the project.

Then I compile again.

 

I then look at the errors in the build log and look for the ones that occur a lot.

I investigate the top one and try to find out what the dependency is.

A common miss is the digital i/o api from MBED.

What I then do, is look up the declaration of the missing dependency online (example: DigitalInOut).

I then create a minimal replacement of the declaration, without implementation, in the missing.h file.

 

Example:

 

class DigitalIn {
public:
  DigitalIn(PinName pin) {}
};

class DigitalOut {
public:
  DigitalOut(PinName pin) {}
  DigitalOut &operator= (int value) {}
  DigitalOut &operator= (DigitalOut &rhs) {}
};

class DigitalInOut {
public:
  DigitalInOut(PinName pin) {}
  DigitalInOut &operator= (int value) {}
  DigitalInOut &operator= (DigitalInOut &rhs) {}
  operator int() {}
  void input() {}
  void output() {}
};

 

You'll see that my classes are not complete. I only put those dependencies that break the build. And they have an empty implementation.

But those are the indicators of what functionality is missing.

 

I perform this exercise iterative.

  • find a build error
  • implement an empty implementation in missing.h
  • check that the build error is resolved
  • rinse and repeat

 

The number of comilation errors has to decrease whle doing that exercise. Repeat until no compilation errors (ignore link issues)

In my case, at the end of the exercise, I end with this missing.h file:

 

/*
 * missing.h
 *
 *  Created on: 9 nov. 2019
 *      Author: jancu
 */


#ifndef CPP_MISSING_H_
#define CPP_MISSING_H_


#include "HL_sys_common.h"


#include <stdio.h>
#include <string.h>


// define all MBED APIs, classes and defines used in the example


typedef enum {
    PIN_INPUT,
    PIN_OUTPUT
} PinDirection;


typedef enum {
  PA_0  = 0x00,
  PA_1  = 0x01,
  PA_2  = 0x02,
  PA_3  = 0x03,
  PA_4  = 0x04,
  PA_5  = 0x05,
  PA_6  = 0x06,
  PA_7  = 0x07,
  PA_8  = 0x08,
  PA_9  = 0x09,
  PA_10 = 0x0A,
  PA_11 = 0x0B,
  PA_12 = 0x0C,
  PA_13 = 0x0D,
  PA_14 = 0x0E,
  PA_15 = 0x0F,
  PB_0  = 0x10,
  PB_1  = 0x11,
  PB_2  = 0x12,
  PB_3  = 0x13,
  PB_4  = 0x14,
  PB_5  = 0x15,
  PB_6  = 0x16,
  PB_7  = 0x17,
  PB_8  = 0x18,
  PB_9  = 0x19,
  PB_10 = 0x1A,
  PB_12 = 0x1C,
  PB_13 = 0x1D,
  PB_14 = 0x1E,
  PB_15 = 0x1F,


  PC_0  = 0x20,
  PC_1  = 0x21,
  PC_2  = 0x22,
  PC_3  = 0x23,
  PC_4  = 0x24,
  PC_5  = 0x25,
  PC_6  = 0x26,
  PC_7  = 0x27,
  PC_8  = 0x28,
  PC_9  = 0x29,
  PC_10 = 0x2A,
  PC_11 = 0x2B,
  PC_12 = 0x2C,
  PC_13 = 0x2D,
  PC_14 = 0x2E,
  PC_15 = 0x2F,


  PD_2  = 0x32,


  PH_0  = 0x70,
  PH_1  = 0x71,
  A0          = PA_0,
  A3          = PB_0,
  A4          = PC_1,


  D1          = PA_2,
  D2          = PA_10,
  D3          = PB_3,
  D4          = PB_5,
  D5          = PB_4,
  D6          = PB_10,
  D7          = PA_8,
  D8          = PA_9,
  D9          = PC_7,
  D10         = PB_6,
  D11         = PA_7,
  D12         = PA_6,
  D13         = PA_5,
  D14         = PB_9,
  D15         = PB_8,


    // Generic signals namings
    LED1        = 0x05,
    LED2        = 0x05,






    // Not connected
    NC = (int)0xFFFFFFFF
} PinName;


class SPI {
public:
 SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel = NC) {}
 virtual int write(int value){return 0;}
 void format(int bits, int mode = 0) {}
};


class DigitalIn {
public:
  DigitalIn(PinName pin) {}
};


class DigitalOut {
public:
  DigitalOut(PinName pin) {}
  DigitalOut &operator= (int value) {}
  DigitalOut &operator= (DigitalOut &rhs) {}
};


class DigitalInOut {
public:
  DigitalInOut(PinName pin) {}
  DigitalInOut &operator= (int value) {}
  DigitalInOut &operator= (DigitalInOut &rhs) {}
  operator int() {}
  void input() {}
  void output() {}
};


template <typename F>
 class Callback;


class InterruptIn {
public:
  InterruptIn(PinName pin) {}
  void rise(void) {}
};


class Timeout{
protected:
  virtual void handler() {}
public:
  void detach() {}
};


// placeholder for all calls used in the MBED example that don't have an implementation
static inline void debug(const char *format, ...) {}
static inline void debug_if(int condition, const char *format, ...) {}




void wait_ms( int ) {}


void wait( int ) {}


double ceil(double) {return 0.0;}


double floor(double) {return 0.0;}


double rint(double) {return 0.0;}


#endif /* CPP_MISSING_H_ */

 

Some constructs are cumbersome to resolve, e.g.: the MBED Callback template construct.

In those cases, where it takes longer to do this exercise than it would be to build a final solution, I comment out the failing code and put a // todo: comment in the source.

Eclipse and other editors have a Task view that shows the things that have to be resolved in source code.

 

image

 

Work Items at This Stage

 

At this point, where there are 0 compilation errors left, we have a list of manageable work items.

    • All code in missing.h. Each of those will need a MBED-independent implementation.
      There's no need to implement it identical to MBED. But it's a good starting point. I think that the MBED object oriented abstractions are neat. Better than what I usually come up with.
    • The tasks in the Todo window. hose are all pieces of code you commented out but are needed for a working design.
      This is a good time to try and dig into those constructs, get a better understanding and create a solution that works on your non-MBED target platform.

Next steps for this blog: Resolve these gaps for my project and document them.

 

Because the Hercules projects are typically C, and the MBED libs are C++, I also had to provide a bridge between the two. A non-intrusive one.

Here's the write-down of that Hercules Safety Microcontroller: Use C++ with HALCoGen C Projects..

 

Related blog
Use C++ with HALCoGen C Projects

Port an MBED design to non-MBED - Phase 1: compile without errors

Port an MBED design to non-MBED - Phase 2a: DigitalOut Class Constructor
Port an MBED design to non-MBED - Phase 2b: DigitalOut Class and Blinky example
Port an MBED design to non-MBED - Phase 3: InterruptIn Class and example
Port an MBED design to non-MBED - Phase 4: Timeout Class and Blinky example
Port an MBED design to non-MBED - Phase 5: OO Callbacks Simplified
  • Sign in to reply

Top Comments

  • Jan Cumps
    Jan Cumps over 5 years ago +1
    The main functionality I'm missing at this point is difital GPIO and SPI and interrupt callbacks. It should not be too hard to come up with a design for the first two that's close to the MBED design. The…
  • Jan Cumps
    Jan Cumps over 5 years ago +1
    ... next steps are to solve those parts that are not strictly MBED dependencies, but C++ dependencies that are resolved somewhere in th MBED includes. I have these instances: memory copy and I/O (not gpio…
  • Jan Cumps
    Jan Cumps over 5 years ago in reply to shabaz +1
    I often do the same The MBED example for the SemTech chip doesn't use the MBED OS's job scheduler - it's a straightforward main loop approach. They use some library functions though. The deeper I drill…
Parents
  • shabaz
    shabaz over 5 years ago

    Hi Jan,

     

    This is really great progress. This will be extremely useful to anyone who wishes to work with LoRa!

    Regarding interrupt handling, if you're trying to make it cross-platform to work without an OS too, I'm sure you have your favourite methods to do it, for what it's worth for hobby stuff I sometimes I just have a timer tick always running (say every millisecond or ten millisec), and execute my state machine in there (since that doesn't take much overhead and executes quickly). Then, any messages to the state machine just become the setting of variables, and similarly any code that needs to be executed by the state machine is another variable change.. and a main while forever loop handles each message at a time. This is super-basic and full of holes if not done carefully, but at least is supported everywhere that a timer tick or periodic function works, and doesn't need threads either, nor C++. On larger systems there's the luxury of using actual real-time middleware of course, but that turns it all into a more major project.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 5 years ago in reply to shabaz

    I often do the same image

     

    The MBED example for the SemTech chip doesn't use the MBED OS's job scheduler - it's a straightforward main loop approach. They use some library functions though.

    The deeper I drill into those, the more I like them. I think that there are some good object oriented designers involved with the MBED development.

    So if I can port this while keeping their mechanisms (and blogging about them in awe image ) during the next Project14 RF month, I'll do that.

    If I fail to complete it by then, I'll take all shortcuts and approaches that I deem fit for purpose image.

     

    It's also a refresher for me. I've been a C++ developer at the beginning of my IT career - claimed being an expert at that time. I lost some of that and this is a chance to get back on level ....

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • Jan Cumps
    Jan Cumps over 5 years ago in reply to shabaz

    I often do the same image

     

    The MBED example for the SemTech chip doesn't use the MBED OS's job scheduler - it's a straightforward main loop approach. They use some library functions though.

    The deeper I drill into those, the more I like them. I think that there are some good object oriented designers involved with the MBED development.

    So if I can port this while keeping their mechanisms (and blogging about them in awe image ) during the next Project14 RF month, I'll do that.

    If I fail to complete it by then, I'll take all shortcuts and approaches that I deem fit for purpose image.

     

    It's also a refresher for me. I've been a C++ developer at the beginning of my IT career - claimed being an expert at that time. I lost some of that and this is a chance to get back on level ....

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
  • shabaz
    shabaz over 5 years ago in reply to Jan Cumps

    Jan Cumps  wrote:

     

    I I think that there are some good object oriented designers involved with the MBED development.

     

    Agree. It all feels production-grade. Also, there's a vast amount of functionality. mbed is a awesome system.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube