Skip to main content

MCU1 Development Guide

MCU Interrupt Numbers and Corresponding Modules

ModuleInterrupt NumberName
SGI0-15
PPI16-31
MCU_STCU32Bist_Stcu0Isr
MEDIA_TOP_STCU33Bist_Stcu1Isr
VIDEO_STCU34Bist_Stcu2Isr
VDSP_STCU35Bist_Stcu3Isr
HSIS_STCU36Bist_Stcu4Isr
GPU_STCU37Bist_Stcu5Isr
DDR2_STCU38Bist_Stcu6Isr
DDR1_STCU39Bist_Stcu7Isr
DDR0_STCU40Bist_Stcu8Isr
CPU_MP4_STCU41Bist_Stcu9Isr
CPU_MP2_STCU42Bist_Stcu10Isr
CAM_STCU43Bist_Stcu11Isr
BPU0_STCU44Bist_Stcu12Isr
UART045Uart0_Isr
UART146Uart1_Isr
UART247Uart2_Isr
ADC048Adc_Ch0WdIsr
49Adc_Ch1WdIsr
50Adc_Ch2WdIsr
51Adc_Ch3WdIsr
52Adc_Ch4WdIsr
53Adc_Ch5WdIsr
54Adc_Ch6WdIsr
55Adc_Ch7WdIsr
56Adc_Ch8WdIsr
57Adc_Ch9WdIsr
58Adc_Ch10WdIsr
59Adc_Ch11WdIsr
60Adc_Ch12WdIsr
61Adc_Ch13WdIsr
62Adc_InjIsr
63Adc_NorIsr
I2C064I2c0_Isr
I2C165I2c1_Isr
I2C266I2c2_Isr
I2C367I2c3_Isr
GPIO068Gpio_Icu0ExtIsr
GPIO169Gpio_Icu1ExtIsr
GPIO270Gpio_Icu2ExtIsr
WWDT071Wdg_Ins0RstIsr
72Wdg_Ins0IntIsr
WWDT173Wdg_Ins1RstIsr
74Wdg_Ins1IntIsr
WWDT275Wdg_Ins2RstIsr
76Wdg_Ins2IntIsr
OTF_CRC077Otf_Isr
CRC078Crc_Isr
GPT079Gpt_Ins0Ch0Isr
80Gpt_Ins0Ch1Isr
81Gpt_Ins0Ch2Isr
82Gpt_Ins0Ch3Isr
GPT183Gpt_Ins1Ch0Isr
84Gpt_Ins1Ch1Isr
85Gpt_Ins1Ch2Isr
86Gpt_Ins1Ch3Isr
GPT287Gpt_Ins2Ch0Isr
88Gpt_Ins2Ch1Isr
89Gpt_Ins2Ch2Isr
90Gpt_Ins2Ch3Isr
GPT391Gpt_Ins3Ch0Isr
92Gpt_Ins3Ch1Isr
93Gpt_Ins3Ch2Isr
94Gpt_Ins3Ch3Isr
GPT495Gpt_Ins4Ch0Isr
96Gpt_Ins4Ch1Isr
97Gpt_Ins4Ch2Isr
98Gpt_Ins4Ch3Isr
GPT599Gpt_Ins5Ch0Isr
100Gpt_Ins5Ch1Isr
101Gpt_Ins5Ch2Isr
102Gpt_Ins5Ch3Isr
PMU103Pmu_ReqDeny0Isr
BIFSPI104
PVT105Pvt_McuAlarmIsr
L1FCHM106Fchm_MissionIntIsr
107Fchm_NcfIntIsr
108Fchm_CfIntIsr
CMM0109Cmm_Ins0Isr
CMM1110Cmm_Ins1Isr
PWM0111Pwm_Generic0Isr
XSPI112Xspi_Isr
CANFD0113Can0_TimestampIsr
114Can0_WakeupIsr
115Can0_ErrorIsr
116Can0_DataIsr
CANFD1117Can1_TimestampIsr
118Can1_WakeupIsr
119Can1_ErrorIsr
120Can1_DataIsr
CANFD2121Can2_TimestampIsr
122Can2_WakeupIsr
123Can2_ErrorIsr
124Can2_DataIsr
CANFD3125Can3_TimestampIsr
126Can3_WakeupIsr
127Can3_ErrorIsr
128Can3_DataIsr
CANFD4129Can4_TimestampIsr
130Can4_WakeupIsr
131Can4_ErrorIsr
132Can4_DataIsr
CANFD5133Can5_TimestampIsr
134Can5_WakeupIsr
135Can5_ErrorIsr
136Can5_DataIsr
CANFD6137Can6_TimestampIsr
138Can6_WakeupIsr
139Can6_ErrorIsr
140Can6_DataIsr
CANFD7141Can7_TimestampIsr
142Can7_WakeupIsr
143Can7_ErrorIsr
144Can7_DataIsr
CANFD8145Can8_TimestampIsr
146Can8_WakeupIsr
147Can8_ErrorIsr
148Can8_DataIsr
CANFD9149Can9_TimestampIsr
150Can9_WakeupIsr
151Can9_ErrorIsr
152Can9_DataIsr
mcu eth153Gmac_TxCh0Isr
154Gmac_TxCh1Isr
155Gmac_TxCh2Isr
156Gmac_TxCh3Isr
157Gmac_TxCh4Isr
158Gmac_TxCh5Isr
159Gmac_RxCh0Isr
160Gmac_RxCh1Isr
161Gmac_RxCh2Isr
162Gmac_RxCh3Isr
163Gmac_RxCh4Isr
164Gmac_RxCh5Isr
165Gmac_SbdIsr
166Gmac_PmtIsr
167Gmac_LpiIsr
LIN0168Lin0_Isr
LIN1169Lin1_Isr
LIN2170Lin2_Isr
SPI0171Spi0_Isr
SPI1172Spi1_Isr
SPI2173Spi2_Isr
SPI3174Spi3_Isr
SPI4175Spi4_Isr
SPI5176Spi5_Isr
IPC177Ipc_Ch0Isr
178Ipc_Ch1Isr
179Ipc_Ch2Isr
180Ipc_Ch3Isr
181Ipc_Ch4Isr
182Ipc_Ch5Isr
183Ipc_Ch6Isr
184Ipc_Ch7Isr
185Ipc_Ch8Isr
186Ipc_Ch9Isr
187Ipc_Ch10Isr
188Ipc_Ch11Isr
189Ipc_Ch12Isr
190Ipc_Ch13Isr
191Ipc_Ch14Isr
192Ipc_Ch15Isr
193Ipc_Ch16Isr
194Ipc_Ch17Isr
195Ipc_Ch18Isr
196Ipc_Ch19Isr
197Ipc_Ch20Isr
198Ipc_Ch21Isr
199Ipc_Ch22Isr
200Ipc_Ch23Isr
201Ipc_Ch24Isr
202Ipc_Ch25Isr
203Ipc_Ch26Isr
204Ipc_Ch27Isr
205Ipc_Ch28Isr
206Ipc_Ch29Isr
207Ipc_Ch30Isr
208Ipc_Ch31Isr
MDMA0209Mdma0_Ch0Isr
210Mdma0_Ch1Isr
MDMA1211Mdma1_Ch0Isr
212Mdma1_Ch1Isr
PDMA0213PDMA0_Ch0Isr
214PDMA0_Ch1Isr
215PDMA0_Ch2Isr
216PDMA0_Ch3Isr
217PDMA0_Ch4Isr
218PDMA0_Ch5Isr
PMC0219Pmc0_Isr
PMC1220Pmc1_Isr
PPS(TIME_SYNC0)222Pps_Icu0Isr
PPS(TIME_SYNC1)223Pps_Icu1Isr
PPS(TIME_SYNC2)224Pps_Icu2Isr
PPS_SYNC225Pps0_Isr
226Pps1_Isr
227Pps2_Isr
228Pps3_Isr
229Pps4_Isr
HSM_IPC0230Ipc_HsmIpc0Ch4Isr
231Ipc_HsmIpc0Ch5Isr
232Ipc_HsmIpc0Ch6Isr
233Ipc_HsmIpc0Ch7Isr
Reserved234
235
236
237
238
239
240
HSM_IPC1241Ipc_HsmIpc1Ch4Isr
242Ipc_HsmIpc1Ch5Isr
243Ipc_HsmIpc1Ch6Isr
244Ipc_HsmIpc1Ch7Isr
CPU_MP4_CMM245Cmm_Ins13Isr
CPU_MP4_CLUSTER_PMU246Pmu_ReqDeny1Isr
CPU_MP4_CDB_PMU247Pmu_ReqDeny2Isr
CPU_MP2_CMM248Cmm_Ins14Isr
CPU_MP2_CLUSTER_PMU249Pmu_ReqDeny3Isr
CPU_MP2_CDB_PMU250Pmu_ReqDeny4Isr
CPU_IPC1_CH0251Ipc_CpuIpc1Ch0Isr
CPU_IPC1_CH1252Ipc_CpuIpc1Ch1Isr
CPU_IPC1_CH2253Ipc_CpuIpc1Ch2Isr
CPU_IPC0_CH0254Ipc_CpuIpc0Ch0Isr
CPU_IPC0_CH1255Ipc_CpuIpc0Ch1Isr
CPU_IPC0_CH2256Ipc_CpuIpc0Ch2Isr
CPU_IPC0_CH3257Ipc_CpuIpc0Ch3Isr
CPU_IPC0_CH4258Ipc_CpuIpc0Ch4Isr
CPU_IPC0_CH5259Ipc_CpuIpc0Ch5Isr
CPU_IPC0_CH6260Ipc_CpuIpc0Ch6Isr
CPU_IPC0_CH7261Ipc_CpuIpc0Ch7Isr
CPU_IPC0_CH8262Ipc_CpuIpc0Ch8Isr
CPU_IPC0_CH9263Ipc_CpuIpc0Ch9Isr
CPU_IPC0_CH10264Ipc_CpuIpc0Ch10Isr
CPU_IPC0_CH11265Ipc_CpuIpc0Ch11Isr
CPU_IPC0_CH12266Ipc_CpuIpc0Ch12Isr
CPU_IPC0_CH13267Ipc_CpuIpc0Ch13Isr
CPU_IPC0_CH14268Ipc_CpuIpc0Ch14Isr
CPU_IPC0_CH15269Ipc_CpuIpc0Ch15Isr
CPU_ROUTER_SWTRIG1_0270Router_Swtrig1Ch0Isr
CPU_ROUTER_SWTRIG1_1271Router_Swtrig1Ch1Isr
CPU_ROUTER_SWTRIG1_2272Router_Swtrig1Ch2Isr
CPU_ROUTER_SWTRIG1_3273Router_Swtrig1Ch3Isr
DDR0_CMM291Cmm_Ins2Isr
DDR1_CMM294Cmm_Ins3Isr
DDR2_CMM297Cmm_Ins4Isr
PERI_I2C0300Peri_I2C0Isr
PERI_I2C1301Peri_I2C1Isr
PERI_I2C2302Peri_I2C2Isr
PERI_I2C3303Peri_I2C3Isr
PERI_I2C4304Peri_I2C4Isr
PERI_I2C5305Peri_I2C5Isr
PERI_USB306Peri_UsbIsr
PERI_CMM307Cmm_Ins19Isr
CAM_ISP0_0308Cam_Isp0Ch0Isr
CAM_ISP0_1309Cam_Isp0Ch1Isr
CAM_ISP0_2310Cam_Isp0Ch2Isr
CAM_ISP0_3311Cam_Isp0Ch3Isr
CAM_CPE0_PYM312Cam_Cpe0PymIsr
CAM_CPE0_MIPI_RX_CSI313Cam_Cpe0MipiRxCsiIsr
CAM_CPE0_CIM314Cam_Cpe0CimIsr
CAM_CPE0_PYM_PRE_UV315Cam_Cpe0PymPreUvIsr
CAM_CPE0_PYM_PRE_Y316Cam_Cpe0PymPreYIsr
CAM_CPE0_CMM317Cmm_Ins8Isr
CAM_ISP1_0318Cam_Isp1Ch0Isr
CAM_ISP1_1319Cam_Isp1Ch1Isr
CAM_ISP1_2320Cam_Isp1Ch2Isr
CAM_ISP1_3321Cam_Isp1Ch3Isr
CAM_CPE1_YNR322Cam_Cpe1YnrIsr
CAM_CPE1_PYM323Cam_Cpe1PymIsr
CAM_CPE1_MIPI_RX_CSI324Cam_Cpe1MipiRxCsiIsr
CAM_CPE1_CIM325Cam_Cpe1CimIsr
CAM_CPE1_PYM_PRE_UV326Cam_Cpe1PymPreUvIsr
CAM_CPE1_PYM_PRE_Y327Cam_Cpe1PymPreYIsr
CAM_CPE1_CMM328Cmm_Ins7Isr
CAM_STITCH329Cam_StichIsr
CAM_CPE_LITE_MIPI_RX330Cam_CpeLiteMipiRxCsiIsr
CAM_GDC0331Cam_Gdc0Isr
CAM_CPE_LITE_PYM332Cam_CpeLitePymIsr
CAM_CPE_LITE_PYM_PRE_UV333Cam_CpeLitePymPreUvIsr
CAM_CPE_LITE_PYM_PRE_Y334Cam_CpeLitePymPreYIsr
CAM_CPE_LITE_CIM335Cam_CpeLiteCymIsr
CAM_CPE_LITE_CMM336Cmm_Ins6Isr
CAM_MIPI_TX1_DSI337Cam_MipiTx1DsiIsr
CAM_MIPI_TX1_CSI2338Cam_MipiTx1Csi2Isr
CAM_MIPI_TX0_DSI339Cam_MipiTx0DsiIsr
CAM_MIPI_TX0_CSI2340Cam_MipiTx0Csi2Isr
CAM_IDU0341Cam_Idu0Isr
CAM_IDU1342Cam_Idu1Isr
CAM_IDE_CMM343Cmm_Ins5Isr
CAM_GPIO344Cam_GpioIsr
CAM_TOP_CMM345Cmm_Ins9Isr
VIDEO_VPU346Vid_VpuIsr
VIDEO_JPU347Vid_JpuIsr
VIDEO_CMM348Cmm_Ins10Isr
VIDEO_GIPO349Vid_GpioIsr
VDSP_CMM350Cmm_Ins11Isr
VDSP_Q8_EARLY_REST351Vdsp_EarlyRestIsr
VDSP_Q8_REST352Vdsp_ResetIsr
HSIS_CMM353Cmm_Ins12Isr
BPU_VM0354Bpu_Vm0Isr
BPU_VM1355Bpu_Vm1Isr
BPU_HYP356Bpu_HypIsr
BPU_PVT357Pvt_BpuAlarmIsr
BPU_CMM358Cmm_Ins17Isr
GPU_CMM359Cmm_Ins18Isr
RTC360Rtc_Isr
AON_WAKEUP_GPIO361Aon_WakeUpGpioIsr
AON_GPIO362Aon_GpioIsr
AON_PMU_REQ_MOD363Aon_PmuReqModIsr
MEDIA_BOT_CMM364Cmm_Ins15Isr
MEDIA_TOP_CMM366Cmm_Ins16Isr
CMN_CMM368Cmm_Ins20Isr
CMN_PVTC369Pvt_CmnAlarmIsr
CMN_PPU_PMU370Pmu_Ppu0Isr

