【NXP OKdo E1双核Cortex M33开发板】+LPC55S69双核通讯实验
今天我来做一下LPC55S69的双核通讯实验,我们通过上面的分析已知通讯的关键就在是要mailbox寄存器。闲话不多说,我们在官方的hello_world_cm33_core0及其匹配的hello_world_cm33_core1.上面修改。
我们定义core1程序一直在运行一个闪烁灯,而core0程序控制一个按键,按下按键可以打开或者关闭core1,并空闲状态不停输出"Hello world"。
先在core0的main函数文件页面修改:
先添加1个变量
//按键的初始化
...
uint8_t led_flg=0;
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.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,包括新注册的建中断任务等。小弟感激不尽!
页:
[1]