BL808学习日志-1-三核通讯

接上个博客,今天实验了一下BL808的IPC通讯,使用的是博流自己的SDK;参考手册上并没有说明各个寄存器,是通过网友的结论和自己的部分修改达成的。

一、实验代码

1.目前仅测试了LP内核和M0内核之间的通讯,使用SIPEED的M1S_Dock开发板,修改了\bouffalo_sdk\bsp\board\bl808dk\board.c文件,先将debug的管脚14 15分配给M0内核使用,方便打印M0内核的日志;

static void console_init()
{struct bflb_device_s *gpio;gpio = bflb_device_get_by_name("gpio");
#if defined(CPU_M0)bflb_gpio_uart_init(gpio, GPIO_PIN_14, GPIO_UART_FUNC_UART0_TX);bflb_gpio_uart_init(gpio, GPIO_PIN_15, GPIO_UART_FUNC_UART0_RX);
#elif defined(CPU_D0)/* sipeed m1s dock */bflb_gpio_init(gpio, GPIO_PIN_16, 21 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);bflb_gpio_init(gpio, GPIO_PIN_17, 21 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
#elif defined(CPU_LP)/* map GPIO_PIN_18 and GPIO_PIN_19 as UART for LP core */bflb_gpio_uart_init(gpio, GPIO_PIN_18, GPIO_UART_FUNC_UART1_TX);bflb_gpio_uart_init(gpio, GPIO_PIN_19, GPIO_UART_FUNC_UART1_RX);
#endifstruct bflb_uart_config_s cfg;cfg.baudrate = 2000000;cfg.data_bits = UART_DATA_BITS_8;cfg.stop_bits = UART_STOP_BITS_1;cfg.parity = UART_PARITY_NONE;cfg.flow_ctrl = 0;cfg.tx_fifo_threshold = 7;cfg.rx_fifo_threshold = 7;
#if defined(CPU_M0)uart0 = bflb_device_get_by_name("uart0");
#elif defined(CPU_D0)uart0 = bflb_device_get_by_name("uart3");
#elif defined(CPU_LP)uart0 = bflb_device_get_by_name("uart1");
#endifbflb_uart_init(uart0, &cfg);bflb_uart_set_console(uart0);
}

2.在bouffalo_sdk\examples\bl808_triplecore\helloworld_m0例程上进行修改,M0主函数中对中断寄存器进行了初始化,定义了中断回调函数;并在中断函数中输出IPC中断号;其中对LED灯进行了一个0.5Hz的闪烁,来提示系统进行了正常的IPC通讯。

#include "bflb_mtimer.h"
#include "board.h"
#include "bflb_gpio.h"
#include "bl808.h"
#include "ipc_reg.h"
#include "bl808_ipc.h"
#include "bl808_common.h"#define DBG_TAG "M0"
#include "log.h"struct bflb_device_s *gpio;
uint32_t value = 0;
void IPC_M0_IRQHandler(void)
{gpio = bflb_device_get_by_name("gpio");// Read Interrupt Statusuint32_t irqStatus = BL_RD_REG(IPC0_BASE, IPC_CPU0_IPC_IRSRR);//Interrupt handlebflb_gpio_set(gpio,GPIO_PIN_8);LOG_F("the irqStatus value is %d\r\n",irqStatus);value = 1;//Clear InterryptBL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_ICR, irqStatus);
}void m0_ipc_init(void)
{/* setup the IPC Interupt */bflb_irq_attach(IPC_M0_IRQn, IPC_M0_IRQHandler, NULL);BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_IUSR, 1 << 1);bflb_irq_enable(IPC_M0_IRQn);
}int main(void)
{board_init();m0_ipc_init();while (1) {if(value == 1){bflb_gpio_set(gpio,GPIO_PIN_8);bflb_mtimer_delay_ms(1000);bflb_gpio_reset(gpio,GPIO_PIN_8);LOG_F("hello world m0\r\n");LOG_E("hello world m0\r\n");LOG_W("hello world m0\r\n");LOG_I("hello world m0\r\n");LOG_D("hello world m0\r\n");LOG_T("hello world m0\r\n");}bflb_mtimer_delay_ms(1000);}}

将M0程序烧录到开发板中;

2.在bouffalo_sdk\examples\bl808_triplecore\helloworld_lp将LP板载外设初始化,然后打开开发板上的LED灯,使用IO8控制;默认上电拉低IO8,打开闪光灯;进入主循环之前,使能M0内核的IPC通道1;