MCU Interrupt Usage

Since MCU0 and MCU1 reside in the same hardware domain, both MCU0 and MCU1 receive the same interrupt when it occurs. Therefore, to ensure proper operation of the MCU system, each interrupt must be enabled exclusively on either MCU0 or MCU1. However, as MCU0 is not open-source externally, it is necessary to summarize the interrupts already used by MCU0 to prevent conflicts during customer development on MCU1.

Currently used interrupts on MCU0:

ModuleInterrupt NumberName
GPIO068Gpio_Icu0ExtIsr
GPIO169Gpio_Icu1ExtIsr
GPIO270Gpio_Icu2ExtIsr
WWDT071Wdg_Ins0RstIsr
WWDT072Wdg_Ins0IntIsr
WWDT173Wdg_Ins1RstIsr
WWDT174Wdg_Ins1IntIsr
WWDT275Wdg_Ins2RstIsr
WWDT276Wdg_Ins2IntIsr
GPT081Gpt_Ins0Ch2Isr
GPT183Gpt_Ins1Ch0Isr
GPT184Gpt_Ins1Ch1Isr
L1FCHM106Fchm_MissionIntIsr
107Fchm_NcfIntIsr
108Fchm_CfIntIsr
PWM0111Pwm_Generic0Isr
MDMA1211Mdma1_Ch0Isr
PDMA0213PDMA0_Ch0Isr
PPS(RTC)221Pps_IcuRtcIsr
HSM_IPC1241Ipc_HsmIpc1Ch4Isr
HSM_IPC1242Ipc_HsmIpc1Ch5Isr
CPU_IPC1_CH0251Ipc_CpuIpc1Ch0Isr
CPU_IPC1_CH1252Ipc_CpuIpc1Ch1Isr
CPU_IPC1_CH2253Ipc_CpuIpc1Ch2Isr
CPU_IPC0_CH8262Ipc_CpuIpc0Ch8Isr
CPU_IPC0_CH9263Ipc_CpuIpc0Ch9Isr
CPU_IPC0_CH10264Ipc_CpuIpc0Ch10Isr
CPU_IPC0_CH11265Ipc_CpuIpc0Ch11Isr
CPU_IPC0_CH12266Ipc_CpuIpc0Ch12Isr
CPU_IPC0_CH13267Ipc_CpuIpc0Ch13Isr
CPU_IPC0_CH14268Ipc_CpuIpc0Ch14Isr
CPU_IPC0_CH15269Ipc_CpuIpc0Ch15Isr
CPU_ROUTER_SWTRIG1_0270Router_Swtrig1Ch0Isr
CPU_ROUTER_SWTRIG1_1271Router_Swtrig1Ch1Isr
CPU_ROUTER_SWTRIG1_2272Router_Swtrig1Ch2Isr
CPU_ROUTER_SWTRIG1_3273Router_Swtrig1Ch3Isr
RTC360Rtc_Isr

