Running FreeRTOS on CM0+

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
NiBu_4687336
Level 5
Level 5
5 solutions authored 50 replies posted 25 replies posted

Hi.

The most recent discussion on this topic dates back to 2018. At that point, Cypress did not support running FreeRTOS on the PSoC 6's CM0+ core.

First - has that position changed? Is there any official support for FreeRTOS on the CM0+?

Second - has anyone done this, especially using ModusToolbox? If so, would  you please share your experience here?

A side issue is that the procedure for developing dual-CPU applications using ModusToolbox omits the FreeRTOS include directories from the compiler command line. The obvious brute-force workaround would be to add them in the CM0+ Makefile. Is there a better way?

There is a CM0 port of FreeRTOS available directly from FreeRTOS - download the FreeRTOS distro, then look in

<distro root>/FreeRTOS/Source/portable/<compiler>/ARM_CM0

The port is not specific to the PSoC 6, of course, and I'm unclear exactly what, if anything, needs to be changed.

For background, we plan to run FreeRTOS on both PSoC 6 cores. The CM0+ will handle data acquisition code (external multi-channel SPI ADC via DMA), and lightweight feature detection. The CM4 will be called into action for heavyweight processing when a feature is detected.

Thanks,

-Nick

0 Likes
1 Solution

To update this thread on my experience, once I switched to ModusToolbox 2.2, I found that the "stock" FreeRTOS CM0 port worked without significant changes. Use the FreeRTOS-Kernel repository to avoid all the demo and "plus" code. You'll still have to prune all the unused compilers (i.e. everything except GCC) from the "portable" directory, and then the unused processors (i.e. everything except ARM_CM0) from the GCC compiler directory, or ModusToolbox will try to compile them all. You can either prune the unused heap_N.c files, or modify them as Cypress did so that only the selected version compiles.

I should note that there are no differences between the CM0 and CM0+ processors that affect the code they run, so there is no port specifically targeting the CM0+.

Be prepared to fiddle with the Makefile a bit. Beware that the Makefile may have a hard-coded starting address for the CM4 code, which will step on any value in the linker script. You should be able simply to delete that definition from the Makefile. The "make" facility is rather byzantine, and not well documented, so be prepared for some head-scratching and experimentation.

The document that is intended to explain dual-core programming (PSoC 6 MCU Dual-CPU System Design) is a bit thin, and does not entirely match the configuration used in the example I chose to work with, the mtb-example-psoc6-dual-cpu-ipc-pipes project. Also, ModusToolbox doesn't play particularly nicely with the basic setup either, as most of the magic is placed where Eclipse CDT's code navigation can't find it. A good text search tool (e.g. find + grep) will come in handy be required.

Have fun!

-Nick

View solution in original post

0 Likes
16 Replies
RiBa_4055821
Level 1
Level 1

FreeRTOS will run on any Cortex-M0, M0+, M3, M4, M4F, M7, M23 and M33 chips that has adequate RAM.  You don't need to port it, but there won't necessarily be a preconfigured demo you can use as a starting point.  The following links may help:

Creating a new RTOS project

FreeRTOS - Porting a FreeRTOS demo to a different hardware platform

If you are using GCC then you will need the port layer files in the FreeRTOS/Source/portable/GCC/ARM_CM0 directory:

FreeRTOS - Free RTOS Source Code Directory Structure

FreeRTOS-Kernel/portable/GCC/ARM_CM0 at master · FreeRTOS/FreeRTOS-Kernel · GitHub

0 Likes

Hi RiBa_4055821​.

Thanks for the reply. It seems mostly to repeat the same information as my original post, but to clarify, yes, you do need to port FreeRTOS to the CM0+. Cypress provides only a CM4 port, which will not work on the CM0+. If you meant to reiterate that the work of porting to the CM0 had already been done, then you're correct.

Here is what I have learned since then.

First, to answer my own question, Cypress does not appear to provide an implementation of FreeRTOS for the CM0+ processor. Your best bet is to start with the CM0 port from FreeRTOS.

If you're using FreeRTOS on both the CM4 and CM0+ processors in a ModusToolbox dual-CPU project, it can no longer be considered a "shared" library, as described in PSoC 6 MCU Dual-CPU System Design​. You'll have to remove it from the shared/libs and deps directories and add the appropriate source trees to both the cm0p_app and cm4_app projects directly. This may apply even if you're using it only on the CM0+.

