How to make my firmware compatible on two microcontrollers

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

How to make my firmware compatible on two microcontrollers

1,646 Views
DeepakK
Contributor I

My physical board has two variations, one has MK12_DN_512 part and other has MK12_DX_256 part. Rest everything is same The two microcontrollers are from the same family, infact share the same datasheet and are pin to pin replaceable.. The only difference is the memory size.

I am using the MCUXpresso IDE as my development tool. I downloaded the SDK for the MK12_DN_512 part and tested my firmware.

How can I easily switch to the MK12_DN_256 part, build my code and test on it? The difference in memory size is not an issue since my firmware is hardly 10KByte of flash

I would want to keep my firmware files common for version control purposes for the two parts. 

0 Kudos
4 Replies

1,303 Views
scottm
Senior Contributor II

For parts that differ only in memory configuration, you might be able to get away with not changing anything. We used to use the MC9S08AW32 in a handful of products and at various times we've substituted the MC9S08AW48 or MC9S08AW60, depending on what's available. We didn't even change anything on the production programmer, just loaded the AW32 firmware directly onto the AW48 and AW60 parts.

I do have some projects that span multiple device families with different capabilities. My current solution for that is to keep the main application code in its own git submodule repository - in the past I've used linked source folders to have multiple projects share the same folder for the main application, but I've found that linked folders can cause weird issues with MCUXpresso projects and it's been safer to keep all of the source in the project folder. And of course if the application code changes much, git ensures that I don't break one build while I'm working on another.

My application code as a rule doesn't make any direct references to hardware registers or SDK functions. There's always a layer of abstraction. Like I'll have an spi_byte() function, which is implemented in a support library for that device family and it might map to an SDK function or to my own driver.

So the result is an IDE project that has a submodule for the common application code, and one or more submodules specific to a device family to contain my drivers or wrappers to the SDK, and then the project itself has board-specific files to handle pin assignments and hardware details.

Scott

1,642 Views
ErichStyger
Senior Contributor V

Hi @DeepakK ,

I'm afraid there is probably no simple (or single) answer to this. The thing is that there is a 'simple and short' answer for simple cases, and a longer one if you want to use an approach which is more powerful and applies to a more universal use case.

 

The 'short' one:

If it is only about the memory map/size, then you simply can go the the 'MCU settings' and change the memory size there:

ErichStyger_0-1661788541194.png

But that way you always have to change the settings if you switch the device. Good for a one-off thing. Bad if you want or need to maintain both variants the same time.

 

The 'long' one:

The other way is that you have two (or multiple) projects: one for each device. This is what I do in my projects. I even have projects that way with the same/common source base for completely different MCUs (Kinetis, LPC and even others).

So the idea is to have a project for each MCU/device, but configuring and sharing the source files for it. To share things between projects, see my article about this here: https://mcuoneclipse.com/2014/08/15/link-to-files-and-folders-in-eclipse/

How to configure things for different devices, I wrote an article about this here: https://mcuoneclipse.com/2019/02/23/different-ways-of-software-configuration/

To give you an idea, how this looks likes, see https://github.com/ErichStyger/MetaClockClock or the screenshot below:

ErichStyger_1-1661788935120.png

The yellow marked things are links to folders with all the common source code. The things in the red box are just the main() plus two configuration header files. Everything else is shared or anyway part of the MCUXpresso SDK setup. So about 99% of the source base is really shared, and the project only is a kind of container for the SDK (yes, with some of the SDK generated files). But all the application and driver files are inside McuLib and ClockCommon, and that way portable between systems.

As you can see with the above example: everything is under git/version control, and portable between M0+ (LPC) and different M4 MCUs. Up to the point that the application itself is very different across multiple platforms, with the full source base configured and shared between the projects :-).

And it gives you the ability to create production binaries, plus you can debug projects in parallel/etc.

Last but not least: if your 'common' sources are 'static', you might consider using a library. I wrote about this for example here: https://mcuoneclipse.com/2017/09/19/managing-project-and-library-dependencies-with-eclipse-cdt/

I hope this helps,

Erich

 

1,619 Views
DeepakK
Contributor I

Thanks Erich for the elaborate reply, the longer approach seems good.

BTW a big fan of your MCU on eclipse web pages. Thanks for curating all your knowledge and experience into these webpages that are of good help.

There is a slight issue that I am facing and maybe you can throw some light.

So, like I mentioned I have an existing tested project with MK12DN512VLK5, and now I am making a new one with the MK12DX128 part.

I want to bring all the SDK component selection, pin configuration from the existing project to the new project(with the different pin compatible part).

What is a good way to migrate that from one project to another?