Guide to Adding Compilation Directories

Brief Introduction to SCons

Currently, the RDK-S100 MCU only supports building for s100_sip_B, and uses SCons instead of Makefile for compilation.

SCons works similarly to Makefile: each directory contains an SConscript file (analogous to a Makefile), and a top-level SConstruct file controls the overall build process.
For example, the MCU1 image is controlled by SConstruct_Lite_FRtos_S100_sip_B.

Steps to Add a Compilation Directory

  1. Modify the file mcu/Build/FreeRtos_mcu1/SConstruct_Lite_FRtos_S100_sip_B to add or remove corresponding modules.

    For instance, to add the mcu/Service/Log directory, simply add its path accordingly. The variable False indicates that source files will not be copied to the build output directory during the build process.

  1. Add an SConscript file in the newly added module directory. This SConscript file can be copied from any existing compiled module directory.

Introduction to MCU FreeRTOS System

The MCU system includes several key functionalities, as illustrated below:

The diagram shows the relative task priorities of each function and the calling sequence within the same task. When integrating, customers must maintain the relative priorities, assigned core, and calling order within each task. Descriptions and important notes for each function are provided below:

Power

ScmiProcess: Place in a high-priority task; it is recommended to run within a 2ms task. If this cannot be achieved, ensure the maximum scheduling period does not exceed 100ms. Placing it in a task with a long scheduling period will negatively impact boot time. The approximate impact can be estimated as:
"Number of SCMI communications during boot × task period".

