今天是学习STM32MP157C的8第三天,研究在STM32CubeIDE 下如何开发M4的应用程序.
IDE和MX的切换
双击击项目最后的.ioc 文件,出现CubeMX的窗口。 保存这个文件,自动产生程序,并回到IDE.
定义GPIO端口
由于GPIO 可以在两个处理器上定义,因此,需要对着引脚击右键,设置Pin Reservied 选择M4.否则,相应的GPIO 代码不出现。
我在程序中定义了开发板的红灯和蓝灯,他们分别是
PA13 -LED_RED
PA14 - LED_BLUE
openAMP
openAMP 是一个中间件,它的低层是IPCC 所以要现将System Core 中的PICC 参数中打钩的地方全部打钩。然后在中间件目录下打开openAMP 。和米尔文档中的例子不同。下面的程序已经包含在openAMP 中间件中了。
mbox_ipcc.copenamp,copenamp.log,cres_table.cUART
UART 是从UART4 开始的。大概前面三个都分配给了A7了吧?我想使用UART4 输出M4 的Printf 信息。不知道是否会冲突?
fw_cortex_m4.sh
这个文件自动产生了,包含在RemoteProc目录中。
我建立了一个test项目,并参照了OpenAMP_TTY_echo 项目中的主程序,修改了我的主程序。
main.c
/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * <h2><center>© Copyright (c) 2020 STMicroelectronics. * All rights reserved.</center></h2> * * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "openamp.h" #include "virt_uart.h" #include "openamp_log.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ #define MAX_BUFFER_SIZE RPMSG_BUFFER_SIZE /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ IPCC_HandleTypeDef hipcc; /* USER CODE BEGIN PV */ VIRT_UART_HandleTypeDef huart0; VIRT_UART_HandleTypeDef huart1; __IO FlagStatus VirtUart0RxMsg = RESET; uint8_t VirtUart0ChannelBuffRx[MAX_BUFFER_SIZE]; uint16_t VirtUart0ChannelRxSize = 0; __IO FlagStatus VirtUart1RxMsg = RESET; uint8_t VirtUart1ChannelBuffRx[MAX_BUFFER_SIZE]; uint16_t VirtUart1ChannelRxSize = 0; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_IPCC_Init(void); int MX_OPENAMP_Init(int RPMsgRole, rpmsg_ns_bind_cb ns_bind_cb); /* USER CODE BEGIN PFP */ void VIRT_UART0_RxCpltCallback(VIRT_UART_HandleTypeDef *huart); void VIRT_UART1_RxCpltCallback(VIRT_UART_HandleTypeDef *huart); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ if(IS_ENGINEERING_BOOT_MODE()) { /* Configure the system clock */ SystemClock_Config(); } /* IPCC initialisation */ MX_IPCC_Init(); /* OpenAmp initialisation ---------------------------------*/ MX_OPENAMP_Init(RPMSG_REMOTE, NULL); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); /* USER CODE BEGIN 2 */ log_info("Virtual UART0 OpenAMP-rpmsg channel creation\r\n"); if (VIRT_UART_Init(&huart0) != VIRT_UART_OK) { log_err("VIRT_UART_Init UART0 failed.\r\n"); Error_Handler(); } log_info("Virtual UART1 OpenAMP-rpmsg channel creation\r\n"); if (VIRT_UART_Init(&huart1) != VIRT_UART_OK) { log_err("VIRT_UART_Init UART1 failed.\r\n"); Error_Handler(); } /*Need to register callback for message reception by channels*/ if(VIRT_UART_RegisterCallback(&huart0, VIRT_UART_RXCPLT_CB_ID, VIRT_UART0_RxCpltCallback) != VIRT_UART_OK) { Error_Handler(); } if(VIRT_UART_RegisterCallback(&huart1, VIRT_UART_RXCPLT_CB_ID, VIRT_UART1_RxCpltCallback) != VIRT_UART_OK) { Error_Handler(); } /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { OPENAMP_check_for_message(); /* USER CODE END WHILE */ if (VirtUart0RxMsg) { VirtUart0RxMsg = RESET; VIRT_UART_Transmit(&huart0, VirtUart0ChannelBuffRx, VirtUart0ChannelRxSize); } if (VirtUart1RxMsg) { VirtUart1RxMsg = RESET; VIRT_UART_Transmit(&huart1, VirtUart1ChannelBuffRx, VirtUart1ChannelRxSize); } // HAL_GPIO_WritePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin, GPIO_PIN_SET); // HAL_Delay(1000); // HAL_GPIO_WritePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin, GPIO_PIN_RESET); // HAL_Delay(1000); /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = 16; RCC_OscInitStruct.HSIDivValue = RCC_HSI_DIV1; RCC_OscInitStruct.LSIState = RCC_LSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.PLL4.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** RCC Clock Config */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_ACLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 |RCC_CLOCKTYPE_PCLK3|RCC_CLOCKTYPE_PCLK4 |RCC_CLOCKTYPE_PCLK5; RCC_ClkInitStruct.AXISSInit.AXI_Clock = RCC_AXISSOURCE_HSI; RCC_ClkInitStruct.AXISSInit.AXI_Div = RCC_AXI_DIV1; RCC_ClkInitStruct.MCUInit.MCU_Clock = RCC_MCUSSOURCE_HSI; RCC_ClkInitStruct.MCUInit.MCU_Div = RCC_MCU_DIV1; RCC_ClkInitStruct.APB4_Div = RCC_APB4_DIV1; RCC_ClkInitStruct.APB5_Div = RCC_APB5_DIV1; RCC_ClkInitStruct.APB1_Div = RCC_APB1_DIV1; RCC_ClkInitStruct.APB2_Div = RCC_APB2_DIV1; RCC_ClkInitStruct.APB3_Div = RCC_APB3_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct) != HAL_OK) { Error_Handler(); } } /** * @brief IPCC Initialization Function * @param None * @retval None */ static void MX_IPCC_Init(void) { /* USER CODE BEGIN IPCC_Init 0 */ /* USER CODE END IPCC_Init 0 */ /* USER CODE BEGIN IPCC_Init 1 */ /* USER CODE END IPCC_Init 1 */ hipcc.Instance = IPCC; if (HAL_IPCC_Init(&hipcc) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN IPCC_Init 2 */ /* USER CODE END IPCC_Init 2 */ } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pins : LED_BLUE_Pin LED_RED_Pin */ GPIO_InitStruct.Pin = LED_BLUE_Pin|LED_RED_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } /* USER CODE BEGIN 4 */ void VIRT_UART0_RxCpltCallback(VIRT_UART_HandleTypeDef *huart) { log_info("Msg received on VIRTUAL UART0 channel: %s \n\r", (char *) huart->pRxBuffPtr); /* copy received msg in a variable to sent it back to master processor in main infinite loop*/ VirtUart0ChannelRxSize = huart->RxXferSize < MAX_BUFFER_SIZE? huart->RxXferSize : MAX_BUFFER_SIZE-1; memcpy(VirtUart0ChannelBuffRx, huart->pRxBuffPtr, VirtUart0ChannelRxSize); VirtUart0RxMsg = SET; } void VIRT_UART1_RxCpltCallback(VIRT_UART_HandleTypeDef *huart) { log_info("Msg received on VIRTUAL UART1 channel: %s \n\r", (char *) huart->pRxBuffPtr); /* copy received msg in a variable to sent it back to master processor in main infinite loop*/ VirtUart1ChannelRxSize = huart->RxXferSize < MAX_BUFFER_SIZE? huart->RxXferSize : MAX_BUFFER_SIZE-1; memcpy(VirtUart1ChannelBuffRx, huart->pRxBuffPtr, VirtUart1ChannelRxSize); VirtUart1RxMsg = SET; } /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/测试方法与前一篇博文介绍差不多。
这次直接在workspace 中建立了lib 文件夹,在lib 下面建立了firmware 文件夹 将fw_cortex_cortex_m4.sh 传送到workspace
scp fw_cortex_m4.sh root@192.168.31.194://home/root/workspace fw_cortex_m4.sh 100% 541 0.5KB/s 00:00将test_CM4.elf 传送到 lib/firmware 中
(base) yao@yao-dc:~/STM32CubeIDE/workspace_1.4.0/test/CM4/Release$ scp test_CM4.elf root@192.168.31.194:/home/root/workspace/lib/firmware test_CM4.elf 100% 217KB 216.7KB/s 00:00使用 ssh root@192.168.31.194 进入开发板linux
root@myir:~/workspace# ./fw_cortex_m4.sh start root@myir:~/workspace# stty -onlcr -echo -F /dev/ttyRPMSG0 root@myir:~/workspace# cat /dev/ttyRPMSG0 & root@myir:~/workspace# stty -onlcr -echo -F /dev/ttyRPMSG1 root@myir:~/workspace# cat /dev/ttyRPMSG1 & root@myir:~/workspace# echo "hello virtual UART0" >/dev/ttyRPMSG0 root@myir:~/workspace# hello virtual UART0 root@myir:~/workspace# echo "hello virtual UART1" >/dev/ttyRPMSG1 root@myir:~/workspace# hello virtual UART1同时可以看到开发板上的红灯闪烁,如果键入./fw_cortex_m4.sh stop 红灯停止,表示M4 固件停止运行。
晚上,编写了 A7/linux 端测试程序
#include <stdio.h> #include <iostream> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <cstring> // compiller $CC testAMP.cpp -o test -lstdc++ //source SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi using namespace std; const char* rxBuf="Hello M4"; char* txBuf; int main(void){ cout<< "openAMP test"<<endl; int fd = open("/dev/ttyRPMSG0", O_RDWR); int len=strlen(rxBuf); write(fd, rxBuf, len); txBuf=new char(len); read(fd,txBuf,len); string msg=txBuf; cout<<"msg from M4:"<<msg<<endl; return 0; }