#include "bflb_mtimer.h"
#include "board.h"
#include "bflb_gpio.h"
#include "bl808.h"
#include "ipc_reg.h"
#include "bl808_common.h"#define DBG_TAG "MAIN"
#include "log.h"
struct bflb_device_s *gpio;int main(void)
{board_init();gpio = bflb_device_get_by_name("gpio");bflb_gpio_init(gpio, GPIO_PIN_8, GPIO_OUTPUT | GPIO_FLOAT | GPIO_SMT_EN | GPIO_DRV_0);bflb_gpio_reset(gpio,GPIO_PIN_8);LOG_F("hello world lp\r\n");LOG_E("hello world lp\r\n");LOG_W("hello world lp\r\n");LOG_I("hello world lp\r\n");LOG_D("hello world lp\r\n");LOG_T("hello world lp\r\n");LOG_I("LPcore will comunity to M0 core");BL_WR_REG(IPC0_BASE, IPC_CPU1_IPC_ISWR, 1 << 1);while (1) {bflb_mtimer_delay_ms(1000);}
}

 将LP内核程序烧录到开发板中,会看到LED灯先是亮起,然后被M0主程序改为1秒闪烁1次;

3.若是想看debug日志,默认是查看M0内核的日志,可以把board.c文件中LP和M0的串口引脚对换。输出的LP内核的日志:

  ____               __  __      _       _       _|  _ \             / _|/ _|    | |     | |     | || |_) | ___  _   _| |_| |_ __ _| | ___ | | __ _| |__|  _ < / _ \| | | |  _|  _/ _` | |/ _ \| |/ _` | '_ \| |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) ||____/ \___/ \__,_|_| |_| \__,_|_|\___/|_|\__,_|_.__/Build:18:11:43,Oct  1 2023
Copyright (c) 2022 Bouffalolab team
lp does not use memheap due to little ram
sig1:ffff76ff
sig2:0000ffff
cgen1:9f7ffffd
[F][LP] hello world lp
[E][LP] hello world lp
[W][LP] hello world lp
[I][LP] hello world lp
[I][LP] LPcore will comunity to M0 core

4.输出的M0内核日志:

____               __  __      _       _       _|  _ \             / _|/ _|    | |     | |     | || |_) | ___  _   _| |_| |_ __ _| | ___ | | __ _| |__|  _ < / _ \| | | |  _|  _/ _` | |/ _ \| |/ _` | '_ \| |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) ||____/ \___/ \__,_|_| |_| \__,_|_|\___/|_|\__,_|_.__/Build:18:21:31,Oct  1 2023
Copyright (c) 2022 Bouffalolab team
======== flash cfg ========
flash size 0x01000000
jedec id     0xEF4018
mid              0xEF
iomode           0x04
clk delay        0x01
clk invert       0x01
read reg cmd0    0x05
read reg cmd1    0x35
write reg cmd0   0x01
write reg cmd1   0x31
qe write len     0x01
cread support    0x00
cread code       0xFF
burst wrap cmd   0x77
===========================
dynamic memory init success,heap size = 21 Kbyte
sig1:ffff32ff
sig2:0000ffff
[F][M0] the irqStatus value is 2
[F][M0] hello world m0
[E][M0] hello world m0

可以看到,M0日志显示"the irqSstatus value is 2",也就是通道1触发; 

4.随机试验了一下其他的通道,试验通道0能否正常触发,修改LP内核main.c文件的触发为

int main(void)
{board_init();gpio = bflb_device_get_by_name("gpio");bflb_gpio_init(gpio, GPIO_PIN_8, GPIO_OUTPUT | GPIO_FLOAT | GPIO_SMT_EN | GPIO_DRV_0);bflb_gpio_reset(gpio,GPIO_PIN_8);LOG_F("hello world lp\r\n");LOG_E("hello world lp\r\n");LOG_W("hello world lp\r\n");LOG_I("hello world lp\r\n");LOG_D("hello world lp\r\n");LOG_T("hello world lp\r\n");LOG_I("LPcore will comunity to M0 core");BL_WR_REG(IPC0_BASE, IPC_CPU1_IPC_ISWR, 1 << 0);while (1) {bflb_mtimer_delay_ms(1000);}
}

修改M0内核中main.c文件中的使能通道

void m0_ipc_init(void)
{/* setup the IPC Interupt */bflb_irq_attach(IPC_M0_IRQn, IPC_M0_IRQHandler, NULL);BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_IUSR, 1 << 0);bflb_irq_enable(IPC_M0_IRQn);
}

 编译烧录到开发板,发现M0内核的输出日志发生变化为"the irqSstatus value is 1",也就是通道0触发; 

