本帖最后由 guo8113 于 2015-4-12 22:16 编辑
今晚基于LPC54xxx LPCXpresso中的DualCore例子,稍加修改,在万利的板子上顺利跑通。附件为工程。
做了一年左右的TMS320DM8168异构多核(ARM cortex-A8+DSP+M3+M3),发现cortex系列的多核也就这个样子,相当于单芯片集成了两个MCU,共用一套外设,有个mailbox可以用核间中断传递32位数据,然后再加个mutex用于共享地址的互斥。相比于带MMU的异构多核应用要方便简单的多。
双核通信的机制有人在论坛介绍了,不再啰嗦。只写Keil写双核程序的步骤:AN11609资料也有讲。
1.建立M0+的工程,配置其ROM,RAM:
2.在“user”自定义编译等工具中使用以下命令,将生成的m0+的axf(arm可执行文件)文件转为C数组(这里采用双核烧写一个镜像的形式运行)。
fromelf --cadcombined --output="
\M0_image_array.c" "\CM0_RAM.axf”
3.编写m0+代码啦,
需要使用mailbox了,主要就是开中断,写中断响应函数。注意,mailbox模块只需要在一个核中进行初始化,一般先启动的核初始化mailbox,并为另一个核(m0+)设置程序入口,允许时钟,启动运行。
所以,在m0+中没有初始化mailbox。
- static void MAILBOX_mutexWait(void) {
- while (LPC_MAILBOX->MUTEX == 0) __NOP(); /* Wait forever for mutex */
- }
- static void MAILBOX_mutexRelease(void) {
- LPC_MAILBOX->MUTEX = 1; /* release mutex */
- }
- NVIC_EnableIRQ(MAILBOX_IRQn); /* Enable mailbox interrupt */
- ///////中断服务程序
- void MAILBOX_IRQHandler(void) {
- pledState = (uint32_t *)LPC_MAILBOX->IRQ0; /* get address of ledState */
- MAILBOX_mutexWait();
- // 对共享的地址处数据进行操作
- MAILBOX_mutexRelease();
- LPC_MAILBOX->IRQ0CLR = 0xFFFFFFFF; /* Clear own mailbox */
- LPC_MAILBOX->IRQ1SET = 1; /* Signal change to M4 */
- }
复制代码
4.编译,会将其可执行文件转为.c文件,这个文件是需要被m4核的程序包含进去的。
5.新建M4核的工程,包含m0+的执行文件转换成的.c文件。
6.编写M4程序
需要对mailbox进行初始化。
- static void MAILBOX_Initialize(void) {
- LPC_SYSCON->AHBCLKCTRL0 |= (1ul << 26); /* Enable clock for Mailbox */
- LPC_SYSCON->PRESETCTRLSET0 = (1ul << 26); /* assert reset for Mailbox */
- LPC_SYSCON->PRESETCTRLCLR0 = (1ul << 26); /* deassert reset for Mailbox */
- MAILBOX_mutexRelease();
- }
复制代码 然后同m0+核,对mailbox操作。
- NVIC_EnableIRQ(MAILBOX_IRQn); /* Enable mailbox interrupt */
复制代码
另外还要在M4中规定ROM,RAM地址,以及规定m0+链接时的地址,并启动m0+
规定M0+程序的地址:
- #define M0plus_IMAGE_START 0x20000 /* address where the M0+ Image is located in the flash */
- const __attribute__((at(M0plus_IMAGE_START)))
- #include "CM0plus_Image.c"
复制代码 启动M0+核:
- /* Boot M0+ core */
- /* Setup M0+ stack pointer and reset vector ( from M0+ flash image) */
- LPC_SYSCON->CPSTACK = (*(uint32_t *)(M0plus_IMAGE_START + 0));
- LPC_SYSCON->CPBOOT = (*(uint32_t *)(M0plus_IMAGE_START + 4));
- /* Enable M0+ clock and perform M0+ reset */
- LPC_SYSCON->CPUCTRL |= ((0xC0C4ul << 16) |
- ( 1ul << 3) ); /* enable M0+ clock */
- LPC_SYSCON->CPUCTRL |= ((0xC0C4ul << 16) |
- ( 1ul << 5) ); /* assert M0+ reset */
- LPC_SYSCON->CPUCTRL = ((0xC0C4ul << 16) |
- (LPC_SYSCON->CPUCTRL & ~(1ul << 5))); /* deassert M0+ reset */
复制代码
7.编译,烧写。完事。
ps:第一次发帖,如有遗漏,尽情谅解。