Skip to main content

MCU1开发指南

MCU中断号及模块对应关系

模块中断号名称
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(RTC)221Pps_IcuRtcIsr
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中断使用情况

由于MCU0和MCU1处于统一硬件域,所以当中断产生时,MCU0/MCU1都能接收到同一中断。因此为了保障MCU系统的正常运行,统一中断只能由MCU0或MCU1使能。但是又因为MCU0不对外开源,因此需要对MCU0使用的中断进行总结,避免MCU1客户开发过程中使用冲突。

目前MCU0已经使用的中断:

模块中断号名称
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

增加编译目录教程

scons简述

目前RDK-S100 mcu仅仅支持s100_sip_B的编译,并且采用的是scons编译方式取代了Makefile。 Scons跟Makefile类似,每个文件夹由Sconscript编译文件(类似于Makefile),最后有个总的SConstruct文件总体去控制编译。 如mcu1的镜像就是SConstruct_Lite_FRtos_S100_sip_B控制。

增加编译目录流程

  1. 修改mcu/Build/FreeRtos_mcu1/SConstruct_Lite_FRtos_S100_sip_B文件,增加/删除相应的模块。

    如增加mcu/Service/Log文件夹,只需增加相应的位置即可。变量False表示控制构建过程中不会将源文件复制到编译输出目录。

  1. 在添加编译的模块下,添加SConscript文件,SConscript文件可以从任意已经编译的模块文件夹下获取

MCU FreeRtos系统简介

MCU这边有几个系统关键功能,如下图所示:

上图可以看到各个功能所在任务的相对优先级及同一个任务中的调用顺序,客户集成请保持各功能的相对优先级、所在core及同一个任务中的调用顺序。各个功能的说明及注意事项如下:

Power

ScmiProcess:放在高优先级任务中,建议放在2ms任务中。如果不能满足,最大调度周期不要超过100ms。放在调度周期长的任务中会影响启动时间,一般评估影响可以按照启动过程中的"scmi通讯次数x所在任务周期"计算。

SysPower_State_Loop:放在低优先级任务中。

Boot

AcoreBootProc:放在低优先级任务中。这个里面会有Acore启动需要的相关初始化等。其中就有Housekeeping关键功能的初始化 Housekeeping_WriteMagicNum,如果该功能未被正常初始化,Acore对MCU的寄存器访问会导致Acore异常。

集成注意:需要放在MCU0上处理。AcoreBoot需要使用flash,需要避免flash冲突问题。和下文的OTA功能都放到同一个低优任务中处理。

OTA

OtaFlash_MainFunction:放在低优先级任务,涉及到OTA相关处理逻辑。

集成注意:需要放在MCU0上处理。OTA功能需要使用flash、IPC以及crypto功能。需要避免flash并发操作的冲突问题,建议将所有使用到flash相关的功能放到一个低优先级的task中串行使用。比如前文提到的AcoreBootProc就是和它在同一个低优任务中。

休眠唤醒

SysPower_McuCoreEnterLowPower:放在本core上能支持的最短周期最高优先级任务中。

集成注意:该函数只有在需要休眠唤醒时才会真正运行,其他时候都是快速退出不会产生额外耗时。

系统中断说明

MCU和Acore/HSM通信依赖IPC,IPC系统服务涉及到的中断可以参考:IPC的相关介绍 章节 这些中断优先级建议配置成比平常的功能类中断优先级高,这些中断本身可以配置成同样的优先级。

FreeRtos系统简介

FreeRTOS的主流的启动方式有两种:第一种,在main函数中将硬件初始化,RTOS系统初始化,所有任务的创建这些都弄好,最后启动RTOS的调度器,开始多任务的调度;第二种,在main函数中将硬件和RTOS系统先初始化好,然后创建一个启动任务后就启动调度器,在启动任务里面创建各种应用任务,当所有任务都创建成功后,启动任务把自己删除。两种方式没有太强的优劣之分,RDK-S100选择第一种方式。

FreeRtos系统任务创建

任务创建位于/mcu/Target/Target-hobot-lite-freertos-mcu1/target/FreeRtosOsHal/Task_Hal.c中,举例如下:

xxx_Startup任务,为启动初始化相关的函数,只执行一次。 FreeRtos_OsTask_SysCore_BSW_xms和FreeRtos_OsTask_SysCore_ASW_xms为周期性任务,会根据xms的不同产生周期性的调度。同时周期性任务内部会有工作处理,细节见本章上一节"MCU FreeRtos系统简介"章节。

如果客户自行开发,可参考上述两种类型的例子。也可以在已经创建的任务中处理自己的demo,见下文。 任务函数位于/mcu/Target/Target-hobot-lite-freertos-mcu1/target/HorizonTask.c文件中, 以OsTask_SysCore_BSW_5ms为例,任务会周期性地检测Can事务处理:

TASK(OsTask_SysCore_BSW_5ms)
{
hb_CAN2IPC_MainFunction();
Hb_Ipc2Can_MainFunction();
if (Eth_Test == 1) {
EthTest_Mainfunc();
Eth_Receive(0, 0, &ethRxStat);
}
}

FreeRtos系统中断使用

FreeRtos的中断使用集中在/mcu/Target/Target-hobot-lite-freertos/target/FreeRtosOsHal/Isr_Hal.c文件中,

