STM32H757 는 Cortex-M7 + Cortex-M4의 dual-core MCU로 STM32CubeIDE로 개발 가능하다.
기존 STM32와 뭔가 달라진것이 있나? 우선 CubeIDE로 STM32H757을선택하고 프로젝트를 생성하자.
기존 STM32H7과 비교하면 각 페리들을 어떤 코어에 할당 해서 사용할지를 선택할 수 있는 체크 박스가 있다.
가장 간단한 코드로 [STM32H747-RP] 보드의 PA4, PD6에 연결도어 있는 LED를 테스트 해보자.
PA4에 연결된 LED는 M4코어에 PD6에 연결된 LED는 M7코어로 할당해서 듀얼코어를 제어해 보자
MCU의 클럭은 코어별로 각각 최대 CPU1(M7)은 480Mhz, CPU2(M4)는 240Hhz로 설정할수 있다.
STM32CubeIDE로 기본 설정을 하고 코드를 생성하면 자동으로 코드가 생성되는데 기존 STM32H7과는 다르게 듀얼코어를 사용할수 있는 코드가 생성된다.
특이한점은 다른 듀얼코어 MCU와는 다르게 각각 코어에 대한 코드가 생성된다는것이다. 각 코어를 독립적으로 사용할 수 있기 때문에 기존 개발된 코드를 그대로 사용하고 필요할때 자원을 활용할 수 있는 장점이 있다. 물론 코드를 별도로 관리해야 하는 단점도 있을 수 있겠다.
#define Led2On() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, GPIO_PIN_SET)
#define Led2Off() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, GPIO_PIN_RESET)
#define Led2Toggle() HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_6)
int main(void)
{
/* USER CODE BEGIN 1 */
// 사용자 정의 초기화 코드 (필요 시 사용)
/* USER CODE END 1 */
/* USER CODE BEGIN Boot_Mode_Sequence_0 */
int32_t timeout; // 타임아웃을 위한 변수 선언
/* USER CODE END Boot_Mode_Sequence_0 */
/* USER CODE BEGIN Boot_Mode_Sequence_1 */
// CPU2(Cortex-M4)가 부팅되고 STOP 모드에 들어갈 때까지 대기 (또는 타임아웃)
timeout = 0xFFFF;
while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) != RESET) && (timeout-- > 0));
if ( timeout < 0 )
{
// 타임아웃 발생 시 에러 처리 함수 호출
Error_Handler();
}
/* USER CODE END Boot_Mode_Sequence_1 */
/* MCU 초기 설정 시작 --------------------------------------------------------*/
// 모든 주변장치 리셋, 플래시 인터페이스 및 Systick 초기화
HAL_Init();
/* USER CODE BEGIN Init */
// 사용자 정의 초기화 코드
/* USER CODE END Init */
// 시스템 클럭 설정
SystemClock_Config();
/* USER CODE BEGIN Boot_Mode_Sequence_2 */
// 시스템 초기화 완료 후 Cortex-M7이 HSEM(Hardware Semaphore)을 통해 Cortex-M4를 깨움
// HSEM 클럭 활성화
__HAL_RCC_HSEM_CLK_ENABLE();
// HSEM 획득
HAL_HSEM_FastTake(HSEM_ID_0);
// HSEM 해제: Cortex-M4(CPU2)에게 알림
HAL_HSEM_Release(HSEM_ID_0, 0);
// CPU2가 STOP 모드에서 깨어날 때까지 대기 (또는 타임아웃)
timeout = 0xFFFF;
while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) == RESET) && (timeout-- > 0));
if ( timeout < 0 )
{
// 타임아웃 발생 시 에러 처리
Error_Handler();
}
/* USER CODE END Boot_Mode_Sequence_2 */
/* USER CODE BEGIN SysInit */
// 추가적인 시스템 초기화 코드 (필요 시)
/* USER CODE END SysInit */
// 모든 설정된 주변장치 초기화
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
// 사용자 정의 설정 코드 (초기화 후)
/* USER CODE END 2 */
// 무한 루프 시작
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
Led2Toggle();
// 400ms 지연
HAL_Delay(400);
}
/* USER CODE END 3 */
}
PA4에 연결된 LED를 M4코어에 할당하고 LED제어 코들를 작성하면 각각 LED가 듀얼 코어에의해 제어 되는것을 확인 할 수 있다.
#define Led1On() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)
#define Led1Off() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET)
#define Led1Toggle() HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4)
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* 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();
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 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
//MX_LWIP_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
Led1Toggle();
HAL_Delay(1000);
}
/* USER CODE END 3 */
}
반응형