Since I had configured the old project quite some time back, I only broadly remember which SDK components I had selected for the project. When I try to confirm these settings, the IDE just shows a blank (attaching the screenshots). I am sure there must be some project settings file that will be holding this configuration data that I can check, can you please tell which one?

0 Kudos

1,616 Views
ErichStyger
Senior Contributor V

Hi @DeepakK ,

BTW a big fan of your MCU on eclipse web pages. Thanks for curating all your knowledge and experience into these webpages that are of good help.

Thank you :-).

What is a good way to migrate that from one project to another?

There is no easy way to migrate the SDK configuration and settings (pins tool, etc) to a new project.

That's why by now I basically only use these tools to explore the settings, but later on do it directly in my code, with the exception of the clock configurations.

One important concept to realize with the SDK configuration tools is that it stores the settings in the .mex file (check the root of your project). But the same time the settings are stored in the source files as YAML code. For example check files like clock_config. which has something link this:

 

 

/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
!!Configuration
name: BOARD_BootClockRUN
called_from_default_init: true
outputs:
- {id: Bus_clock.outFreq, value: 60 MHz}
- {id: Core_clock.outFreq, value: 120 MHz}
- {id: ERCLK32K.outFreq, value: 32.768 kHz}
- {id: Flash_clock.outFreq, value: 24 MHz}
- {id: FlexBus_clock.outFreq, value: 40 MHz}
- {id: LPO_clock.outFreq, value: 1 kHz}
- {id: MCGFFCLK.outFreq, value: 250 kHz}
- {id: OSCERCLK.outFreq, value: 8 MHz}
- {id: PLLFLLCLK.outFreq, value: 120 MHz}
- {id: System_clock.outFreq, value: 120 MHz}
- {id: USB48MCLK.outFreq, value: 48 MHz}
settings:
- {id: MCGMode, value: PEE}
- {id: MCG.FRDIV.scale, value: '32'}
- {id: MCG.IREFS.sel, value: MCG.FRDIV}
- {id: MCG.PLLS.sel, value: MCG.PLL}
- {id: MCG.PRDIV.scale, value: '2'}
- {id: MCG.VDIV.scale, value: '30'}
- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower}
- {id: MCG_C2_RANGE0_CFG, value: Very_high}
- {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high}
- {id: OSC_CR_ERCLKEN_CFG, value: Enabled}
- {id: OSC_CR_EREFSTEN_CFG, value: Enabled}
- {id: RTC_CR_OSCE_CFG, value: Enabled}
- {id: SIM.OSC32KSEL.sel, value: RTC.RTC32KCLK}
- {id: SIM.OUTDIV2.scale, value: '2'}
- {id: SIM.OUTDIV3.scale, value: '3'}
- {id: SIM.OUTDIV4.scale, value: '5'}
- {id: SIM.PLLFLLSEL.sel, value: MCG.MCGPLLCLK}
- {id: SIM.USBDIV.scale, value: '5'}
- {id: SIM.USBFRAC.scale, value: '2'}
- {id: SIM.USBSRCSEL.sel, value: SIM.USBDIV}
- {id: USBClkConfig, value: 'yes'}
sources:
- {id: OSC.OSC.outFreq, value: 8 MHz, enabled: true}
- {id: RTC.RTC32kHz.outFreq, value: 32.768 kHz, enabled: true}
 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */

 

 

This all contains the settings in 'human readable format': you won't be able to use that in the other project directly, but gives you the information of the settings and changes.

As for the SDK drivers loaded for a project: check the .cproject file of your project, there is something like this below which tells you the list of components:

<storageModule moduleId="com.nxp.mcuxpresso.core.datamodels">
<sdkName>SDK_2.x_MK22FX512xxx12</sdkName>
<sdkVersion>2.3.1</sdkVersion>
<sdkComponents>middleware.baremetal.MK22F12;platform.devices.MK22F12_startup.MK22F12;platform.devices.MK22F12_CMSIS.MK22F12;platform.Include_common.MK22F12;platform.Include_core_cm4.MK22F12;platform.drivers.gpio.MK22F12;platform.drivers.clock.MK22F12;platform.drivers.common.MK22F12;platform.drivers.i2c.MK22F12;platform.drivers.uart.MK22F12;platform.drivers.adc16.MK22F12;platform.drivers.dspi.MK22F12;platform.drivers.flash.MK22F12;platform.drivers.ftm.MK22F12;platform.drivers.port.MK22F12;platform.drivers.sim.MK22F12;platform.drivers.pit.MK22F12;platform.utilities.debug_console.MK22F12;platform.drivers.sysmpu.MK22F12;platform.drivers.rtc.MK22F12;</sdkComponents>
<package>MK22FX512VLK12</package>
<core>cm4</core>
<coreId>core0_MK22FX512xxx12</coreId>
</storageModule>

Erich

0 Kudos