DSP 开发例程: 单镜像多核引导

DSP 开发例程: 单镜像多核引导

此例程实现在 EVM6678L 开发板上将单镜像应用程序进行多核引导, 核0-核4 分别控制一个LED 闪烁, 并通过串口打印日志信息. 例程源码可从我的 gitee 仓库上克隆或下载. 点击 DSP 开发教程(0): 汇总查看其他例程说明.

新建工程

此示例工程直接在 logbuf_print_to_uart 工程基础上修改.

  • 选中 logbuf_print_to_uart 工程, 右键选择 Copy 或 使用快捷键 Ctrl+C 复制工程.

在这里插入图片描述

  • 在工程浏览视图中, 右键选择 Paste 或使用快捷键 Ctrl+V 粘贴工程.
    在这里插入图片描述
    在弹出的 Copy Project 对话框中 修改工程名为: multicore_boot, 点击 OK.
    在这里插入图片描述
  • 删除 multicore_boot 工程中的 Debug目录, 右键选择 Build Project, 编译此工程.

源码编辑

multicore_boot.c

新建名为 multicore_boot.c的源文件, 文件内容如下:

#include <ti/csl/csl_bootcfgAux.h>

#define CORE_0_MAGIC_ADDR (0X1087FFFC)

extern unsigned int  _c_int00(void);

void multicore_boot()
{
	unsigned int i;

	CSL_BootCfgUnlockKicker();
	// 拷贝 core0 L2SRAM 数据到其他核心
	for (i = 1; i < 8; i++)
	{
		memcpy((void *)(CSL_DSP0_L2_SRAM_REGS+0x01000000*i), (void *)CSL_DSP0_L2_SRAM_REGS, 0x70000);
		*(volatile unsigned int *)(CORE_0_MAGIC_ADDR + 0x01000000*i) = (unsigned int)_c_int00;
		CSL_BootCfgGenerateInterDSPInterrupt(i, 0);
	}

	CSL_BootCfgLockKicker();
}

multicore_boot() 函数由核0执行, 实现以下功能:

  • 将核0的 L2SRAM 中的内容复制到其他核心的 L2SRAM中;
  • 向其他核心发送 IPC中断, 唤醒其他核心.

config.h

新建名为 config.h 的头文件, 在其中输入如下内容:

#ifndef CONFIG_H_
#define CONFIG_H_

#define PLATFORM_UART_HW_SEM 4
#define PLATFORM_LED_HW_SEM 5


#endif /* CONFIG_H_ */

其中, 定义了两个宏, 分别用于多核在 UARTLED 外设资源抢占时, 使用哪个硬件信号量进行资源保护.

os.c

修改 os_systemFlush() 函数, 在执行System_flush()前后加入硬件信号量的请求和释放.

void os_systemFlush()
{
	if (logger0)
		myLoggerBuf_flush(logger0);

	if ((CSL_semAcquireDirect (PLATFORM_UART_HW_SEM)))
	{
		System_flush();
		CSL_semReleaseSemaphore (PLATFORM_UART_HW_SEM);
	}
}

main.c

修改 EVM_init() 函数, 调用 multicore_boot() 函数实现多核引导. 平台初始化和多核引导只由核0 完成.

void EVM_init()
{
	platform_init_flags init_flags;
	platform_init_config init_config;

	if (platform_get_coreid() == 0)
	{
		// plaform initialize
		memset(&init_flags, 1, sizeof(platform_init_flags));
		init_flags.phy = 0;
		memset(&init_config, 0, sizeof(platform_init_config));
		if (platform_init(&init_flags, &init_config) != Platform_EOK)
		{
			printf("Platform failed to initialize, errno = 0x%x \n", platform_errno);
			while(1);
		}
		platform_uart_init();

		multicore_boot();
	}
}

修改 task_ledFlash() 函数, 在调用 platform_led() 函数前后加入硬件信号量的请求和释放.

Void task_ledFlash(UArg a0, UArg a1)
{
    int i = 1;
    int id = platform_get_coreid();
    Log_info0("enter task_ledFlash().");

    if (id < 4)
    {
        while(1)
        {
            while ((CSL_semAcquireDirect (PLATFORM_LED_HW_SEM)) == 0);
            platform_led(id, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
            CSL_semReleaseSemaphore (PLATFORM_LED_HW_SEM);
            Log_info2("LED %d ON at %d times.", id, i);
            Task_sleep(500);

            while ((CSL_semAcquireDirect (PLATFORM_LED_HW_SEM)) == 0);
            platform_led(id, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
            CSL_semReleaseSemaphore (PLATFORM_LED_HW_SEM);
            Log_info2("LED %d OFF at %d times.", id, i);
            Task_sleep(500);
            i++;
        }
    }
}

保存对上述文件的修改.

测试

此处我使用 IBL-TFTP 引导方式对核0进行应用程序的加载和引导. 你也可以使用其他的引导方式. 请参考:EVM6678L 开发教程: IBL-TFTP 引导 elf 文件

下图是EVM6678L开发板串口终端打印的日志信息. 多个核心的日志时间戳不一定按时间先后顺序排列

在这里插入图片描述

同时应该可以看到开发板上的四个LED灯以1秒周期闪烁.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

falwat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值