SysPower_State_Loop: Place in a low-priority task.

Boot

AcoreBootProc: Place in a low-priority task. This function includes necessary initializations for Acore boot-up, including initialization of the critical Housekeeping feature Housekeeping_WriteMagicNum. If this function is not properly initialized, Acore accesses to MCU registers will cause Acore exceptions.

Integration Note: This must be handled on MCU0. AcoreBoot requires flash access, so flash resource conflicts must be avoided. It should be placed in the same low-priority task as the OTA functionality described below.

OTA

OtaFlash_MainFunction: Place in a low-priority task, as it involves OTA-related processing logic.

Integration Note: This must be handled on MCU0. The OTA feature requires flash, IPC, and crypto functionalities. To avoid conflicts caused by concurrent flash operations, it is recommended to place all flash-related operations into a single low-priority task for serialized access. For example, the previously mentioned AcoreBootProc runs in the same low-priority task.

Sleep/Wake-up

SysPower_McuCoreEnterLowPower: Place this function in the highest-priority task with the shortest possible cycle supported by this core.

Integration Note: This function only executes when sleep/wake-up is required; otherwise, it exits quickly without introducing additional overhead.

System Interrupt Description

Communication between the MCU and Acore/HSM relies on IPC. For details about interrupts used by the IPC system service, refer to the section: IPC Introduction.
It is recommended to configure the priority of these interrupts higher than regular functional interrupts. These interrupts can be assigned the same priority level.

