建立工程,成功创建两个虚拟串口
This commit is contained in:
248
source/main/mbox_ipcc.c
Normal file
248
source/main/mbox_ipcc.c
Normal file
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file mbox_ipcc.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides code for the configuration
|
||||
* of the mailbox_ipcc_if.c MiddleWare.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Channel direction and usage:
|
||||
*
|
||||
* ======== <-- new msg ---=============--------<------ =======
|
||||
* || || || CHANNEL 1 || || ||
|
||||
* || A7 || ------->-------=============--- buf free--> || M4 ||
|
||||
* || || || ||
|
||||
* ||master|| <-- buf free---=============--------<------ ||slave||
|
||||
* || || || CHANNEL 2 || || ||
|
||||
* ======== ------->-------=============----new msg --> =======
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "openamp/open_amp.h"
|
||||
#include "stm32mp1xx_hal.h"
|
||||
#include "openamp_conf.h"
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Define */
|
||||
|
||||
/* USER CODE END Define */
|
||||
|
||||
#define MASTER_CPU_ID 0
|
||||
#define REMOTE_CPU_ID 1
|
||||
#define IPCC_CPU_A7 MASTER_CPU_ID
|
||||
#define IPCC_CPU_M4 REMOTE_CPU_ID
|
||||
|
||||
#define RX_NO_MSG 0
|
||||
#define RX_NEW_MSG 1
|
||||
#define RX_BUF_FREE 2
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
extern IPCC_HandleTypeDef hipcc;
|
||||
int msg_received_ch1 = RX_NO_MSG;
|
||||
int msg_received_ch2 = RX_NO_MSG;
|
||||
uint32_t vring0_id = 0; /* used for channel 1 */
|
||||
uint32_t vring1_id = 1; /* used for channel 2 */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
void IPCC_channel1_callback(IPCC_HandleTypeDef * hipcc, uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir);
|
||||
void IPCC_channel2_callback(IPCC_HandleTypeDef * hipcc, uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize MAILBOX with IPCC peripheral
|
||||
* @param None
|
||||
* @retval : Operation result
|
||||
*/
|
||||
int MAILBOX_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN PRE_MAILBOX_INIT */
|
||||
|
||||
/* USER CODE END PRE_MAILBOX_INIT */
|
||||
|
||||
if (HAL_IPCC_ActivateNotification(&hipcc, IPCC_CHANNEL_1, IPCC_CHANNEL_DIR_RX,
|
||||
IPCC_channel1_callback) != HAL_OK) {
|
||||
OPENAMP_log_err("%s: ch_1 RX fail\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (HAL_IPCC_ActivateNotification(&hipcc, IPCC_CHANNEL_2, IPCC_CHANNEL_DIR_RX,
|
||||
IPCC_channel2_callback) != HAL_OK) {
|
||||
OPENAMP_log_err("%s: ch_2 RX fail\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* USER CODE BEGIN POST_MAILBOX_INIT */
|
||||
|
||||
/* USER CODE END POST_MAILBOX_INIT */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize MAILBOX with IPCC peripheral
|
||||
* @param virtio device
|
||||
* @retval : Operation result
|
||||
*/
|
||||
int MAILBOX_Poll(struct virtio_device *vdev)
|
||||
{
|
||||
/* If we got an interrupt, ask for the corresponding virtqueue processing */
|
||||
int ret = -1;
|
||||
|
||||
/* USER CODE BEGIN PRE_MAILBOX_POLL */
|
||||
|
||||
/* USER CODE END PRE_MAILBOX_POLL */
|
||||
|
||||
if (msg_received_ch1 == RX_BUF_FREE) {
|
||||
|
||||
/* USER CODE BEGIN MSG_CHANNEL1 */
|
||||
|
||||
/* USER CODE END MSG_CHANNEL1 */
|
||||
|
||||
OPENAMP_log_dbg("Running virt0 (ch_1 buf free)\r\n");
|
||||
rproc_virtio_notified(vdev, VRING0_ID);
|
||||
msg_received_ch1 = RX_NO_MSG;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (msg_received_ch2 == RX_NEW_MSG) {
|
||||
|
||||
/* USER CODE BEGIN MSG_CHANNEL2 */
|
||||
|
||||
/* USER CODE END MSG_CHANNEL2 */
|
||||
|
||||
OPENAMP_log_dbg("Running virt1 (ch_2 new msg)\r\n");
|
||||
rproc_virtio_notified(vdev, VRING1_ID);
|
||||
msg_received_ch2 = RX_NO_MSG;
|
||||
|
||||
/* The OpenAMP framework does not notify for free buf: do it here */
|
||||
rproc_virtio_notified(NULL, VRING1_ID);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN POST_MAILBOX_POLL */
|
||||
|
||||
/* USER CODE END POST_MAILBOX_POLL */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Callback function called by OpenAMP MW to notify message processing
|
||||
* @param VRING id
|
||||
* @retval Operation result
|
||||
*/
|
||||
int MAILBOX_Notify(void *priv, uint32_t id)
|
||||
{
|
||||
uint32_t channel;
|
||||
(void)priv;
|
||||
|
||||
/* USER CODE BEGIN PRE_MAILBOX_NOTIFY */
|
||||
|
||||
/* USER CODE END PRE_MAILBOX_NOTIFY */
|
||||
|
||||
/* Called after virtqueue processing: time to inform the remote */
|
||||
if (id == VRING0_ID) {
|
||||
channel = IPCC_CHANNEL_1;
|
||||
OPENAMP_log_dbg("Send msg on ch_1\r\n");
|
||||
}
|
||||
else if (id == VRING1_ID) {
|
||||
/* Note: the OpenAMP framework never notifies this */
|
||||
channel = IPCC_CHANNEL_2;
|
||||
OPENAMP_log_dbg("Send 'buff free' on ch_2\r\n");
|
||||
}
|
||||
else {
|
||||
OPENAMP_log_err("invalid vring (%d)\r\n", (int)id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check that the channel is free (otherwise wait until it is) */
|
||||
if (HAL_IPCC_GetChannelStatus(&hipcc, channel, IPCC_CHANNEL_DIR_TX) == IPCC_CHANNEL_STATUS_OCCUPIED) {
|
||||
OPENAMP_log_dbg("Waiting for channel to be freed\r\n");
|
||||
while (HAL_IPCC_GetChannelStatus(&hipcc, channel, IPCC_CHANNEL_DIR_TX) == IPCC_CHANNEL_STATUS_OCCUPIED)
|
||||
;
|
||||
}
|
||||
|
||||
/* Inform A7 (either new message, or buf free) */
|
||||
HAL_IPCC_NotifyCPU(&hipcc, channel, IPCC_CHANNEL_DIR_TX);
|
||||
|
||||
/* USER CODE BEGIN POST_MAILBOX_NOTIFY */
|
||||
|
||||
/* USER CODE END POST_MAILBOX_NOTIFY */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Private function ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
/* Callback from IPCC Interrupt Handler: Master Processor informs that there are some free buffers */
|
||||
void IPCC_channel1_callback(IPCC_HandleTypeDef * hipcc,
|
||||
uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN PRE_MAILBOX_CHANNEL1_CALLBACK */
|
||||
|
||||
/* USER CODE END PRE_MAILBOX_CHANNEL1_CALLBACK */
|
||||
|
||||
if (msg_received_ch1 != RX_NO_MSG)
|
||||
OPENAMP_log_dbg("IPCC_channel1_callback: previous IRQ not treated (status = %d)\r\n", msg_received_ch1);
|
||||
|
||||
msg_received_ch1 = RX_BUF_FREE;
|
||||
|
||||
/* Inform A7 that we have received the 'buff free' msg */
|
||||
OPENAMP_log_dbg("Ack 'buff free' message on ch1\r\n");
|
||||
HAL_IPCC_NotifyCPU(hipcc, ChannelIndex, IPCC_CHANNEL_DIR_RX);
|
||||
|
||||
/* USER CODE BEGIN POST_MAILBOX_CHANNEL1_CALLBACK */
|
||||
|
||||
/* USER CODE END POST_MAILBOX_CHANNEL1_CALLBACK */
|
||||
}
|
||||
|
||||
/* Callback from IPCC Interrupt Handler: new message received from Master Processor */
|
||||
void IPCC_channel2_callback(IPCC_HandleTypeDef * hipcc,
|
||||
uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN PRE_MAILBOX_CHANNEL2_CALLBACK */
|
||||
|
||||
/* USER CODE END PRE_MAILBOX_CHANNEL2_CALLBACK */
|
||||
|
||||
if (msg_received_ch2 != RX_NO_MSG)
|
||||
OPENAMP_log_dbg("IPCC_channel2_callback: previous IRQ not treated (status = %d)\r\n", msg_received_ch2);
|
||||
|
||||
msg_received_ch2 = RX_NEW_MSG;
|
||||
|
||||
/* Inform A7 that we have received the new msg */
|
||||
OPENAMP_log_dbg("Ack new message on ch2\r\n");
|
||||
HAL_IPCC_NotifyCPU(hipcc, ChannelIndex, IPCC_CHANNEL_DIR_RX);
|
||||
|
||||
/* USER CODE BEGIN POST_MAILBOX_CHANNEL2_CALLBACK */
|
||||
|
||||
/* USER CODE END POST_MAILBOX_CHANNEL2_CALLBACK */
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
Reference in New Issue
Block a user