I've finally managed to compile and link my test project, but have now run into another problem, for which I'll start a new thread.

Thanks,

-Nick

0 Likes

I don't have new information to post, but I don't want this thread to die.

My first attempt at a CM0 port doesn't seem to be working, but the project is on hold temporarily.

-Nick

0 Likes
Vasanth
Moderator
Moderator
Moderator
250 sign-ins 500 solutions authored First question asked

Hi Nick,

As of now there is no plan to support FreeRTOS in PSoC6 CM0+ core. CM0 core is for specialized stuff like security, BLE controller etc as per the current expectation. But you should be able to port the FreeRTOS  to the CM0+ core. This document can be an interesting read.

Best Regards,
Vasanth

0 Likes

Hi VasanthR_91​.

Thanks - I've been trying to get the CM0 port from the FreeRTOS repo to run on the PSoC 6, but so far I haven't uncovered the secret. I'm stuck at the moment because something goes wrong at the point the scheduler attempts to set my task as the current task. I say "something," because the debugger becomes inoperative at that point, so it's difficult to diagnose further.

Breaking news - I've just upgraded to ModusToolbox 2.2 and the behavior described above has changed. It appears that my task is now actually running, with no other changes on my part. I'll post again when I know more

-Nick

0 Likes

Hi VasanthR_91​.

It appears that with the upgrade to ModusToolbox 2.2, my problems have magically disappeared. I guess that's good news, but I'd have been much happier to have found an error on my part than a mysterious compiler problem.

Thanks,

-Nick

0 Likes
Vasanth
Moderator
Moderator
Moderator
250 sign-ins 500 solutions authored First question asked

Hi Nick,

Happy to know that it is working. Happy Coding !

Best Regards,
Vasanth

0 Likes

Im glad it is fixed for you...

I am with you that I don't believe in magic.  I have a bad problem of letting problems like this get between my ears and not being able to sleep until I figure them out.

Ill bet money that it is not a compiler problem.  It is bound to be something else that you were doing... perhaps a shared memory resource?  Or interrupts?  Or a problem with the linker script?  There is exactly 0 technical reason why it wont work (as you demonstrated on MTB2.2) ...

Alan

0 Likes

Hi AlanD_81​.

Unfortunately, that's no more satisfying than a mysterious compiler error.

If it is something I was doing - I'm still doing it. I changed nothing in my project, I only upgraded ModusToolbox from version 2.1 to 2.2.

Before the upgrade, I was betting on a linker script problem, as they are complex and not well documented. The behavior was suggestive of bus (memory access) error, or other hardware trap being triggered and not handled. The project was simply the Cypress dual-CPU pipes example, modified to use FreeRTOS on both CPUs in place of the bare-metal loops.

The CM4 side gave me no problems, and there was nothing more complicated about the CM0+ side, but it would die (that is, the debugger would give up the ghost) at the "str" instruction that wrote the address of my task's TCB_t into the pxCurrentTcb pointer.

Since I can't reasonably bill my client for figuring out why it didn't work before, but does now, I'm afraid I'm doomed never to know the answer. Unless it's not really fixed, and the problem comes back to haunt me when I try something more complicated.

Thanks,

-Nick

0 Likes

Your response gives me the cold chills... I absolutely hate leaving issues like this laying around...

I haven't looked at the linker scripts recently... but I have never liked those things... it is an area where I am always very careful.

Alan

0 Likes

To update this thread on my experience, once I switched to ModusToolbox 2.2, I found that the "stock" FreeRTOS CM0 port worked without significant changes. Use the FreeRTOS-Kernel repository to avoid all the demo and "plus" code. You'll still have to prune all the unused compilers (i.e. everything except GCC) from the "portable" directory, and then the unused processors (i.e. everything except ARM_CM0) from the GCC compiler directory, or ModusToolbox will try to compile them all. You can either prune the unused heap_N.c files, or modify them as Cypress did so that only the selected version compiles.

I should note that there are no differences between the CM0 and CM0+ processors that affect the code they run, so there is no port specifically targeting the CM0+.

Be prepared to fiddle with the Makefile a bit. Beware that the Makefile may have a hard-coded starting address for the CM4 code, which will step on any value in the linker script. You should be able simply to delete that definition from the Makefile. The "make" facility is rather byzantine, and not well documented, so be prepared for some head-scratching and experimentation.

