TA的每日心情 | 慵懒 2022-10-25 08:55 |
---|
签到天数: 103 天 连续签到: 1 天 [LV.6]常住居民II
|
今天我来做一下LPC55S69的双核通讯实验,我们通过上面的分析已知通讯的关键就在是要mailbox寄存器。
闲话不多说,我们在官方的hello_world_cm33_core0及其匹配的hello_world_cm33_core1.上面修改。
我们定义core1程序一直在运行一个闪烁灯,而core0程序控制一个按键,按下按键可以打开或者关闭core1,并空闲状态不停输出"Hello world"。
先在core0的main函数文件页面修改:
先添加1个变量
//按键的初始化
while函数里面。查询:
- <blockquote><blockquote>if(0 == IS_BUTTON_PRESSED())
复制代码 core1c程序的修改:
main函数while:
- LED_GREEN_TOGGLE();
- delay();
复制代码 这里没有用到中断,仅简单看core0能否直观的控制core1.
编译下载调试:
串口输出(不知道怎么回事,调试双核时,虚拟串口无法正常输出,可能我哪边配置不对,仅调试台输出信息):
- Hello world!
- Hello world!
- Hello world!
- Hello world!
- Starting Secondary core.//开启
- The secondary core application has been started.
- Hello world!
- Hello world!
- Hello world!
- Hello world!
- Hello world!
- Stopping Secondary core.//关闭
- The secondary core application has been stopped.
- Hello world!
- Hello world!
- Hello world!
复制代码 CORE1打开时LED闪烁,关闭时LED保保持最后的状态不变。
至少证明通讯成功,下面用core0程序里的按键进行控制core1程序里的LED亮灭,需要使用中断:
这里定义发送1为开灯,发送2为关灯,发送接收得到数据不能为0,不然会被忽略。
在core0 mian函数页面添加变量:
- uint16_t Mail_DATA=0;//邮箱数据接收缓存
- uint8_t g_flg=0;//邮箱中断标志
- uint8_t led_flg=0;//led状态
复制代码 while里面:
- if(g_flg==1)
- {
- g_flg=0;
- printf("Core0 receve data is : %d",Mail_DATA);
- }
- else
- {
- //我们这添加控制核1打开的操作
- if(0 == IS_BUTTON_PRESSED())
- {
- while (0== IS_BUTTON_PRESSED())
- {
- }
- led_flg=1-led_flg;
- //printf("the led_flg is %d \r\n",led_flg);
- //发送数据不能为0,为0无效
- if(led_flg==1)
- {
- MAILBOX_SetValueBits(MAILBOX, kMAILBOX_CM33_Core1, 1);
- }
- else
- {
- MAILBOX_SetValueBits(MAILBOX, kMAILBOX_CM33_Core1, 2);
- }
- }
- LED_BLUE_TOGGLE();
- delay();
- }
复制代码 mailbox的中断,例程已写好在mcmgr_internal_core_api_lpc55s69.c里面,
我们直接修改下:
添加外部变量引用:
- extern uint16_t Mail_DATA;
- extern uint8_t g_flg;
复制代码 在中断程序里面修改,没有破坏之前的结构(发送接收得到数据不能为0,不然会被忽略):
- void MAILBOX_IRQHandler(void)
- {
- #if defined(FSL_FEATURE_MAILBOX_SIDE_A)
- mailbox_cpu_id_t cpu_id = kMAILBOX_CM33_Core0;
- #else
- mailbox_cpu_id_t cpu_id = kMAILBOX_CM33_Core1;
- #endif
- uint32_t data;
- uint16_t eventType;
- uint16_t eventData;
- data = MAILBOX_GetValue(MAILBOX, cpu_id);
- <font color="#ff0000"> Mail_DATA=data;</font>
- // To be MISRA compliant, return value needs to be checked even it could not never be 0
- if (0U != data)
- {
- <font color="#ff0000"> g_flg=1;</font>
- MAILBOX_ClearValueBits(MAILBOX, cpu_id, data);
- eventType = (uint16_t)(data >> 16u);
- eventData = (uint16_t)(data & 0x0000FFFFu);
- if (((mcmgr_event_type_t)eventType >= kMCMGR_RemoteCoreUpEvent) &&
- ((mcmgr_event_type_t)eventType < kMCMGR_EventTableLength))
- {
- if (MCMGR_eventTable[(mcmgr_event_type_t)eventType].callback != ((void *)0))
- {
- MCMGR_eventTable[(mcmgr_event_type_t)eventType].callback(
- eventData, MCMGR_eventTable[(mcmgr_event_type_t)eventType].callbackData);
- }
- }
- }
- }
复制代码 对core1函数进行修改:
main函数里面修改:
定义变量:
- uint16_t Mailbox_data=0;
- uint8_t g_flag=0,led_flag=0;
复制代码- if(g_flag==1)
- {
- g_flag=0;
- //printf("Core1 receiver data is : %d",Mailbox_data);
- led_flag=Mailbox_data;
- }
- else
- {
- if(led_flag==1)
- {
- LED_GREEN_ON();
- }
- else if(led_flag==2)
- {
- LED_GREEN_OFF();
- }
- }
复制代码 中断函数里面修改:
- <font color="#ff0000">extern uint16_t Mailbox_data;
- extern uint8_t g_flag;</font>
- void MAILBOX_IRQHandler(void)
- {
- #if defined(FSL_FEATURE_MAILBOX_SIDE_A)
- mailbox_cpu_id_t cpu_id = kMAILBOX_CM33_Core0;
- #else
- mailbox_cpu_id_t cpu_id = kMAILBOX_CM33_Core1;
- #endif
- uint32_t data;
- uint16_t eventType;
- uint16_t eventData;
- data = MAILBOX_GetValue(MAILBOX, cpu_id);
- <font color="#ff0000"> Mailbox_data=data;</font>
- //发送接收得到数据不能为0,不然会被忽略
- //To be MISRA compliant, return value needs to be checked even it could not never be 0
- if (0U != data)
- {
- <font color="#ff0000"> g_flag=1;</font>
- MAILBOX_ClearValueBits(MAILBOX, cpu_id, data);
- eventType = (uint16_t)(data >> 16u);
- eventData = (uint16_t)(data & 0x0000FFFFu);
- if (((mcmgr_event_type_t)eventType >= kMCMGR_RemoteCoreUpEvent) &&
- ((mcmgr_event_type_t)eventType < kMCMGR_EventTableLength))
- {
- if (MCMGR_eventTable[(mcmgr_event_type_t)eventType].callback != ((void *)0))
- {
- MCMGR_eventTable[(mcmgr_event_type_t)eventType].callback(
- eventData, MCMGR_eventTable[(mcmgr_event_type_t)eventType].callbackData);
- }
- }
- }
- }
复制代码
编译下载,现象如下:
例程比较简单,但是逻辑确实通用的,我们可以在这上面添加更多的外设控制。好了,双核通讯就到这了。
这里说个题外话,就是这个函数 就是core0里面的MCMGR_StartCore(kMCMGR_Core1, CORE1_BOOT_ADDRESS, 5, kMCMGR_Start_Synchronous);
其中还是很有意思的,kMCMGR_Start_Synchronous等待2个函数同步后再运行。展开MCMGR_StartCore函数:
- mcmgr_status_t MCMGR_StartCore(mcmgr_core_t coreNum, void *bootAddress, uint32_t startupData, mcmgr_start_mode_t mode)
- {
- mcmgr_status_t ret;
- if ((uint32_t)coreNum < g_mcmgrSystem.coreCount)
- {
- /* Pass the startupData - LSB first */
- s_mcmgrCoresContext[coreNum].startupData = startupData;
- /* the startup data is sent asynchronously */
- ret = mcmgr_start_core_internal(coreNum, bootAddress);
- if (ret == kStatus_MCMGR_Success)
- {
- if (mode == kMCMGR_Start_Synchronous)
- {
- /* Wait until the second core reads and confirms the startup data */
复制代码
上面那个函数一直在等待core1准备好的状态。而core1里面:
- do
- {
- status = MCMGR_GetStartupData(&startupData);
- } <font color="#ff0000">while (status != kStatus_MCMGR_Success);</font>
复制代码
在不停的查询当前状态,并刷新。我一开始想完全撇开mcmgr,但发现牵连还挺多就放弃了。哪位大佬能详细讲述一下mcmgr,包括新注册的建中断任务等。小弟感激不尽!
|
|