Introduction to FreeRTOS System

There are two mainstream startup approaches for FreeRTOS:

  1. In the main function, perform hardware initialization, RTOS system initialization, and create all tasks before finally starting the RTOS scheduler to begin multitasking.
  2. In the main function, initialize hardware and the RTOS system first, then create a single startup task and start the scheduler. Within this startup task, create all application tasks. Once all tasks are successfully created, the startup task deletes itself.

Neither approach is inherently superior; RDK-S100 adopts the first method.

FreeRTOS Task Creation

Task creation is located in /mcu/Target/Target-hobot-lite-freertos-mcu1/target/FreeRtosOsHal/Task_Hal.c. Example:

  • xxx_Startup task: Handles startup initialization and executes only once.
  • FreeRtos_OsTask_SysCore_BSW_xms and FreeRtos_OsTask_SysCore_ASW_xms: Periodic tasks scheduled according to their respective xms intervals. These tasks also perform internal processing; for details, refer to the previous section "Introduction to MCU FreeRTOS System".

If customers develop their own code, they can refer to the examples above. Alternatively, they can implement their demo logic within existing tasks (see below).
Task functions are defined in /mcu/Target/Target-hobot-lite-freertos-mcu1/target/HorizonTask.c.
Taking OsTask_SysCore_BSW_10ms as an example, this task periodically checks for Shell transaction processing:

