STM32单片机示例:双核单片机点灯与调试(STM32H7x5 & H7x7)
文章目录
前言
现在多核的单片机越来越多了,这里试试看STM32的双核单片机。
目前来说STM32双核的单片机有 STM32H7x5 & STM32H7x7
这两个系列(无线系列的产品也有双核的,只不过一个核是单独跑官方的无线部分固件的)。
我这里使用官方的 NUCLEO-H755ZI-Q
开发板进行测试:
基础说明
STM32H7x5 & STM32H7x7
双核单片机基本的架构、资源分类、和应用示例在下面官方文档中有介绍:
《AN5557 – STM32H745/755 and STM32H747/757 lines dual-core architecture》
STM32H7x5 & STM32H7x7
的双核都是非对称的,一个核是M7、一个核是M4,两个核有自己的电源域、可访问的资源和外设,也有一些可以公共访问的资源和外设。
默认情况下两个核启动参数如下:
The boot address is provided by option byte and default programmed value to allow:
• CM7 Boots from Flash memory at 0x0800 0000 when Boot0=0
• CM4 Boots from Flash memory at 0x0810 0000 when Boot0=0
• Boot respectively from System memory or SRAM1 when Boot0=1
STM32H7x5 & STM32H7x7
是带硬件信号量的,可以用来进行双核间(或者单核内)的同步/异步交互。官方也提供了一些例程:
另外 Github 上也有例程可以参考:
STM32H7 dual-core inter-CPU communication
使用STM32CubeMX生成程序
在 STM32CubeMX
中 STM32H7x5 & H7x7
单片机的各个外设会显示或者可以选择由哪个核处理,本文主要配置如下:
默认生成的代码其实就是一个大工程包含两个小工程,然后有一些公共代码。每个核心有自己的 main
函数。
其中 CM4
核心的代码大致如下:
int main(void){
/* USER CODE BEGIN Boot_Mode_Sequence_1 */
/*HW semaphore Clock enable*/
__HAL_RCC_HSEM_CLK_ENABLE();
/* Activate HSEM notification for Cortex-M4*/
// 启用硬件信号量中断
HAL_HSEM_ActivateNotification(__HAL_HSEM_SEMID_TO_MASK(HSEM_ID_0));
/*
Domain D2 goes to STOP mode (Cortex-M4 in deep-sleep) waiting for Cortex-M7 to
perform system initialization (system clock config, external memory configuration.. )
*/
HAL_PWREx_ClearPendingEvent();
// 设置D2域进入STOP模式(即停止CM4核工作)
HAL_PWREx_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFE, PWR_D2_DOMAIN);
/* Clear HSEM flag */
// 当硬件信号量中断时会继续从这里工作,清除相关标志
__HAL_HSEM_CLEAR_FLAG(__HAL_HSEM_SEMID_TO_MASK(HSEM_ID_0));
/* USER CODE END Boot_Mode_Sequence_1 */
HAL_Init();
MX_GPIO_Init();
while (1){ }
}
CM7
核心的代码大致如下:
int main(void)
{
int32_t timeout;
MPU_Config();
/* USER CODE BEGIN Boot_Mode_Sequence_1 */
/* Wait until CPU2 boots and enters in stop mode or timeout*/
timeout = 0xFFFF;
// 等待CM4核停止工作
while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) != RESET) && (timeout-- > 0));
if ( timeout < 0 ){
Error_Handler();
}
/* USER CODE END Boot_Mode_Sequence_1 */
HAL_Init();
SystemClock_Config();
/* USER CODE BEGIN Boot_Mode_Sequence_2 */
/* When system initialization is finished, Cortex-M7 will release Cortex-M4 by means of
HSEM notification */
/*HW semaphore Clock enable*/
__HAL_RCC_HSEM_CLK_ENABLE();
/*Take HSEM */
// 获取硬件信号量
HAL_HSEM_FastTake(HSEM_ID_0);
/*Release HSEM in order to notify the CPU2(CM4)*/
// 释放硬件信号量,这将会触发中断(用来唤醒CM4核)
HAL_HSEM_Release(HSEM_ID_0,0);
/* wait until CPU2 wakes up from stop mode */
timeout = 0xFFFF;
// 等待CM4核开始工作
while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) == RESET) && (timeout-- > 0));
if ( timeout < 0 ){
Error_Handler();
}
/* USER CODE END Boot_Mode_Sequence_2 */
MX_GPIO_Init();
while (1){ }
}
上面默认生成的代码主要就是实现了两个核心同步的功能。
使用STM32CubeIDE双核调试
调试主要参考下面官方文档:
《LAT1396 – STM32CubeIDE实用技巧之STM32H7双核调试的配置》
《AN5286 – STM32H7x5/x7 dual-core microcontroller debugging》
首先需要手动新建CM4的调试配置:
选择调试的项目:
注意不要下载,会在下面CM7中配置下载:
这里重点需要关注下面的三项红线,前面那个端口号应该没影响(没验证):
接下来需要新建CM7的调试配置:
CM4的固件在CM7的调试配置中下载:
最后新建Launch Group包含两个项目:
初次启动调试在Launch Group中启动:
以后可以在工具栏启动:
下面是总体调试配置:
下面是调试演示:
调试时需要先启动CM4的程序,然后再启动CM7的程序。CM4的程序启动后会进入STOP模式无法追踪, 启动CM7后可以再次启动CM4程序 进入正常调试。CM4和CM7是独立的程序,可以分别打断点。停止调试时需要分别停止。
其它补充
默认程序配置下或者程序配置错误情况下容易出现 ST-Link 连不上芯片的情况,可以尝试拉高BOOT0,然后按住复位按键,再上电,松开复位键(应该LD3红灯会亮),这时可以通过 ST-Link 连上芯片,可以使用STM32CubeProgrammer软件擦除芯片固件或者调整选项字节。
例程地址
https://github.com/NaisuXu/STM32H7_Dual_Core_Debug_Demo
作者:Naisu Xu