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.mzph.cn/news/92192.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SELinux 介绍

背景 在工作中经常需要在 android 中增加一些东西&#xff0c; 而android有自己的安全限制&#xff0c;如果不懂SELinux&#xff0c;就不好添加。 Control Access Model https://zh.wikipedia.org/wiki/Chmod https://linux.die.net/man/1/chcon DAC DAC and Trojan Horses D…

一维数组和二维数组的使用(一)

目录 导读1. 一维数组1.1 一维数组的创建1.2 数组的初始化1.3 一维数组的使用1.4 一维数组在内存中的存储 2. 二维数组2.1 二维数组的创建2.2 二维数组的初始化2.3 二维数组的使用2.4 二维数组在内存中的存储 博主有话说 导读 本篇主要讲解一维数组和二维数组的创建和使用&…

dart flutter json 转 model 常用库对比 json_serializable json_model JsonToDart

1.对比 我是一个初学者,一直跟着教材用原生的json,最近发现实在太麻烦了.所以搜索了一下,发现真的有很多现成的解决方案. 网页 https://app.quicktype.io/?ldart 这个是测试下来最好用的 有很多选项,可以使用 json_serializable 也可以不使用 json_serializable 这是推荐最…

机器人入门(一)

机器人入门&#xff08;一&#xff09; 一、ROS是什么&#xff0c;能用来干什么&#xff1f;二、哪些机器人用到了ROS&#xff1f;三、ROS和操作系统是绑定的吗&#xff1f;四、ROS 1 和ROS 2的关系是什么&#xff1f;4.1架构中间件改变API改变数据格式改变 4.2特性4.3工具/生态…

前缀、中缀、后缀表达式相互转换工具

目录 1. 界面一览 2. 使用说明 3. 实例演示 3.1 输入中缀 3.2 输入前缀 3.3 输入后缀 3.4 选择错误的类型 4. 代码 5. 资源地址 关于什么是前缀、中缀、后缀表达式&#xff0c;相信你不知道这个东西&#xff0c;那你也不会点进来这篇博客&#xff0c;当然&#xff0c;…

光鉴科技:以3D视觉变革重新定义驾乘体验

以下文章来源于智车行家 ,作者小易

信息化发展73

数字经济 数字经济是继农业经济、工业经济之后的更高级经济形态。从本质上看&#xff0c;数字经济是一种新的技术经济范式&#xff0c;它建立在信息与通信技术的重大突破的基础上&#xff0c;以数字技术与实体经济融合驱动的产业梯次转型和经济创新发展的主引擎&#xff0c;在…

计算机竞赛 深度学习机器视觉车道线识别与检测 -自动驾驶

文章目录 1 前言2 先上成果3 车道线4 问题抽象(建立模型)5 帧掩码(Frame Mask)6 车道检测的图像预处理7 图像阈值化8 霍夫线变换9 实现车道检测9.1 帧掩码创建9.2 图像预处理9.2.1 图像阈值化9.2.2 霍夫线变换 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分…

CentOS上网卡不显示的问题

文章目录 1.问题描述 1.问题描述 ifconfig下看不到ens33网卡了。systemctl status network #查看网卡状态报下面的问题网上说的解决方式有以下三种&#xff1a; 第一种&#xff1a; 和 NetworkManager 服务有冲突&#xff0c;这个好解决&#xff0c;直接关闭 NetworkManger 服…

竞赛选题 大数据疫情分析及可视化系统

文章目录 0 前言2 开发简介3 数据集4 实现技术4.1 系统架构4.2 开发环境4.3 疫情地图4.3.1 填充图(Choropleth maps)4.3.2 气泡图 4.4 全国疫情实时追踪4.6 其他页面 5 关键代码最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 大数据疫…

【Linux】——基操指令(二)

个人主页 代码仓库 C语言专栏 初阶数据结构专栏 Linux专栏 LeetCode刷题 算法专栏 目录 前言 man指令 cp 指令 mv指令 echo指令 cat指令 more指令 less指令 head和tail指令 head指令 tail指令 前言 上篇文章给大家讲解了Linux环境下的一点基操指令&#xf…

消息队列实现进程之间通信方式代码,现象

消息队列 #include <myhead.h> //消息结构体 typedef struct {long msgtype; //消息类型char data[1024]; //消息正文 }Msg_ds; #define SIZE sizeof(Msg_ds)-sizeof(long) //正文大小int main(int argc, const char *argv[]) {//1、创建key值key_t …

搭建全连接网络进行分类(糖尿病为例)

拿来练手&#xff0c;大神请绕道。 1.网上的代码大多都写在一个函数里&#xff0c;但是其实很多好论文都是把网络&#xff0c;数据训练等分开写的。 2.分开写就是有一个需要注意的事情&#xff0c;就是要import 要用到的文件中的模型或者变量等。 3.全连接的回归也写了&#…

ChatGPT的截图识别功能测评:开启图像中的文字与信息的新纪元

文章目录 根据截图&#xff0c;识别菜品根据截图&#xff0c;识别数学公式根据截图生成前端UI代码可视化图像复现案例一案例二 更多可以使用的方向 制作人&#xff1a;川川 辛苦测评&#xff0c;如果对你有帮助支持一下书籍&#xff1a;https://item.jd.com/14049708.html 根据…

[C#]C#最简单方法获取GPU显存真实大小

你是否用下面代码获取GPU显存容量&#xff1f; using System.Management; private void getGpuMem() {ManagementClass c new ManagementClass("Win32_VideoController");foreach (ManagementObject o in c.GetInstances()){string gpuTotalMem String.For…

自动化测试-友好的第三方库

目录 mock furl coverage deepdiff pandas jsonpath 自动化测试脚本开发中&#xff0c;总是会遇到各种数据处理&#xff0c;例如MOCK、URL处理、JSON数据处理、结果断言等&#xff0c;也会遇到所采用的测试框架不能满足当前需求&#xff0c;这些问题都需要我们自己动手解…

Flink CDC MySQL同步MySQL错误记录

1、启动 Flink SQL [appuserwhtpjfscpt01 flink-1.17.1]$ bin/sql-client.sh2、新建源表 问题1&#xff1a;Encountered “(” 处理方法&#xff1a;去掉int(11)&#xff0c;改为int Flink SQL> CREATE TABLE t_user ( > uid int(11) NOT NULL AUTO_INCREMENT COMME…

Pytorch中关于forward函数的理解与用法

目录 前言1. 问题所示2. 原理分析2.1 forward函数理解2.2 forward函数用法 前言 深入深度学习框架的代码&#xff0c;发现forward函数没有被显示调用 但代码确重写了forward函数&#xff0c;于是好奇是不是python的魔术方法作用 1. 问题所示 代码如下所示&#xff1a; cla…

若依不分离+Thymeleaf select选中多个回显

项目中遇到的场景&#xff0c;亲测实用 表单添加时&#xff0c;select选中多个&#xff0c;编辑表单时&#xff0c;select多选回显&#xff0c;如图 代码&#xff1a; // 新增代码 <label class"col-sm-3 control-label">通道&#xff1a;</label><…

计算机图形学、贝塞尔曲线及绘制方法、反走样问题的解决(附完整代码)

贝塞尔曲线 1. 本次作业实现的函数及简单描述&#xff08;详细代码见后&#xff09;2. 与本次作业有关的基础知识整理3. 代码描述&#xff08;详细&#xff09;4. 完整代码5. 参考文献 &#xff08;本篇为作者学习计算机图形学时根据作业所撰写的笔记&#xff0c; 如有同课程请…