查看: 3737|回复: 0

[原创] 【LPC54114双核任务二】之一:纯寄存器操作双核通讯

[复制链接]
  • TA的每日心情
    开心
    2017-7-10 09:04
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    7

    主题

    69

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    342
    最后登录
    2020-7-29
    发表于 2017-7-2 23:00:44 | 显示全部楼层 |阅读模式
    本帖最后由 baicaiaichibaicai 于 2017-7-3 09:33 编辑

    官方和万利都提供了库,但是我已习惯用纯寄存器的方式开发程序,所以我打算用纯寄存器的方式开发LPC54114开发板。双核的代码都是放在flash上,可以将m0的bin文件当作一个数组存放在m4的程序中,我的做法如下
    1. 创建m0工程,设置flash地址为 0x00020000~0x00040000,ram地址为 0x20010000~0x20020000,同时在"Option for target"的Asm中定义宏NO_CRP。
    2. 增加编译完转换成bin文件 “$K\ARM\ARMCC\bin\fromelf.exe --bincombined --bincombined_base=0x00020000 --output ../../m4f/code/m0Image.bin !L”
    TIM截图20170703091128.png
    3. 创建m4工程,设置flash地址为0x00000000~0x00020000,ram地址为0x20000000~0x20010000,同时增加 incm0.s文件如下
    1.                 AREA |.ARM.__AT_0x00020000|,CODE,READONLY,ALIGN=3
    2.                 INCBIN m0Image.bin
    3.                 END
    复制代码
    将m0镜像放在0x00020000的位置,注意此地址要与生成bin文件是的参数--bincombined_base=0x00020000 一致,否则会导致m0的链接与运行地址不一致。
    编写简单的例程。
    m0+
    1. #include <stdio.h>
    2. #include <string.h>
    3. #include <stdlib.h>

    4. #include "chip.h"

    5. int main(void){

    6.     int i,cnt;

    7.     cnt = 0xFFFFFFFF;
    8.     while(cnt--){
    9.         i = 0xFFFFFF;while(i--);
    10.         sprintf((void *)0x04000000,"0x%08x",cnt);
    11.         LPC_MBOX->BOX[1].IRQ = 1;
    12.     }
    13.     return 0;
    14. }
    复制代码
    M4
    1. #include <stdio.h>
    2. #include <string.h>
    3. #include <stdlib.h>

    4. #include "chip.h"

    5. LPC_USART_T * usart0 = (LPC_USART_T *)(LPC_FLEXCOMM0_BASE);

    6. #pragma import(__use_no_semihosting_swi)
    7. struct __FILE {
    8.     /* Whatever you require here. If the only file you are using is */
    9.     /* standard output using printf() for debugging, no file handling */
    10.     /* is required. */
    11.     int handle;
    12. };

    13. void _ttywrch(void){

    14. }
    15.    
    16. int _sys_open(const char *name, int openmode){
    17.     return 0;  
    18. }

    19. int _sys_exit(int x){

    20.     x = x;
    21.     return 0;
    22. }

    23. int fputc(int ch, FILE *f){

    24.     while(0 == (usart0->FIFOSTAT & (1 << 5)));
    25.     usart0->FIFOWR = ch;
    26.     return ch;
    27. }

    28. void MAILBOX_IRQHandler(){

    29.     LPC_MBOX->BOX[1].IRQCLR = 0xFFFFFFFF;
    30.     printf("%s\r\n",(unsigned char *)0x04000000);
    31.     return;
    32. }

    33. int main(void){

    34.     unsigned int run = 1;

    35.     LPC_SYSCON->FROCTRL = (1 << 14) | (1 << 30) | (1UL << 31);  // enable fro_hf to 96M
    36.     LPC_SYSCON->MAINCLKSELA = 3;    // select main clock A to fro_hf
    37.     LPC_SYSCON->MAINCLKSELB = 0;    // select main clock A as input source of main clock clock B

    38.     LPC_SYSCON->FXCOMCLKSEL[0] = 0; // select fro_12m as clock of flexcomm0
    39.     LPC_SYSCON->AHBCLKCTRL[1] |= (1 << 11); // enable clock of flexcomm0
    40.     LPC_SYSCON->PRESETCTRL[1] |= (1 << 11); // reset flexcomm0
    41.     LPC_SYSCON->PRESETCTRL[1] &= ~(1 << 11); // un-reset flexcomm0
    42.     *((volatile unsigned int *)(LPC_FLEXCOMM0_BASE + 0xFF8)) = (1 << 0) | (1 << 3);   // set flexcomm0 as UART and lock it
    43.     LPC_SYSCON->AHBCLKCTRL[0] |= (1 << 13); // enable clock of IOCON
    44.     LPC_IOCON->PIO[0][0] = (1 << 0) | (1 << 7) | (1 << 9);  // set pin0.0
    45.     LPC_IOCON->PIO[0][1] = (1 << 0) | (1 << 7) | (1 << 9);  // set pin0.1
    46.     usart0->CTL = (0 << 6); // enable uart0 tx
    47.     usart0->FIFOCFG = (1 << 0); // enable tx FIFO
    48.     usart0->OSR = 13;   // set oversample
    49.     usart0->BRG = 8;    //8 == (12000000/(115200*13));
    50.     usart0->CFG = (1 << 0) | (1 << 2);  // 8b none 1b stop,enable

    51.     LPC_SYSCON->AHBCLKCTRL[0] |= (1 << 26); // enable clock of MBOX
    52.     NVIC_EnableIRQ(MAILBOX_IRQn);   // enable mbox irq

    53.     LPC_SYSCON->CPCTRL |= (0xC0C40000 | (1 << 3) | (1 << 5));   //enable CM0 clock and reset it
    54.     LPC_SYSCON->CPBOOT = *((unsigned int *)0x00020004); // set CM0 enter address
    55.     LPC_SYSCON->CPSTACK = *((unsigned int *)0x00020000);    // set CM0 stack pointer
    56.     LPC_SYSCON->CPCTRL = 0xC0C40000 | (LPC_SYSCON->CPCTRL & (~(1 << 5)));    //un-reset CM0

    57.     while(run);
    58.     return 0;
    59. }
    复制代码
    LPC54114的双核使用中断,对LPC_MBOX->BOX[coreNumber].IRQ写任意值即可触发该核的中断,要传输数据给另外一个核时,只要对该核的IRQ寄存器进行写操作即可。另还提供一个硬件互斥锁LPC_MBOX->MUTEX(本例子没用到)

    PS1: CM0的代码我是没有拷贝到RAM中,优点是节省RAM,缺点是执行效率低下,因为两个核心都要通过总线去访问flash。
    PS2: 中断里不应该放打印的,这里只是例程,就比较随意了。




    lpc54114 dual-core.rar

    674.06 KB, 下载次数: 14, 下载积分: 威望 1

    工程及源码

    该会员没有填写今日想说内容.
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-8-31 06:35 , Processed in 0.074285 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表