TA的每日心情 | 慵懒 2024-7-12 21:42 |
---|
签到天数: 229 天 连续签到: 1 天 [LV.7]常住居民III
|
本帖最后由 az158 于 2020-11-10 22:56 编辑
LPC55S69这个芯片最吸引人的无疑是它的双核部分,而NXP作为在双核MCU领域沉浸多年老厂商,这一款很新的芯片的双核部分已经非常成熟,下面我们以提供的一个双核实例,在keil5 ARM的开发环境进行分析。
首先编译core1的代码。
然后对core0的代码进行一些修改,因为这个板子上没有外部晶振,所以要将clock_config.c文件里面的BOARD_InitBootClocks函数修改如下。
- void BOARD_InitBootClocks(void)
- {
- BOARD_BootClockFROHF96M();
- }
复制代码
运行后串口打印如下,之后一段时间后蓝灯开始闪烁。
其中串口打印是由core0实现,蓝灯闪烁是由core1实现。接下来我们来对这个双核的启动流程简要分析一下。
首先是core1的部分,下图可以看出,它输出了一个名为core1_image.bin的文件
接下来是core0的部分,先看incbin.S,关键代码如下- AREA M0CODE, DATA, READONLY, PREINIT_ARRAY, ALIGN=3
- EXPORT m0_image_start
- EXPORT m0_image_end
- m0_image_start
- INCBIN core1_image.bin
- m0_image_end
- END
复制代码
可以看到这里定义了一个段名为M0CODE的数据段,只读,8字节对齐。
然后在这个数据段里面放入了core1编译输出的core1_image.bin文件,起始标记是m0_image_start,结尾标记是m0_image_end。
接下来要看LPC55S69_cm33_core0_flash.scf文件,关键代码如下- #define m_core1_image_start 0x00072000
- #define m_core1_image_size 0x00026000
- ......
- LR_CORE1_IMAGE m_core1_image_start {
- CORE1_REGION m_core1_image_start m_core1_image_size {
- * (.m0code)
- }
- }
复制代码
这里是定义了一个区域,起始地址为0x00072000,长度为0x00026000(keil rom空间为0-0x98000,也就是最后一段)
然后将m0code这个段放到这个地址上,也就是把core1_image.bin这个文件放到了0x00072000地址上。
这里的地址是可以进行修改的,也就是可以根据代码的配置选择core1程序的存储位置,根据代码量删减,或者将core1生成的bin文件混淆到最终生成的文件里面,让别人很难进行逆向分析。
最后看一下hello_world_core0.c文件,关键代码如下- #define CORE1_BOOT_ADDRESS 0x20033000
- extern uint32_t Image$CORE1_REGION$Base;
- extern uint32_t Image$CORE1_REGION$Length;
- #define CORE1_IMAGE_START &Image$CORE1_REGION$Base
- ......
- uint32_t get_core1_image_size(void)
- {
- uint32_t core1_image_size;
- core1_image_size = (uint32_t)&Image$CORE1_REGION$Length;
- return core1_image_size;
- }
- ......
- core1_image_size = get_core1_image_size();
- (void)memcpy((void *)(char *)CORE1_BOOT_ADDRESS, (void *)CORE1_IMAGE_START, core1_image_size);
- (void)MCMGR_StartCore(kMCMGR_Core1, (void *)(char *)CORE1_BOOT_ADDRESS, 2, kMCMGR_Start_Synchronous);
复制代码
首先是get_core1_image_size函数,&Image$$CORE1_REGION$$Length是用来得到CORE1_REGION区域的大小,也就是core1_image.bin文件的大小。而Image$$CORE1_REGION$$Base则是CORE1_REGION区域的起点。
下面就是把从CORE1_IMAGE_START开始的core1_image_size的数据复制到CORE1_BOOT_ADDRESS地址上。也就是把代码从rom里面搬到了ram里面。
最后就是将core1从CORE1_BOOT_ADDRESS地址同步启动。
简要总结一下,LPC55S69代码由两部分组成,以core0为主,core0启动起来之后,将core1的代码从rom复制到ram里面,然后再启动core1。其中core1代码在rom以及在ram里面的位置都是可以任意配置,非常灵活。
|
|