____               __  __      _       _       _|  _ \             / _|/ _|    | |     | |     | || |_) | ___  _   _| |_| |_ __ _| | ___ | | __ _| |__|  _ < / _ \| | | |  _|  _/ _` | |/ _ \| |/ _` | '_ \| |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) ||____/ \___/ \__,_|_| |_| \__,_|_|\___/|_|\__,_|_.__/Build:18:21:31,Oct  1 2023
Copyright (c) 2022 Bouffalolab team
======== flash cfg ========
flash size 0x01000000
jedec id     0xEF4018
mid              0xEF
iomode           0x04
clk delay        0x01
clk invert       0x01
read reg cmd0    0x05
read reg cmd1    0x35
write reg cmd0   0x01
write reg cmd1   0x31
qe write len     0x01
cread support    0x00
cread code       0xFF
burst wrap cmd   0x77
===========================
dynamic memory init success,heap size = 21 Kbyte
sig1:ffff32ff
sig2:0000ffff
[F][M0] the irqStatus value is 1
[F][M0] hello world m0
[E][M0] hello world m0

二、SIPEED默认库IPC描述

SIPEED的默认M1S_BL808_SDK中对IPC和XRAM进行了更深层次的封装,也实现了XRAM的数据交互,包括bl808_ipc.c文件,其中XRAM是作为一个组件使用,封装的相当好,这里也是很不明白为什么博流自己的SDK却删掉了这部分的内容。贴个代码,应该就知道怎么使用了。