The document that is intended to explain dual-core programming (PSoC 6 MCU Dual-CPU System Design) is a bit thin, and does not entirely match the configuration used in the example I chose to work with, the mtb-example-psoc6-dual-cpu-ipc-pipes project. Also, ModusToolbox doesn't play particularly nicely with the basic setup either, as most of the magic is placed where Eclipse CDT's code navigation can't find it. A good text search tool (e.g. find + grep) will come in handy be required.

Have fun!

-Nick

0 Likes

A few more notes...

After power-on reset, the CM0+ is started, but the CM4 is held in reset. It is the responsibility of the CM0+ to enable the CM4. Oddly, though, Cypress's examples assume that it is the CM4 that will call cybsp_init(). One consequence of this order of operations is that if the CM0+ calls SystemCoreClockUpdate() before the CM4 has called cybsp_init(), the global variables that are supposed to indicate the system clock speed will not be set correctly. Since FreeRTOS maintains a SysTick timer, it has to know the actual speed of the SysTick interrupt, which is calculated from these variables. The default values indicate that the system clock (in the case of the CM0+, that's CLK_SLOW) has a frequency of 8 MHz, which will make any RTOS-based timers wildly incorrect.

Your choices here are to figure out how the CM0+ can determine that cybsp_init() has been called and postpone calling SystemCoreClockUpdate() until then, or have the CM0+ call cybsp_init() itself, before enabling the CM4. The CM4 will then be able to call SystemCoreClockUpdate(), knowing the the clocks have already been properly configured. It may also be necessary for the CM4 to call Cy_SystemInitFpuEnable() if it will use tthe FPU.

It also seems to be the case that the emeeprom EEPROM emulation library is restricted to the CM4. Attempting to link it into the CM0+ executable causes the resulting .bin file to balloon to over 64 MBytes.

I'll try to add more details as I discover them.

-Nick

0 Likes
rushikeshmunde
Level 1
Level 1
25 sign-ins 10 sign-ins 5 replies posted

@NiBu_4687336 

Thank you very much for your updates on this thread. I am also trying to run FreeRTOS on CM0+ and obviously was getting errors, then I came  across your thread.  What you said here makes sense, but I have a question, are you able to run FreeRTOS on both cores now  and be able to run your application ?

Because I am working on similar application where I need RTOS on both cores. 

Thanks & Regards

Rushikesh  

0 Likes

Hi @rushikeshmunde.

Yes, I was able to get FreeRTOS running on both cores, after a bit of experimentation. It requires that the system IPC pipe mechanism be properly configured and initialized, but you'll probably want that anyway.

As I mentioned, I did not use the FreeRTOS library provided by Cypress/Infineon, but cloned the FreeRTOS-Kernel repository on GitHub. It may not be strictly necessary, but it allows me to modify the repository and prevents the Cypress Library Manager from making unwanted changes.

Here's the startup sequence my application uses, glossing over some of the details:

On startup, the PSoC 6 puts the CM4 to sleep, then starts the CM0+.

The CM0+ first registers its IPC callback function with Cy_IPC_Pipe_RegisterCallback(), then starts the CM4 with Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR), and then goes to sleep by calling Cy_SysPm_DeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT). 

The CM4 calls cybsp_init(), then initializes its FreeRTOS tasks, and then calls vTaskStartScheduler(). One of the tasks finally sends an IPC message to the CM0+ that wakes it up.

The CM0+ then calls SystemCoreClockUpdate(), initializes its FreeRTOS tasks and  then calls vTaskStartScheduler().

I have a task running on each core to provide IPC communication from that point forward.

If you don't need inter-processor communication, you can probably use some other mechanism to synchronize the two cores' initialization procedures, but the key for me was to allow the CM4 to fully initialize the BSP before awakening the CM0+.

Getting the linker scripts right is imperative, as is setting the CY_CORTEX_M4_APPL_ADDR constant in system_psoc6.h correctly.

I'll be happy to provide more details if you need.

Good luck!

-Nick

0 Likes
rushikeshmunde
Level 1
Level 1
25 sign-ins 10 sign-ins 5 replies posted

Hi @NiBu_4687336 , 

Thank you for your reply and for the startup sequence. Yes, I am going to need IPC in my application. I will try setting up FreeRTOS on CM0+ first and will get in touch with you if I need more help. 

Hope you dont mind !

Thanks again 

Rushikesh

0 Likes
NiBu_4687336
Level 5
Level 5
5 solutions authored 50 replies posted 25 replies posted

Hi @rushikeshmunde.

I'll be happy to help.

-Nick

0 Likes