void FreeRtos_Irq_Init(void)
{
FreeRtosInstallHandler(); // 中断处理函数设置
Isr_SetPriority(); // 中断优先级设置
Isr_Enable(); // 中断使能
}

如果没有设置中断处理函数,那么中断处理函数处于默认状态,见/mcu/Target/Target-hobot-lite-freertos-mcu1/target/SuperSoC_ISR.s文件。 以RTC中断处理函数为例:

// DefaultISR---默认中断处理函数
.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

// 设置RTC默认中断处理函数
def_irq_handler AON_RTC_INTR

注意: 在MCU1使能中断的时候一定要确保MCU0相应的中断处于关闭状态!!!

FreeRtos内存管理方案简介

FreeRtos内存管理方案位于/mcu/OpenSource/FreeRTOS/portable/MemMang/文件夹中,共有5 种内存管理算法,分别是heap_1.c、heap_2.c、heap_3.c、heap_4.c和heap_5.c。FreeRTOS 的内存管理模块通过对内存的申请、释放操作,来管理用户和系统对内存的使用,使内存的利用率和使用效率达到最优,同时最大限度地解决系统可能产生的内存碎片问题。

heap_1.c

heap_1.c 管理方案是 FreeRTOS 提供所有内存管理方案中最简单的一个,它只能申请内存而不能进行内存释放,这样子对于要求安全的嵌入式设备来说是最好的,因为不允许内存释放,就不会产生内存碎片而导致系统崩溃,但是也有缺点,那就是内存利用率不高,某段内存只能用于内存申请的地方,即使该内存只使用一次,也无法让系统回收重新利用。

heap_2.c

heap_2.c方案与heap_1.c方案采用的内存管理算法不一样,它采用一种最佳匹配算法(best fit algorithm),比如我们申请100字节的内存,而可申请内存中有三块对应大小200字节,500字节和1000字节大小的内存块,按照算法的最佳匹配,这时候系统会把200字节大小的内存块进行分割并返回申请内存的起始地址,剩余的内存则插回链表留待下次申请。Heap_2.c方案支持释放申请的内存,将释放的内存重新插入链表,并按照大小进行排序,但是它不能把相邻的两个小的内存块合成一个大的内存块,对于每次申请内存大小都比较固定的,这个方式是没有问题的,而对于每次申请并不是固定内存大小的则会造成内存碎片,后面要讲解的heap_4.c方案采用的内存管理算法能解决内存碎片的问题,可以把这些释放的相邻的小的内存块合并成一个大的内存块。

heap_3.c

heap_3.c方案只是简单的封装了标准C库中的malloc()和free()函数,并且能满足常用的编译器。重新封装后的malloc()和free()函数具有保护功能,采用的封装方式是操作内存前挂起调度器、完成后再恢复调度器。

heap_4.c

heap_4.c方案与heap_2.c方案一样都采用最佳匹配算法来实现动态的内存分配,但是不一样的是heap_4.c方案还包含了一种合并算法,能把相邻的空闲的内存块合并成一个更大的块,这样可以减少内存碎片。heap_4.c方案特别适用于移植层中可以直接使用pvPortMalloc()和vPortFree()函数来分配和释放内存的代码。heap_4.c内存管理方案的空闲块链表不是以内存块大小进行排序的,而是以内存块起始地址大小排序,内存地址小的在前,地址大的在后,因为heap_4.c 方案还有一个内存合并算法,在释放内存的时候,假如相邻的两个空闲内存块在地址上是连续的,那么就可以合并为一个内存块,这也是为了适应合并算法而作的改变。

heap_5.c

heap_5.c 方案在实现动态内存分配时与 heap4.c 方案一样,采用最佳匹配算法和合并算法,并且允许内存堆跨越多个非连续的内存区,也就是允许在不连续的内存堆中实现内存分配,比如用户在片内RAM中定义一个内存堆,还可以在外部SDRAM再定义一个或多个内存堆,这些内存都归系统管理。该方案较为复杂,实时性略逊于heap_4.c。

RDK-S100内存方案

RDK-S100采用的是heap_4.c方案,该方案结合最佳匹配算法和合并算法,可以分配和释放随机字节内存,在避免内存碎片的同时覆盖实时系统内存分配的全场景,并且实时性较好。

LOG区域调整

MCU1区域调整

修改/mcu/Build/FreeRtos_mcu1/Linker/gcc/S100.ld文件中相应位置,大小暂不支持修改

Acore区域调整

修改/source/hobot-drivers/kernel-dts/drobot-s100-soc.dtsi文件中相应位置,与MCU1修改保持一致

MCU与Acore共享内存区域预留

该共享内存区域空间开辟在MCU0所在空间,但MCU0和MCU1同属于MCU SRAM域,因此MCU1也可以使用相应地址

MCU_STATE_Reserved      : org = 0x0C800400, len = 1K

目前已经被占用的区域:

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

使用注意事项

如果使用共享内存的方式传输数据,可能会出现MCU数据更新至SRAM,但是Acore的缓存还为旧数据的问题,因此导致读取数据不同步。

为避免Acore和MCU出现数据不同步的问题,需要在变量前加"volatile"或者"ioremap_np()函数"。这两种方式都是为了避免读取缓存,而是直接读取SRAM数据。