/** Copyright (c) 2020 Bouffalolab.** This file is part of*     *** Bouffalolab Software Dev Kit ****      (see www.bouffalolab.com).** Redistribution and use in source and binary forms, with or without modification,* are permitted provided that the following conditions are met:*   1. Redistributions of source code must retain the above copyright notice,*      this list of conditions and the following disclaimer.*   2. Redistributions in binary form must reproduce the above copyright notice,*      this list of conditions and the following disclaimer in the documentation*      and/or other materials provided with the distribution.*   3. Neither the name of Bouffalo Lab nor the names of its contributors*      may be used to endorse or promote products derived from this software*      without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/#include "bl808_ipc.h"/** @addtogroup  BL606P_Peripheral_Driver*  @{*//** @addtogroup  IPC*  @{*//** @defgroup  IPC_Private_Macros*  @{*/
#define IPC_LP_OFFSET_IN_M0 0
#define IPC_D0_OFFSET_IN_M0 16#define IPC_M0_OFFSET_IN_LP 0
#define IPC_D0_OFFSET_IN_LP 16#define IPC_M0_OFFSET_IN_D0 0
#define IPC_LP_OFFSET_IN_D0 16/*@} end of group IPC_Private_Macros *//** @defgroup  IPC_Private_Types*  @{*//*@} end of group IPC_Private_Types *//** @defgroup  IPC_Private_Variables*  @{*/ipcIntCallback *m0IpcIntCbfArra[GLB_CORE_ID_MAX - 1] = { NULL };
ipcIntCallback *lpIpcIntCbfArra[GLB_CORE_ID_MAX - 1] = { NULL };
ipcIntCallback *d0IpcIntCbfArra[GLB_CORE_ID_MAX - 1] = { NULL };/*@} end of group IPC_Private_Variables *//** @defgroup  IPC_Global_Variables*  @{*//*@} end of group IPC_Global_Variables *//** @defgroup  IPC_Private_Fun_Declaration*  @{*//*@} end of group IPC_Private_Fun_Declaration *//** @defgroup  IPC_Private_Functions*  @{*//*@} end of group IPC_Private_Functions *//** @defgroup  IPC_Public_Functions*  @{*/
#if defined(CPU_M0) || defined(CPU_LP)
/****************************************************************************/ /*** @brief  M0 IPC interrupt init** @param  onLPTriggerCallBack: Callback when LP trigger** @param  onD0TriggerCallBack: Callback when D0 trigger** @return None*
*******************************************************************************/
void IPC_M0_Init(ipcIntCallback *onLPTriggerCallBack,ipcIntCallback *onD0TriggerCallBack)
{m0IpcIntCbfArra[0] = onLPTriggerCallBack;m0IpcIntCbfArra[1] = onD0TriggerCallBack;IPC_M0_Int_Unmask_By_Word(0xffffffff);#ifndef BFLB_USE_HAL_DRIVERInterrupt_Handler_Register(IPC_M0_IRQn, IPC_M0_IRQHandler);
#endifCPU_Interrupt_Enable(IPC_M0_IRQn);
}
#endif/****************************************************************************/ /*** @brief  M0 unmask IPC interrupt** @param  src: M0 IPC interrupt source** @return None*
*******************************************************************************/
void IPC_M0_Int_Unmask(IPC_Int_Src_Type src)
{uint32_t tmpVal = 0;/* Check the parameters */CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));tmpVal = (1 << src);BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_IUSR, tmpVal);
}/****************************************************************************/ /*** @brief  M0 unmask IPC interrupt by word** @param  src: IPC interrupt source in word,every bit is interrupt source** @return None*
*******************************************************************************/
void IPC_M0_Int_Unmask_By_Word(uint32_t src)
{BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_IUSR, src);
}/****************************************************************************/ /*** @brief  M0 get IPC interrupt raw status** @param  None** @return IPC interrupt raw status*
*******************************************************************************/
uint32_t IPC_M0_Get_Int_Raw_Status(void)
{return BL_RD_REG(IPC0_BASE, IPC_CPU0_IPC_IRSRR);
}/****************************************************************************/ /*** @brief  M0 clear IPC interrupt** @param  src: M0 IPC interrupt source** @return None*
*******************************************************************************/
void IPC_M0_Clear_Int(IPC_Int_Src_Type src)
{uint32_t tmpVal = 0;/* Check the parameters */CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));tmpVal = (1 << src);BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_ICR, tmpVal);
}/****************************************************************************/ /*** @brief  M0 clear IPC interrupt by word** @param  src: IPC interrupt source in word,every bit is interrupt source** @return None*
*******************************************************************************/
void IPC_M0_Clear_Int_By_Word(uint32_t src)
{BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_ICR, src);
}/****************************************************************************/ /*** @brief  CPUx trigger IPC interrupt to M0** @param  src: IPC interrupt source* * @param  cpuxOffset: CPU interrupt offset** @return None*
*******************************************************************************/
void IPC_CPUx_Trigger_M0(IPC_Grp_Int_Src_Type src, uint8_t cpuxOffset)
{uint32_t tmpVal = 0;/* Check the parameters *///CHECK_PARAM(IS_IPC_Grp_Int_Src_Type(src));tmpVal = (1 << (src + cpuxOffset));BL_WR_REG(IPC0_BASE, IPC_CPU1_IPC_ISWR, tmpVal);
}/****************************************************************************/ /*** @brief  LP trigger IPC interrupt to M0** @param  src: LP IPC interrupt source** @return None*
*******************************************************************************/
void IPC_LP_Trigger_M0(IPC_Grp_Int_Src_Type src)
{IPC_CPUx_Trigger_M0(src, IPC_LP_OFFSET_IN_M0);
}/****************************************************************************/ /*** @brief  D0 trigger IPC interrupt to M0** @param  src: D0 IPC interrupt source** @return None*
*******************************************************************************/
void IPC_D0_Trigger_M0(IPC_Grp_Int_Src_Type src)
{IPC_CPUx_Trigger_M0(src, IPC_D0_OFFSET_IN_M0);
}#if defined(CPU_M0) || defined(CPU_LP)
/****************************************************************************/ /*** @brief  LP IPC interrupt init** @param  onM0TriggerCallBack: Callback when M0 trigger** @param  onD0TriggerCallBack: Callback when D0 trigger** @return None*
*******************************************************************************/
void IPC_LP_Init(ipcIntCallback *onM0TriggerCallBack,ipcIntCallback *onD0TriggerCallBack)
{lpIpcIntCbfArra[0] = onM0TriggerCallBack;lpIpcIntCbfArra[1] = onD0TriggerCallBack;IPC_LP_Int_Unmask_By_Word(0xffffffff);#ifndef BFLB_USE_HAL_DRIVERInterrupt_Handler_Register(IPC_LP_IRQn, IPC_LP_IRQHandler);
#endifCPU_Interrupt_Enable(IPC_LP_IRQn);
}
#endif/****************************************************************************/ /*** @brief  LP unmask IPC interrupt** @param  src: LP IPC interrupt source** @return None*
*******************************************************************************/
void IPC_LP_Int_Unmask(IPC_Int_Src_Type src)
{uint32_t tmpVal = 0;/* Check the parameters */CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));tmpVal = (1 << src);BL_WR_REG(IPC1_BASE, IPC_CPU0_IPC_IUSR, tmpVal);
}/****************************************************************************/ /*** @brief  LP unmask IPC interrupt by word** @param  src: IPC interrupt source in word,every bit is interrupt source** @return None*
*******************************************************************************/
void IPC_LP_Int_Unmask_By_Word(uint32_t src)
{BL_WR_REG(IPC1_BASE, IPC_CPU0_IPC_IUSR, src);
}/****************************************************************************/ /*** @brief  LP get IPC interrupt raw status** @param  None** @return IPC interrupt raw status*
*******************************************************************************/
uint32_t IPC_LP_Get_Int_Raw_Status(void)
{return BL_RD_REG(IPC1_BASE, IPC_CPU0_IPC_IRSRR);
}/****************************************************************************/ /*** @brief  LP clear IPC interrupt** @param  src: LP IPC interrupt source** @return None*
*******************************************************************************/
void IPC_LP_Clear_Int(IPC_Int_Src_Type src)
{uint32_t tmpVal = 0;/* Check the parameters */CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));tmpVal = (1 << src);BL_WR_REG(IPC1_BASE, IPC_CPU0_IPC_ICR, tmpVal);
}/****************************************************************************/ /*** @brief  LP clear IPC interrupt by word** @param  src: IPC interrupt source in word,every bit is interrupt source** @return None*
*******************************************************************************/
void IPC_LP_Clear_Int_By_Word(uint32_t src)
{BL_WR_REG(IPC1_BASE, IPC_CPU0_IPC_ICR, src);
}/****************************************************************************/ /*** @brief  CPUx trigger IPC interrupt to LP** @param  src: IPC interrupt source** @param  cpuxOffset: CPU interrupt offset** @return None*
*******************************************************************************/
void IPC_CPUx_Trigger_LP(IPC_Grp_Int_Src_Type src, uint8_t cpuxOffset)
{uint32_t tmpVal = 0;/* Check the parameters *///CHECK_PARAM(IS_IPC_Grp_Int_Src_Type(src));tmpVal = (1 << (src + cpuxOffset));BL_WR_REG(IPC1_BASE, IPC_CPU1_IPC_ISWR, tmpVal);
}/****************************************************************************/ /*** @brief  M0 trigger IPC interrupt to LP** @param  src: M0 IPC interrupt source** @return None*
*******************************************************************************/
void IPC_M0_Trigger_LP(IPC_Grp_nIt_Src_Type src)
{IPC_CPUx_Trigger_LP(src, IPC_M0_OFFSET_IN_LP);
}/****************************************************************************/ /*** @brief  D0 trigger IPC interrupt to LP** @param  src: D0 IPC interrupt source** @return None*
*******************************************************************************/
void IPC_D0_Trigger_LP(IPC_Grp_Int_Src_Type src)
{IPC_CPUx_Trigger_LP(src, IPC_D0_OFFSET_IN_LP);
}#if defined(CPU_D0) || defined(CPU_D1)
/****************************************************************************/ /*** @brief  D0 IPC interrupt init** @param  onM0TriggerCallBack: Callback when M0 trigger** @param  onLPTriggerCallBack: Callback when LP trigger** @return None*
*******************************************************************************/
void IPC_D0_Init(ipcIntCallback *onM0TriggerCallBack,ipcIntCallback *onLPTriggerCallBack)
{d0IpcIntCbfArra[0] = onM0TriggerCallBack;d0IpcIntCbfArra[1] = onLPTriggerCallBack;IPC_D0_Int_Unmask_By_Word(0xffffffff);#ifndef BFLB_USE_HAL_DRIVERInterrupt_Handler_Register(IPC_D0_IRQn, IPC_D0_IRQHandler);
#endifCPU_Interrupt_Enable(IPC_D0_IRQn);
}
#endif/****************************************************************************/ /*** @brief  D0 unmask IPC interrupt** @param  src: D0 IPC interrupt source** @return None*
*******************************************************************************/
void IPC_D0_Int_Unmask(IPC_Int_Src_Type src)
{uint32_t tmpVal = 0;/* Check the parameters */CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));tmpVal = (1 << src);BL_WR_REG(IPC2_BASE, IPC_CPU0_IPC_IUSR, tmpVal);
}/****************************************************************************/ /*** @brief  D0 unmask IPC interrupt by word** @param  src: D0 IPC interrupt source** @return None*
*******************************************************************************/
void IPC_D0_Int_Unmask_By_Word(uint32_t src)
{BL_WR_REG(IPC2_BASE, IPC_CPU0_IPC_IUSR, src);
}/****************************************************************************/ /*** @brief  D0 get IPC interrupt raw status** @param  None** @return IPC interrupt raw status*
*******************************************************************************/
uint32_t IPC_D0_Get_Int_Raw_Status(void)
{return BL_RD_REG(IPC2_BASE, IPC_CPU0_IPC_IRSRR);
}/****************************************************************************/ /*** @brief  D0 clear IPC interrupt** @param  src: D0 IPC interrupt source** @return None*
*******************************************************************************/
void IPC_D0_Clear_Int(IPC_Int_Src_Type src)
{uint32_t tmpVal = 0;/* Check the parameters */CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));tmpVal = (1 << src);BL_WR_REG(IPC2_BASE, IPC_CPU0_IPC_ICR, tmpVal);
}/****************************************************************************/ /*** @brief  D0 clear IPC interrupt by word** @param  src: IPC interrupt source in word,every bit is interrupt source** @return None*
*******************************************************************************/
void IPC_D0_Clear_Int_By_Word(uint32_t src)
{BL_WR_REG(IPC2_BASE, IPC_CPU0_IPC_ICR, src);
}/****************************************************************************/ /*** @brief  CPUx trigger IPC interrupt to D0** @param  src: IPC interrupt source** @param  cpuxOffset: CPU interrupt offset** @return None*
*******************************************************************************/
void IPC_CPUx_Trigger_D0(IPC_Grp_Int_Src_Type src, uint8_t cpuxOffset)
{uint32_t tmpVal = 0;/* Check the parameters *///CHECK_PARAM(IS_IPC_Grp_Int_Src_Type(src));tmpVal = (1 << (src + cpuxOffset));BL_WR_REG(IPC2_BASE, IPC_CPU1_IPC_ISWR, tmpVal);
}/****************************************************************************/ /*** @brief  M0 trigger IPC interrupt to D0** @param  src: M0 IPC interrupt source** @return None*
*******************************************************************************/
void IPC_M0_Trigger_D0(IPC_Grp_Int_Src_Type src)
{IPC_CPUx_Trigger_D0(src, IPC_M0_OFFSET_IN_D0);
}/****************************************************************************/ /*** @brief  LP trigger IPC interrupt to D0** @param  src: LP IPC interrupt source** @return None*
*******************************************************************************/
void IPC_LP_Trigger_D0(IPC_Grp_Int_Src_Type src)
{IPC_CPUx_Trigger_D0(src, IPC_LP_OFFSET_IN_D0);
}/****************************************************************************/ /*** @brief  M0 trigger IPC interrupt to CPUx** @param  tgtCPU: Target CPU** @param  src: IPC interrupt source** @return None*
*******************************************************************************/
void IPC_M0_Trigger_CPUx(GLB_CORE_ID_Type tgtCPU, IPC_Grp_Int_Src_Type src)
{switch (tgtCPU) {case GLB_CORE_ID_LP:IPC_M0_Trigger_LP(src);break;case GLB_CORE_ID_D0:IPC_M0_Trigger_D0(src);break;default:break;}
}/****************************************************************************/ /*** @brief  LP trigger IPC interrupt to CPUx** @param  tgtCPU: Target CPU** @param  src: IPC interrupt source** @return None*
*******************************************************************************/
void IPC_LP_Trigger_CPUx(GLB_CORE_ID_Type tgtCPU, IPC_Grp_Int_Src_Type src)
{switch (tgtCPU) {case GLB_CORE_ID_M0:IPC_LP_Trigger_M0(src);break;case GLB_CORE_ID_D0:IPC_LP_Trigger_D0(src);break;default:break;}
}/****************************************************************************/ /*** @brief  D0 trigger IPC interrupt to CPUx** @param  tgtCPU: Target CPU** @param  src: IPC interrupt source** @return None*
*******************************************************************************/
void IPC_D0_Trigger_CPUx(GLB_CORE_ID_Type tgtCPU, IPC_Grp_Int_Src_Type src)
{switch (tgtCPU) {case GLB_CORE_ID_M0:IPC_D0_Trigger_M0(src);break;case GLB_CORE_ID_LP:IPC_D0_Trigger_LP(src);break;default:break;}
}/****************************************************************************/ /*** @brief  D0 trigger IPC interrupt to D1** @param  src: D0 IPC interrupt source** @return None*
*******************************************************************************/
void IPC_Trigger_Target_CPU(GLB_CORE_ID_Type tgtCPU, IPC_Grp_Int_Src_Type src)
{GLB_CORE_ID_Type localCPU = GLB_Get_Core_Type();switch (localCPU) {case GLB_CORE_ID_M0:IPC_M0_Trigger_CPUx(tgtCPU, src);break;case GLB_CORE_ID_LP:IPC_LP_Trigger_CPUx(tgtCPU, src);break;case GLB_CORE_ID_D0:IPC_D0_Trigger_CPUx(tgtCPU, src);break;default:break;}
}/****************************************************************************/ /*** @brief  D0 trigger IPC interrupt to D1** @param  src: D0 IPC interrupt source** @return None*
*******************************************************************************/
void IPC_Common_Interrupt_Handler(uint32_t irqStatus, ipcIntCallback *callBack[GLB_CORE_ID_MAX - 1])
{uint32_t tmp;uint32_t grp = 0;for (grp = 0; grp < GLB_CORE_ID_MAX - 1; grp++) {tmp = (irqStatus >> (16 * grp)) & 0xffff;if (tmp != 0) {if (callBack[grp] != NULL) {callBack[grp](tmp);}}}
}/****************************************************************************/ /*** @brief  M0 IPC IRQ handler** @param  None** @return None*
*******************************************************************************/
#ifndef BFLB_USE_HAL_DRIVER
void IPC_M0_IRQHandler(void)
{uint32_t irqStatus;irqStatus = IPC_M0_Get_Int_Raw_Status();IPC_Common_Interrupt_Handler(irqStatus, m0IpcIntCbfArra);IPC_M0_Clear_Int_By_Word(irqStatus);
}
#endif/****************************************************************************/ /*** @brief  LP IPC IRQ handler** @param  None** @return None*
*******************************************************************************/
#ifndef BFLB_USE_HAL_DRIVER
void IPC_LP_IRQHandler(void)
{uint32_t irqStatus;irqStatus = IPC_LP_Get_Int_Raw_Status();IPC_Common_Interrupt_Handler(irqStatus, lpIpcIntCbfArra);IPC_LP_Clear_Int_By_Word(irqStatus);
}
#endif/****************************************************************************/ /*** @brief  D0 IPC IRQ handler** @param  None** @return None*
*******************************************************************************/
#ifndef BFLB_USE_HAL_DRIVER
void IPC_D0_IRQHandler(void)
{uint32_t irqStatus;irqStatus = IPC_D0_Get_Int_Raw_Status();IPC_Common_Interrupt_Handler(irqStatus, d0IpcIntCbfArra);IPC_D0_Clear_Int_By_Word(irqStatus);
}
#endif/*@} end of group IPC_Public_Functions *//*@} end of group IPC *//*@} end of group BL606P_Peripheral_Driver */