TASK(OsTask_SysCore_BSW_10ms)
{
#ifdef SHELL_ENABLE
Shell_Handler();
#endif
}

FreeRTOS Interrupt Usage

FreeRTOS interrupt handling is centralized in /mcu/Target/Target-hobot-lite-freertos/target/FreeRtosOsHal/Isr_Hal.c:

void FreeRtos_Irq_Init(void)
{
int interrupt_index = 0;
for(; interrupt_index < INTERRUPT_MCU_MAX_NUM; interrupt_index++)
{
if((!Interrupt_McuConfigs[interrupt_index].irqNumber) && (!Interrupt_McuConfigs[interrupt_index].priority)
&& (!Interrupt_McuConfigs[interrupt_index].Handler) && (!Interrupt_McuConfigs[interrupt_index].enable_flag))
{
break;
}

if(Interrupt_McuConfigs[interrupt_index].Handler)
{
INT_SYS_InstallHandler(Interrupt_McuConfigs[interrupt_index].irqNumber, Interrupt_McuConfigs[interrupt_index].Handler, NULL);
}

if(Interrupt_McuConfigs[interrupt_index].priority)
{
INT_SYS_SetPriority(Interrupt_McuConfigs[interrupt_index].irqNumber, Interrupt_McuConfigs[interrupt_index].priority);
}

if(Interrupt_McuConfigs[interrupt_index].enable_flag)
{
INT_SYS_EnableIRQ(Interrupt_McuConfigs[interrupt_index].irqNumber);
}
}
}

If no interrupt handler is configured, the default interrupt handler is used (see /mcu/Target/Target-hobot-lite-freertos-mcu1/target/SuperSoC_ISR.s).
For example, the RTC interrupt handler:

