FreeRTOS SMP Port to VS

I hope to use freertos smp on vs to complete the simulation function of smp. How to operate specifically?

Dear brother,or is there an exiting port file available?

Dear brothers, or how should i transplant? can you provide a detailed list to me?

Can you elaborate what you mean by VS? Visual Studio (VS) is just a build platform. Are you asking about the FreeRTOS Windows Simulator port? If yes, we do not have SMP port for Windows Simulator. This page provides more details about SMP - Symmetric Multiprocessing (SMP) with FreeRTOS - FreeRTOS.

Yes, VS refers to Visual Studio (VS). If there isn’t an off-the-shelf Visual Studio simulation port for FreeRTOS SMP, then I would like to explore with you the feasibility of using Visual Studio (VS) combined with FreeRTOS SMP to simulate SMP behavior. If this is possible, we could preemptively avoid some design risks during the design phase. If the aforementioned idea is feasible, what should I do to implement the simulation port? Or, to implement this port, what specific aspects of work do I need to complete (and it would be great if you could provide a checklist for designing this port)? Lastly, thank you.

You need to write SMP port for Windows Simulator. You can use the single core Windows Simulator port as starting point. You can also refer to the existing SMP ports-

Thank you, do you think that using multiple processes can be used to simulate cores? If so, can each core be simulated with a separate process, and then bind all the processes to the same core on an x86 architecture? After that, can the threads created by FreeRTOS be bound to each of these processes? Would this approach achieve the desired effect?

One FreeRTOS application is one process as of today - so I am not sure how you’ll use separate processes to simulate cores. You need to elaborate more on how do you plan to do that.

Dear AggarG, the idea of simulating an SMP (Symmetric Multi-Processing) multi-core setup using processes is just a preliminary thought of mine. I haven’t really figured out the specifics, and I’m just curious to know if it’s feasible. From your hints, it seems that simulating cores with processes might not work very well. It appears that we can only rely on the two cores of the x86 on a PC to simulate two cores in an SMP setup, then create a Windows thread 1 to simulate the SysTick behavior running on Core A, create a Windows thread 2 to simulate the PendSV behavior running on Core A, and create a Windows thread 3 to simulate the PendSV behavior running on Core B. Windows thread 1 and Windows thread 2 can communicate with Windows thread 3 bidirectionally. This way, if there is a FreeRTOS thread scheduling on Core A, it can simultaneously notify Core B to perform FreeRTOS thread scheduling; if there is a FreeRTOS thread scheduling on Core B, it can simultaneously notify Core A to perform FreeRTOS thread scheduling. What do you think? Is this line of thinking feasible?

This seems like it should work. You may stumble upon some problems when you start implementing it - feel free to post them here.

AggarG, thank you, I feel that I will be troubling you again soon.

Looking forward to hear from you soon! Feel free to contribute your port once you are done :wink:

If I am successful, I would be very willing to share the steps involved in the porting process as well as the porting files.

My plan is as follows:

  1. To port the latest version v11.1.0, which supports SMP (Symmetric Multi-Processing), to Microsoft Visual C++ 6.0.
  2. First, successfully implement a single-core version of the task scheduler: a periodic timer sends a semaphore to Task 1, which then sends a message to Task 2.
  3. Then, convert the single-core version to an SMP version: the periodic timer and Task 1 are bound to Core A, Task 2 is bound to Core B, and the idle task can run on both Core A and Core B.

Currently, I have made some simple modifications and completed steps 1 and 2, but the outcome of step 2 has not met the expected results.


In the callback function of the software timer in v11.1.0, I called xSemaphoreGive(xSemaphore). Upon examining the call stack, I found that it got stuck in the function xTaskPriorityDisinherit with the assertion configASSERT(pxTCB == pxCurrentTCB), as pxTCB and pxCurrentTCB were not equal, causing it to keep getting stuck there. The semaphore xSemaphore was obtained through xSemaphoreCreateMutex, and the sending was performed using xSemaphoreGive, all of which was done according to the manual. What might be the issue here? Could you please help me analyze it?
Let me add some more information: pxCurrentTCB points to xTimerTaskTCB, while pxTCB points to the timer that I created.

Thank you

A mutex is meant for protecting resources from simultaneous access and its usage looks like the following :

1. Acquire mutex.
2. Use resource.
3. Release mutex.

It is expected that the task that releases the mutex must be the same that acquired it before.

A Semaphore, on the other hand, is meant for synchronization and there is no such restriction. If you are trying to synchronize tasks, you need to create a semaphore using xSemaphoreCreateBinary (instead of creating a mutex using xSemaphoreCreateMutex).

Thank you very much for your answer. There seems to be quite a few differences between this version of FreeRTOS-SMP and FreeRTOS V7.2.0, huh. Well, I will follow your steps to re-operate the Mutex.

Thank you very much. After replacing with xSemaphoreCreateBinary, the scheduling timing meets the requirements.

No. The semantics of semaphores and muteces and their differences have been unaltered pretty much from day one, as far as I can tell.

The functions that need to be added in the port file are as follows:
void vportGet_CoreId();
void vportSet_IntMask();
void vportClear_IntMask();
void vportRelease_TaskLock();
void vportGet_TaskLock();
void vportRelease_IsrLock();
void vportGet_IsrLock();
void vportEnter_CriticalFromIsr();
void vportExit_Critical_FromIsr();
void vPortGenerateSimulatedInterruptCore( uint32_t x, uint32_t ulInterruptNumber );
The functions that need to be modified in the port are as follows:
void prvProcessSimulatedInterrupts( void )
uint32_t prvProcessYieldInterrupt( void )
uint32_t prvProcessTickInterrupt( void )
vPortSetInterruptHandler( uint32_t ulInterruptNumber,uint32_t ( * pvHandler )( void ) )
BaseType_t xPortStartScheduler( void )
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,TaskFunction_t pxCode,void * pvParameters )

During the process of modifying the BaseType_t xPortStartScheduler(void) function, I have a few questions:

  1. How can I ensure that the highest priority tasks on each core are started first?
    [wuxu]:Similar to the approach on a single core, resume the highest-priority task on another core.
  2. If I run a prvProcessSimulatedInterrupts on core 0, how can I run another instance of prvProcessSimulatedInterrupts on core 1?
    [wuxu]:CreateThread(NULL,0,prvProcessSimulatedInterrupts,…),Bind to core 1, where prvProcessSimulatedInterrupts is modified to be a re-entrant function supporting two cores.,will be ok.
    I am looking forward to your response.


Another issue is:the portYield is mostly defined as portYield(x) in SMP scenarios, but in the task: portTASK_FUNCTION, the taskYIELD() is defined using portYield() instead, where portTASK_FUNCTION is located within #configNUMBER_OF_CORES > 1.
The issue is affecting my compilation, and my principle is to modify only the port files without making changes to the source files.

I am looking forward to your response.