三、总结 

基本试验了IPC通讯,寄存器和触发动作应该是没问题的;看来后续要使用M1S_BL808_SDK作为开发主力的SDK了,好多函数封装了,功能实现的也比较好;只是目前只能在Linux下的开发环境使用,对于笔记本性能有限,懒得开虚拟机的我,还是eciplse的Windows客户端使用起来更方便一点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/146345.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

大喜国庆,聊聊我正式进入职场的这三个月...

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

实现三栏布局的十种方式

本文节选自我的博客&#xff1a;实现三栏布局的十种方式 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是MilesChen&#xff0c;偏前端的全栈开发者。&#x1f4dd; CSDN主页&#xff1a;爱吃糖的猫&#x1f525;&#x1f4e3; 我的博客&#xff1a;爱吃糖的猫&…

02-Zookeeper实战

上一篇&#xff1a;01-Zookeeper特性与节点数据类型详解 1. zookeeper安装 Step1&#xff1a; 配置JAVA环境&#xff0c;检验环境&#xff1a; java -versionStep2: 下载解压 zookeeper wget https://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.5.8/apache-zookeepe…

番外5:下载+安装+配置Linux

任务前期工作&#xff1a; 01. 电脑已安装好VMware Workstation软件&#xff1b; 02.提前下载好Rhel-8.iso映像文件&#xff08;文件较大一般在9.4GB&#xff0c;建议采用迅雷下载&#xff09;&#xff0c;本人使用的以下版本&#xff08;地址ed2k://|file|rhel-8.4-x86_64-dvd…

