一、board init()

core0初始化时钟、外设、内存、释放core1

void board_init(void)
{
    board_turnoff_rgb_led();
    board_init_clock();
    board_init_console();
    board_init_pmp();
#if BOARD_SHOW_CLOCK
    board_print_clock_freq();
#endif
#if BOARD_SHOW_BANNER
    board_print_banner();
#endif
}

在时钟初始化部分,基本外设都挂在在cpu0,cpu1的邮箱挂在cpu1

init-pmp 定义nocache区,方便双核进行数据交换

 释放core1

void multicore_release_cpu(uint8_t cpu_id, uint32_t start_addr)
{
    sdp_dma_ctx_t *p_sdp_ctx = (sdp_dma_ctx_t *) core_local_mem_to_sys_address(HPM_CORE0, (uint32_t) &s_dma_ctx);
    uint32_t sec_core_app_sys_addr = core_local_mem_to_sys_address(cpu_id, (uint32_t)start_addr);
    uint32_t sec_core_img_sys_addr = core_local_mem_to_sys_address(0, (uint32_t)sec_core_img);
    uint32_t aligned_start;
    uint32_t aligned_end;
    uint32_t aligned_size;

    if (!sysctl_is_cpu_released(HPM_SYSCTL, cpu_id)) {
        printf("\nCopying secondary core image to destination memory: %#x\n", sec_core_img_sys_addr);

        rom_sdp_memcpy(p_sdp_ctx, (void *)sec_core_app_sys_addr, (void *)sec_core_img_sys_addr, sec_core_img_size);
        if (l1c_ic_is_enabled() || l1c_dc_is_enabled()) {
            aligned_start = HPM_L1C_CACHELINE_ALIGN_DOWN(sec_core_img_sys_addr);
            aligned_end = HPM_L1C_CACHELINE_ALIGN_UP(sec_core_img_sys_addr + sec_core_img_size);
            aligned_size = aligned_end - aligned_start;
            l1c_dc_flush(aligned_start, aligned_size);
        }

        sysctl_set_cpu_entry(HPM_SYSCTL, cpu_id, (uint32_t)start_addr);
        sysctl_release_cpu(HPM_SYSCTL, cpu_id);
    }
}

core1初始化内存

void board_init_core1(void)
{
    board_init_console();
    board_init_pmp();
}

二、如何判断双核跑在哪里

查看link文档

core0的连接文件

配置share memory

  /* Init share memory */
    extern uint32_t __share_mem_start__[];
    extern uint32_t __share_mem_end__[];
    start_addr = (uint32_t)__share_mem_start__;
    end_addr = (uint32_t)__share_mem_end__;
    length = end_addr - start_addr;
    if (length > 0) {
        /* Ensure the address and the length are power of 2 aligned */
        assert((length & (length - 1U)) == 0U);
        assert((start_addr & (length - 1U)) == 0U);
        pmp_entry[index].pmp_addr = PMP_NAPOT_ADDR(start_addr, length);
        pmp_entry[index].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
        pmp_entry[index].pma_addr = PMA_NAPOT_ADDR(start_addr, length);
        pmp_entry[index].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN);
        index++;
    }

core1的连接文件

配置share memory

    /* Init share memory */
    extern uint32_t __share_mem_start__[];
    extern uint32_t __share_mem_end__[];
    start_addr = (uint32_t)__share_mem_start__;
    end_addr = (uint32_t)__share_mem_end__;
    length = end_addr - start_addr;
    if (length > 0) {
        /* Ensure the address and the length are power of 2 aligned */
        assert((length & (length - 1U)) == 0U);
        assert((start_addr & (length - 1U)) == 0U);
        pmp_entry[index].pmp_addr = PMP_NAPOT_ADDR(start_addr, length);
        pmp_entry[index].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
        pmp_entry[index].pma_addr = PMA_NAPOT_ADDR(start_addr, length);
        pmp_entry[index].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN);
        index++;
    }

core0、core1要设置一样配置的共享内存区域

三、核间通信示例

 test_singleword_communication();
 test_multiword_communication(8);      邮箱通信                                                       test_mbx_sharram_communication(); 共享内存通信

结果见HPM6750——双核通信结果-CSDN博客

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