// DefaultISR---default interrupt handler
.align 4
.weak DefaultISR
.type DefaultISR, %function
DefaultISR:
hlt #0
b .
.pool
.size DefaultISR, . - DefaultISR

/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.set \handler_name, DefaultISR
.endm

// Set default RTC interrupt handler
def_irq_handler AON_RTC_INTR

Note:
When enabling interrupts on MCU1, ensure that the corresponding interrupts on MCU0 are disabled!!!

Introduction to FreeRTOS Memory Management Scheme

FreeRTOS memory management schemes are located in /mcu/OpenSource/FreeRTOS/portable/MemMang/, offering five memory management algorithms: heap_1.c, heap_2.c, heap_3.c, heap_4.c, and heap_5.c. The FreeRTOS memory management module optimizes memory utilization and efficiency through memory allocation and deallocation operations, while minimizing memory fragmentation.

heap_1.c

heap_1.c is the simplest memory management scheme provided by FreeRTOS. It supports memory allocation but not deallocation. This is ideal for safety-critical embedded systems, as the inability to free memory prevents fragmentation and potential system crashes. However, its drawback is low memory utilization—once allocated, memory cannot be reclaimed even if used only once.

heap_2.c

heap_2.c uses a best-fit algorithm. For example, if 100 bytes are requested and available memory blocks are 200, 500, and 1000 bytes, the 200-byte block is split, and the remaining portion is returned to the free list. This scheme supports deallocation and reinserts freed memory into the list sorted by size. However, it cannot coalesce adjacent free blocks, leading to fragmentation when allocation sizes vary. (In contrast, heap_4.c solves this by merging adjacent blocks.)

heap_3.c

heap_3.c simply wraps the standard C library’s malloc() and free() functions, ensuring compatibility with common compilers. These wrapped functions are made thread-safe by suspending the scheduler before memory operations and resuming it afterward.

heap_4.c

Like heap_2.c, heap_4.c uses a best-fit algorithm but also includes a coalescing mechanism to merge adjacent free blocks, reducing fragmentation. It is especially suitable for port layers that directly use pvPortMalloc() and vPortFree(). Unlike heap_2.c, its free block list is sorted by memory address (lower addresses first) to facilitate efficient merging during deallocation.

heap_5.c

heap_5.c uses the same best-fit and coalescing algorithms as heap_4.c but supports memory heaps spanning multiple non-contiguous memory regions (e.g., internal RAM and external SDRAM). This scheme is more complex and slightly less real-time efficient than heap_4.c.

RDK-S100 Memory Scheme

RDK-S100 uses heap_4.c, which combines best-fit allocation and coalescing. It supports allocation and deallocation of arbitrary-sized memory blocks, minimizes fragmentation, covers all real-time system scenarios, and offers good real-time performance.

LOG Area Adjustment

MCU1 Area Adjustment

Modify the relevant section in /mcu/Build/FreeRtos_mcu1/Linker/gcc/S100.ld. The size cannot be changed for now.

Acore Area Adjustment

Modify the corresponding section in /source/hobot-drivers/kernel-dts/drobot-s100-soc.dtsi, keeping it consistent with the MCU1 modification.

Reserved Shared Memory Region Between MCU and Acore

This shared memory region is allocated within the MCU0 address space. However, since both MCU0 and MCU1 belong to the same MCU SRAM domain, MCU1 can also access this address range:

MCU_STATE_Reserved      : org = 0x0C800400, len = 1K

Currently Occupied Regions:

MCU1_VERSION:  org = 0x0C800400, len = 0x60
MCU_ALIVE: org = 0x0C800460, len = 0x10
---MCU0_ALIVE: org = 0x0C800460, len = 0x04;
---MCU1_ALIVE: org = 0x0C800464, len = 0x04;
---REVERSED: org = 0x0C800468, len = 0x08;

Usage Notes

When using shared memory for data transfer, a synchronization issue may arise: MCU updates data in SRAM, but Acore still reads stale data from its cache.

To prevent data inconsistency between Acore and MCU, prepend variables with volatile or use the ioremap_np() function. Both methods ensure direct reads from SRAM instead of cached values.