C++-哈希Hash

本期我们来学习哈希 目录 unordered系列关联式容器 unordered_map unordered_set 性能比较 哈希概念 哈希冲突 哈希函数 哈希冲突解决 闭散列 模拟实现 开散列 模拟实现 全部代码 unordered系列关联式容器 在 C98 中&#xff0c; STL 提供了底层为红黑树结构的一…

【算法基础】一文掌握十大排序算法,冒泡排序、插入排序、选择排序、归并排序、计数排序、基数排序、希尔排序和堆排序

目录 1 冒泡排序&#xff08;Bubble Sort&#xff09; 2 插入排序&#xff08;Insertion Sort&#xff09; 3 选择排序&#xff08;Selection Sort&#xff09; 4. 快速排序&#xff08;Quick Sort&#xff09; 5. 归并排序&#xff08;Merge Sort&#xff09; 6 堆排序 …

【day10.01】使用select实现服务器并发

用select实现服务器并发&#xff1a; linuxlinux:~/study/1001$ cat server.c #include <myhead.h>#define ERR_MSG(msg) do{\printf("%d\n",__LINE__);\perror(msg);\ }while(0)#define PORT 8880#define IP "192.168.31.38"int main(int argc, c…

11链表-迭代与递归

目录 LeetCode之路——206. 反转链表 分析&#xff1a; 解法一&#xff1a;迭代 解法二&#xff1a;递归 LeetCode之路——206. 反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head […

