# FreeRTOS SMP Port to VS

**URL:** <https://forums.freertos.org/t/freertos-smp-port-to-vs/19888>\
**Category:** Kernel\
**Created:** [April 26, 2024, 9:35am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888 "2024-04-26T09:35:20Z")\
**Posts on this page:** 20\
**Page:** 4

<div class="post-metadata">

**Author:** ![richard-damon](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/richard-damon/32/38_2.png) [@richard-damon](https://forums.freertos.org/u/richard-damon)\
**Post date:** [June 10, 2024, 2:19am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/61 "2024-06-10T02:19:52Z")

</div>

Why do you think that Queue can not be used on SMP systems?

They can’t be used between cores on an AMP system, but SMP is fine.

If your queues are having problems, it is more likely that your SMP port isn’t doing what it needs to.

---

<div class="post-metadata">

**Author:** ![wuxuangle](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/wuxuangle/32/4503_2.png) [@wuxuangle](https://forums.freertos.org/u/wuxuangle)\
**Post date:** [June 10, 2024, 5:59am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/62 "2024-06-10T05:59:06Z")

</div>

Your viewpoint is likely correct, but I am uncertain about the root cause. Let me describe the current state of affairs on my end:

A timer guardian thread is bound to core 0.

In the main function, the “Start For Core0 Task” is created and bound to core 0 with a priority of 5.

In the main function, the “Start For Core1 Task” is created and bound to core 1 with a priority of 5.

The “Start For Core0 Task” creates the “TestA” task bound to core 0. The priority of TestA is 10; TestA waits for semaphore A. Then, a periodic timer A is created, and after the creation of periodic timer A is successful, Timer A is started. Subsequently, a one-shot Timer B is created. The callback function of Timer A, upon counting to 14, activates Timer B. In the callback function of Timer B, semaphore A is sent, and after TestA task waits for the semaphore, it sends a message to TestB.

The “Start For Core1 Task” creates the “TestB” task bound to core 0. The priority of TestB is 7. TestB uses `xStreamBufferIsEmpty` to check if the stream buffer has any messages. If the stream buffer is empty, it prints no message to process; otherwise, it uses `xStreamBufferReceive` to retrieve messages from TestA and processes them.

```c
#define portEnter_CRITICAL() vTaskEnterCritical()
#define portExit_CRITICAL() vTaskExitCritical()

```

`configNUMBER_OF_CORES: 2`  
`configUSE_CORE_AFFINITY: 1`  
`configTIMER_SERVICE_TASK_CORE_AFFINITY: 0`  
`configUSE_PREEMPTION: 0`  
`configUSE_TIME_SLICING: 1`  
`configRUN_MULTIPLE_PRIORITIES: 1`

From the trace, the following task switch process is observed:

On core 0: IDLE0 → Tmr Svc → Start For Core0 Task → TestA task → Tmr Svc (periodic timer A) → TestA task →  
…→Tmr Svc (one-shot timer B): sends semaphore → TestA task:sends message to TestB→…

On core 1: IDLE1 → Start For Core1 Task → TestB (prints no message to process) → TestB (prints no message to process) → TestB (prints no message to process) → TestB (prints no message to process) → TestB (prints no message to process)→…

Note: TestA continuously sends messages to TestB until the stream buffer is full, at which point TestA is blocked. If TestB does not use `xStreamBufferIsEmpty` and directly uses `xStreamBufferReceive`, TestB will be blocked immediately.If TestA and TestB communicate using a queue, both sides would be blocked directly. From the current perspective, it appears that each core is scheduling its own tasks, and the TestA task on core 0 cannot communicate with the TestB task on core 1. However, tasks on the same core should be able to communicate with each other using semaphores.

In the current state, are there any good solutions? Or are there any good directions to try out?

---

<div class="post-metadata">

**Author:** ![richard-damon](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/richard-damon/32/38_2.png) [@richard-damon](https://forums.freertos.org/u/richard-damon)\
**Post date:** [June 10, 2024, 1:07pm UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/63 "2024-06-10T13:07:01Z")

</div>

When task A adds a message to the buffer, if there is a task ON ANY CORE waiting for that buffer, it should move it from blocked to ready. and if that task is higher in priority than a task currently executing on any core that task can run on, it should send the cross core signal to force the reschedule on that core.

Your description sounds like the cross core signaling isn’t working, which would be a problem in the SMP port layer.

---

<div class="post-metadata">

**Author:** ![wuxuangle](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/wuxuangle/32/4503_2.png) [@wuxuangle](https://forums.freertos.org/u/wuxuangle)\
**Post date:** [June 11, 2024, 12:46am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/64 "2024-06-11T00:46:07Z")

</div>

Could you take the stream as an example to demonstrate: when TestA on core 0 sends a message to TestB on core 1 through the stream, where in the kernel’s code does this cross-core signal take effect? I will debug according to the displayed segment of code to find out what is causing the cross-core signal not to work properly?

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [June 11, 2024, 5:17am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/65 "2024-06-11T05:17:36Z")

</div>

> [@wuxuangle](#):
>
> where in the kernel’s code does this cross-core signal take effect?

It is implemented internally and uses the macro `portYIELD_CORE`. Check your implementation of this macro and see if you are able to interrupt core 1 from core 0.

---

<div class="post-metadata">

**Author:** ![wuxuangle](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/wuxuangle/32/4503_2.png) [@wuxuangle](https://forums.freertos.org/u/wuxuangle)\
**Post date:** [June 11, 2024, 8:58am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/66 "2024-06-11T08:58:44Z")

</div>

> [@aggarg](#):
>
> It is implemented internally and uses the macro `portYIELD_CORE`. Check your implementation of this macro and see if you are able to interrupt core 1 from core 0.

if this meas that I will look for the macro `portYIELD_CORE` in the stream api，and then debug the portYIELD\_CODE？but I don’t understand stream api, so I want Your help for give the accurate code position of the macro `portYIELD_CORE`，So that I can debug this source more accurately and quickly， and find the root cause from the source downwards。

---

<div class="post-metadata">

**Author:** ![richard-damon](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/richard-damon/32/38_2.png) [@richard-damon](https://forums.freertos.org/u/richard-damon)\
**Post date:** [June 11, 2024, 8:59pm UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/67 "2024-06-11T20:59:51Z")

</div>

The Stream Buffer will call xTaskNotify to wake up the receiving task, to let it know data is present.

Notify will call taskYIELD\_ANY\_CORE\_IF\_USING\_PREEMPTION, which will call prvYieldForTask which is in the port layer if you are in SMP mode.

---

<div class="post-metadata">

**Author:** ![wuxuangle](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/wuxuangle/32/4503_2.png) [@wuxuangle](https://forums.freertos.org/u/wuxuangle)\
**Post date:** [June 12, 2024, 12:40am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/68 "2024-06-12T00:40:55Z")

</div>

> [@richard-damon](#):
>
> taskYIELD\_ANY\_CORE\_IF\_USING\_PREEMPTION

Does this mean that `configUSE_PREEMPTION` should be set to 1? However, during the actual debugging process, `configUSE_PREEMPTION` cannot be set to 1 because sometimes there is a deadlock situation where the IDLE task YIELDS and the TICK interrupt service routine causes both cores to YIELD simultaneously. Therefore, I have set `configUSE_PREEMPTION` to 0.

I would like to inquire, is it necessary to use the PREEMPTION mechanism when scheduling other cores? Can the other core be made to perform scheduling just by sending a PendSV interrupt without using the preemption mechanism?

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [June 12, 2024, 5:51am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/69 "2024-06-12T05:51:59Z")

</div>

> [@wuxuangle](#):
>
> Therefore, I have set `configUSE_PREEMPTION` to 0.

When `configUSE_PREEMPTION` is set to 0, a context switch will only occur when the Running task enters the Blocked state, or the Running task explicitly yields (manually requests a re-schedule) by calling taskYIELD().

> [@wuxuangle](#):
>
> I would like to inquire, is it necessary to use the PREEMPTION mechanism when scheduling other cores?

No, it is not. As explained above, running task either need to block or yield explicitly.

---

<div class="post-metadata">

**Author:** ![wuxuangle](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/wuxuangle/32/4503_2.png) [@wuxuangle](https://forums.freertos.org/u/wuxuangle)\
**Post date:** [June 12, 2024, 8:15am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/70 "2024-06-12T08:15:23Z")

</div>

> [@aggarg](#):
>
> No, it is not. As explained above, running task either need to block or yield explicitly.

Thank you very much. Next, I will proceed to debug the reason why cross-core scheduling is not possible on SMP using xTaskNotify and taskYIELD\_ANY\_CORE\_IF\_USING\_PREEMPTION.

---

<div class="post-metadata">

**Author:** ![wuxuangle](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/wuxuangle/32/4503_2.png) [@wuxuangle](https://forums.freertos.org/u/wuxuangle)\
**Post date:** [June 15, 2024, 3:43am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/71 "2024-06-15T03:43:49Z")

</div>

1.Due to in-depth debugging, I have gained a deeper understanding of the previous phenomenon, and I need to correct the previous phenomenon.

A timer guardian thread is bound to core 0.

In the main function, the “Start For Core0 Task” is created and bound to core 0 with a priority of 5.

In the main function, the “Start For Core1 Task” is created and bound to core 1 with a priority of 5.

The “Start For Core0 Task” creates the “TestA” task bound to core 0. The priority of TestA is 10; TestA waits for semaphore A. Then, a periodic timer A is created, and after the creation of periodic timer A is successful, Timer A is started. Subsequently, a one-shot Timer B is created. The callback function of Timer A, upon counting to 14, activates Timer B. In the callback function of Timer B, semaphore A is sent, and after TestA task waits for the semaphore, it sends a message to TestB.

The “Start For Core1 Task” creates the “TestB” task bound to core 0. The priority of TestB is 7. TestB uses `xStreamBufferIsEmpty` to check if the stream buffer has any messages. If the stream buffer is empty, it prints no message to process; otherwise, it uses `xStreamBufferReceive` to retrieve messages from TestA and processes them.

```auto
#define portEnter_CRITICAL() vTaskEnterCritical()
#define portExit_CRITICAL() vTaskExitCritical()

```

`configNUMBER_OF_CORES: 2`  
`configUSE_CORE_AFFINITY: 1`  
`configTIMER_SERVICE_TASK_CORE_AFFINITY: 0`  
`configUSE_PREEMPTION: 0`  
`configUSE_TIME_SLICING: 1`  
`configRUN_MULTIPLE_PRIORITIES: 1`

From the trace, the following task switch process is observed:

On core 0: IDLE0 → Tmr Svc → Start For Core0 Task → TestA task → Tmr Svc (periodic timer A) → TestA task →  
…→Tmr Svc (one-shot timer B): sends semaphore → TestA task:sends message to TestB by Xqueue→…

On core 1: IDLE1 → Start For Core1 Task → TestB（receive message by xQueue） →TestB（receive message by xQueue）→TestB（receive message by xQueue）

Note: The issue with xStream is likely the same as with xQueue, so I will choose xQueue as an example since I am more familiar with it.I will continue to use xQueue for message passing between cores. The previous blocking issue with inter-core messaging using xQueue was because TestB was created too early, before xQueue was successfully created, which led to an Assert failure. After adjusting the code, this ASSERT issue is resolved. When TestB receives messages, it uses xQueue and configures xTicksToWait as portMAX\_DELAY. Because TestB starts relatively early, the execution sequence on CORE1 is roughly as follows:  
TestB → xQueueReceive → vTaskPlaceOnEventList → vListInsert → prvAddCurrentTaskToDelayedList → taskYIELD\_WITHIN\_API in xQueueReceive →   
vTaskSwitchContext(Core1) → pxCurrentTCBS[core1] = TestB, which causes TestB to be executed repeatedly. During the third execution(At this point, no message has been sent to TestB yet.）,  
in vListInsert for(pxIterator = (ListItem\_t\*)&(pxList-\>xListEnd); pxIterator-\>pxNext-\>xItemValue \<= xValueOfInsertion; pxIterator = pxIterator-\>pxNext)  
a recursion is formed and it cannot get out. The reason is that the address of xListEnd and the pxNext below xListEnd are exactly the same, and xItemValue is equal to xValueOfInsertion. I don’t understand why TestB is not removed from the ready list and placed in the DelayedList? I think the normal phenomenon should be that after the first execution of the TestB task, it is removed from the ready list and the IDLE1 task is executed, and when there is a message in xQueue, TestB will re-enter the ready list for execution.

2.The code snippet in prvAddCurrentTaskToDelayedList is as follows:

```auto
if(uxListRemove(&(pxCurrentTCB->xStateListItem)) == (UBaseType_t)0)
{
    portRESET_READY_PRIORITY(pxCurrentTCB->uxPriority, uxTopReadyPriority);
}

```

Why not use configNUM\_OF\_CORES to differentiate between signal core and SMP core? Instead, why is the above method used directly?

3.Why can’t the idle task created for each core be bound to a specific core, and why does every idle task have the core 0 as its parent core attribute?

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [June 17, 2024, 7:10am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/72 "2024-06-17T07:10:12Z")

</div>

> [@wuxuangle](#):
>
> The reason is that the address of xListEnd and the pxNext below xListEnd are exactly the same, and xItemValue is equal to xValueOfInsertion.

This seems list or memory is corrupted.

> [@wuxuangle](#):
>
> I think the normal phenomenon should be that after the first execution of the TestB task, it is removed from the ready list and the IDLE1 task is executed, and when there is a message in xQueue, TestB will re-enter the ready list for execution.

Can you try to debug why that is not happening and if that is the cause of the corruption?

> [@wuxuangle](#):
>
> Why not use configNUM\_OF\_CORES to differentiate between signal core and SMP core?

The code to remove a task from ready list would be same in single core and SMP. Why do you think that the code should be different?

> [@wuxuangle](#):
>
> Why can’t the idle task created for each core be bound to a specific core

There is no benefit of doing that.

> [@wuxuangle](#):
>
> why does every idle task have the core 0 as its parent core attribute?

What do you mean by this? Can you link the specific code line you are referring to?

---

<div class="post-metadata">

**Author:** ![wuxuangle](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/wuxuangle/32/4503_2.png) [@wuxuangle](https://forums.freertos.org/u/wuxuangle)\
**Post date:** [June 17, 2024, 10:55am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/73 "2024-06-17T10:55:11Z")

</div>

> [@aggarg](#):
>
> The code to remove a task from ready list would be same in single core and SMP. Why do you think that the code should be different?

Because a single core uses `pxCurrentTCB` to obtain the current TCB, SMP (Symmetric Multi-Processing) cores use `pxCurrentTCBs` to obtain the current TCB for each core. Why can `pxCurrentTCB` be used to obtain the TCB for each core in SMP within this function? How is this achieved? Initially, I thought that the reason why the TestB task on core 1 could not be removed from the ready state was due to this issue.

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [June 17, 2024, 3:44pm UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/74 "2024-06-17T15:44:05Z")

</div>

> [@wuxuangle](#):
>
> Why can `pxCurrentTCB` be used to obtain the TCB for each core in SMP within this function? How is this achieved?

Because `pxCurrentTCB` is defined to `xTaskGetCurrentTaskHandle()` for SMP here - [FreeRTOS-Kernel/tasks.c at main · FreeRTOS/FreeRTOS-Kernel · GitHub](https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/tasks.c#L452).

---

<div class="post-metadata">

**Author:** ![wuxuangle](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/wuxuangle/32/4503_2.png) [@wuxuangle](https://forums.freertos.org/u/wuxuangle)\
**Post date:** [June 18, 2024, 12:55am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/75 "2024-06-18T00:55:21Z")

</div>

> [@aggarg](#):
>
> This seems list or memory is corrupted.

> [@aggarg](#):
>
> Can you try to debug why that is not happening and if that is the cause of the corruption?

> [@aggarg](#):
>
> What do you mean by this? Can you link the specific code line you are referring to?

Okay, I will continue to debug in the direction you suggested. Currently, it seems that using `uxQueueMessagesWaiting` has bypassed the aforementioned issue, and TestB is able to start as planned. I may need to continue debugging to see if it meets the expected outcome.

---

<div class="post-metadata">

**Author:** ![wuxuangle](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/wuxuangle/32/4503_2.png) [@wuxuangle](https://forums.freertos.org/u/wuxuangle)\
**Post date:** [June 23, 2024, 7:37am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/76 "2024-06-23T07:37:04Z")

</div>

> [@aggarg](#):
>
> What do you mean by this? Can you link the specific code line you are referring to?

The English translation of the given text is:

In `prvCreateIdleTasks`, it calls

```c
xTaskCreateStatic(pxIdleTaskFunction,
                                  cIdleName,
                                  uxIdleTaskStackSize,
                                  (void*)NULL,
                                  portPRIVILEGE_BIT,
                                  pxIdleTaskStackBuffer,
                                  pxIdleTaskTCBBuffer);

```

to create the Idle task for each core. However, in `xTaskCreateStatic`,

```c
#if(( configNUMBER_OF_CORES > 1) && ( configUSE_CORE_AFFINITY == 1))
{
    pxNewTCB->uxCoreAffinityMask = configTASK_DEFAULT_CORE_AFFINITTY;
}
#endif

```

This results in both idle tasks having the core affinity set to core 0.

This is the reason why the task switching on core 1, when calling `prvSelectHighestPriorityTask`, includes the following code snippet:

```c
if(pxTCB->xTaskRunState == taskTASK_NOT_RUNNING)
{
    #if(configUSE_CORE_AFFINITY == 1)
    if((pxTCB->uxCoreAffinityMask&((UBaseType_t)1U << (UBaseType_t)xCoreID))
    #endif
    {
        pxCurrentTCBs[xCoreID]->xTaskRunState = taskTASK_NOT_RUNNING;
        #if(configUSE_CORE_AFFINITY == 1)
            pxPreviousTCB = pxCurrentTCBs[xCoreID];
        #endif
        pxTCB->xTaskRunState = xCoreID;
        pxCurrentTCBs[xCoreID] = pxTCB;
        xTaskScheduled = pdTRUE;
    }
}

```

This code cannot be executed, and as a result, the task pointed to by `pxCurrentTCBs[xCoreID]` always refers to TestB. Therefore, even if TestB is removed from `pxReadyTaskLists`, it will still be executed again after the scheduling is complete. Therefore, it is necessary to bind the core affinity of the idle task for core 1 to core 1 itself.

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [June 24, 2024, 5:50am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/77 "2024-06-24T05:50:51Z")

</div>

> [@wuxuangle](#):
>
> This results in both idle tasks having the core affinity set to core 0.

The default value of `configTASK_DEFAULT_CORE_AFFINITTY` is `tskNO_AFFINITY` and not 0 - [FreeRTOS-Kernel/include/FreeRTOS.h at main · FreeRTOS/FreeRTOS-Kernel · GitHub](https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/include/FreeRTOS.h#L507). Are you setting `configTASK_DEFAULT_CORE_AFFINITTY` to 0 in your FreeRTOSConfig.h?

---

<div class="post-metadata">

**Author:** ![wuxuangle](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/wuxuangle/32/4503_2.png) [@wuxuangle](https://forums.freertos.org/u/wuxuangle)\
**Post date:** [June 24, 2024, 6:47am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/78 "2024-06-24T06:47:45Z")

</div>

> [@aggarg](#):
>
> Are you setting `configTASK_DEFAULT_CORE_AFFINITTY` to 0 in your FreeRTOSConfig.h?

Yes，but if I configure it as 1, then both idle tasks will be bound to core1,which also is a problem. that is the idle task on core0 will not continue to run after the first run.

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [June 24, 2024, 6:55am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/79 "2024-06-24T06:55:33Z")

</div>

> [@wuxuangle](#):
>
> Yes，but if I configure it as 1, then both idle tasks will be bound to core1,which also is a problem. that is the idle task on core0 will not continue to run after the first run.

Remove that setting from your FreeRTOSConfig.h so that the default value will be used.

---

<div class="post-metadata">

**Author:** ![wuxuangle](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/wuxuangle/32/4503_2.png) [@wuxuangle](https://forums.freertos.org/u/wuxuangle)\
**Post date:** [June 24, 2024, 9:27am UTC](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888/80 "2024-06-24T09:27:58Z")

</div>

> [@aggarg](#):
>
> Remove that setting from your FreeRTOSConfig.h so that the default value will be used

thank you, I will try the suggest

[Previous page](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888.md?page=3)

[Next page](https://forums.freertos.org/t/freertos-smp-port-to-vs/19888.md?page=5)