开绕组电机零序Bakc EMF-based无感控制以及正交锁相环inverse Park-based

前言 最近看论文遇到了基于反Park变换的锁相环&#xff0c;用于从开绕组永磁同步电机零序电压信号中提取转子速度与位置信息&#xff0c;实现无感控制。在此记录 基于零序Back EMF的转子估算 开绕组电机的零序反电动势 e 0 − 3 ω e ψ 0 s i n 3 θ e e_0-3\omega_e\psi_…

SoloX:Android和iOS性能数据的实时采集工具

SoloX&#xff1a;Android和iOS性能数据的实时采集工具 github地址&#xff1a;https://github.com/smart-test-ti/SoloX 最新版本&#xff1a;V2.7.6 一、SoloX简介 SoloX是开源的Android/iOS性能数据的实时采集工具&#xff0c;目前主要功能特点&#xff1a; 无需ROOT/越狱…

直播协议 python 常见直播协议

1. 推流、直播 和 点播分别是什么意思&#xff1f; 推流 主播将本地视频源和音频源推送到云服务器&#xff0c;也被称为“RTMP发布”。 直播 即直接观看主播实时推送过来的音视频数据。 点播 视频源已经事先存储于云服务器之上的音视频文件&#xff0c;观众随时可以观看。 目…

STM32晶振的选择与计算

目录 1、石英晶体特性和型号2、振荡器理论2.1负电阻2.2跨导2.3负阻振荡器原理 3、皮尔斯振荡器设计3.1 皮尔斯振荡器简介3.2反馈电阻器3.3负载电容3.4振荡器跨导3.5驱动电平和外部电阻计算3.5.1计算驱动电平3.5.2另一种驱动电平测量方法3.5.3计算外部电阻 3.6启动时间3.7晶体拉…

八个不可不知的SQL高级方法

结构化查询语言&#xff08;SQL&#xff09;是一种广泛使用的工具&#xff0c;用于管理和操作数据库。基本的SQL查询简单易学&#xff0c;但掌握高级SQL技术可以将您的数据分析和管理能力提升到新的高度。 高级SQL技术是指一系列功能和函数&#xff0c;使您能够对数据执行复杂…

记录:Unity脚本的编写

目录 前言添加脚本到unity编写c#脚本查看效果 前言 在学习软件构造这门课的时候&#xff0c;对unity和c#进行了 一定程度的学习&#xff0c;包括简单的建立地形&#xff0c;添加对象&#xff0c;添加材质等&#xff0c;前不久刚好学习了如何通过c#脚本对模型进行操控&#xff…

uniapp - 微信小程序实现腾讯地图位置标点展示,将指定地点进行标记选点并以一个图片图标展示出来(详细示例源码,一键复制开箱即用)

效果图 在uniapp微信小程序平台端开发,简单快速的实现在地图上进行位置标点功能,使用腾讯地图并进行标点创建和设置(可以自定义标记点的图片)。 你只需要复制代码,改个标记图标和位置即可。

Fiddler Orchestra用户指南:打造高效协同调试利器

引言&#xff1a;今天Fiddler更新到5.0版本后&#xff0c;小酋不经意间晃到了“Fiddler Orchestra”选项卡。爱折腾的小酋赶紧链接到官方用户指南一睹为快&#xff0c;看看这是什么东西&#xff0c;实现了什么新功能。下面是小酋看后做的一个翻译抢先版。 这是了解和设置Fiddl…

《 新手》web前端(axios)后端(java-springboot)对接简解

文章目录 <font color red>1.何为前后端对接?2.对接中关于http的关键点2.1. 请求方法2.2. 请求参数设置简解&#xff1a; 3.对接中的跨域(CROS)问题**为什么后端处理跨域尽量在业务之前进行&#xff1f;**3.总结 1.何为前后端对接? “前后端对接” 是指前端和后端两个…

ElementUI实现增删改功能以及表单验证

目录 前言 BookList.vue action.js 展示效果 前言 本篇还是在之前的基础上&#xff0c;继续完善功能。上一篇完成了数据表格的查询&#xff0c;这一篇完善增删改&#xff0c;以及表单验证。 BookList.vue <template><div class"books" style"pa…

picoctf_2018_can_you_gets_me

picoctf_2018_can_you_gets_me Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)32位&#xff0c;只开了NX 拿到这么大的程序&#xff0c;直接ROPchain看看 #!/usr/bin/env python2# execve …

低代码工作流程管理系统:提升企业运营效率的利器

业务运营状况是否良好&#xff0c;除了人员需要配合以外&#xff0c;真正发挥作用的是背后的工作流程。将重复的工作进行自动化处理&#xff0c;确保这些流程最终指向同一个目标、实现一致的运营结果。而设计和实施不佳的工作流程则产生相反的效果——导致处理时间延长、运营成…