当前位置: 首页 > news >正文

DSP在CCS中实现双核在线仿真调试及下载的方法(以TMS320F28x为例)

DSP在CCS中实现双核在线仿真调试及下载的方法

  • 介绍
  • 使用的软硬件
  • 双核项目结构及工程配置
    • 工程建立
    • 配置在线调试和离线烧写
  • 双核程序在线调试
  • 双核程序离线下载
  • 后续

介绍

现在DSP的双核芯片已经越来越普遍,尤其是在TI推出的TMS320F2837xD、F2838x系列中,双核(CPU1 + CPU2)的架构成为了性能提升的重要手段。双核DSP不仅提高了系统的实时性和并行处理能力,还为复杂的控制、通信、算法运算等场景提供了更灵活的资源调度方式。
然而,双核带来的性能提升的同时,也使得程序开发和调试变得更加复杂。在CCS(Code Composer Studio)中,如果不能掌握正确的双核调试方法,往往会遇到程序不运行、Flash下载失败、两个CPU间无法通信等问题。

本篇文章将详细介绍如何在CCS中实现双核DSP的在线仿真调试程序下载,涵盖以下几个方面:

  • 双核项目结构及工程配置
  • 如何配置和切换在线调试/离线下载
  • 如何进行双核程序在线调试
  • 如何进行双核程序下载
    无论你是初次接触双核DSP的开发者,还是在项目中遇到多核调试困难的工程师,相信通过本文的讲解都能对你有所帮助。

使用的软硬件

  1. Code Composer Studio™ 集成式开发环境 (IDE)
  2. XDS100v3 USB Debug Probe
  3. UniFlash
  4. TMS320F28X芯片的开发板

双核项目结构及工程配置

工程建立

TMS320F28X芯片双核结构虽然使用上CPU占据主导权,但是两个CPU的工程是分开的,也就是完全独立的两个工程。

图中的两个工程led_ex1_blinky_cpu1和led_ex1_blinky_cpu2分别是CPU1和CPU2的工程。

配置在线调试和离线烧写

  1. 在CPU1工程中增加:
#ifdef _STANDALONE
#ifdef _FLASH//// Send boot command to allow the CPU2 application to begin execution//Device_bootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);
#else//// Send boot command to allow the CPU2 application to begin execution//Device_bootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_RAM);#endif // _FLASH
#endif // _STANDALONE

这段代码的含义为,当定义_STANDALONE和_FLASH时,启用 Device_bootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);
在 TI 的 dual-core 设备 中,CPU1 是主核,它控制整个设备的启动过程。CPU2 默认上电是处于复位或等待状态,需要由 CPU1 启动。
从数据手册可以看到:CPU2需要CPU1选择引导,Device_bootCPU2函数其实就是干这个的。

函数原型:void Device_bootCPU2(uint32_t bootMode);
bootMode 是启动方式参数,比如:

  • C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH → 从 Flash 启动
  • C1C2_BROM_BOOTMODE_BOOT_FROM_RAM → 从 RAM 启动
  • C1C2_BROM_BOOTMODE_BOOT_FROM_SCI → 从 SCI(串口)启动
  • C1C2_BROM_BOOTMODE_BOOT_FROM_I2C → 从 I2C 启动
  • C1C2_BROM_BOOTMODE_BOOT_WAIT → 不启动,等待指令
  1. 增加定义
    CPU1和CPU2都需要设置一个 Predefined Symbols,右键工程文件->Properties->在Predefined Symbols进行添加。
  • 对于CPU2定义是一样的,因为不需要区分在线调试和离线烧写,所以定义都是一样的。
  • 对于CPU1则不同,离线烧写时,选择CPU1_FLASH,只需要定义_CPU1和_FLASH即可。
  • 对于在线调试,首先需要建立一个编译配置。点击管理配置然后新建一个CPU1_FLASH_STANDALONE(继承CPU1_FLASH)。
  • 在这里插入图片描述
    然后额外添加一个_STANDALONE。

之后我们编译的时候根据编译配置就可以选择是在线调试还是离线烧写了。
在这里插入图片描述

  1. 下面放一个官方的双核程序供大家测试。
    CPU1
//
// Included Files
//
#include "driverlib.h"
#include "device.h"//
// Main
//
void main(void)
{//// Initialize device clock and peripherals//Device_init();#ifdef _STANDALONE
#ifdef _FLASH//// Send boot command to allow the CPU2 application to begin execution//Device_bootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);
#else//// Send boot command to allow the CPU2 application to begin execution//Device_bootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_RAM);#endif // _FLASH
#endif // _STANDALONE//// Initialize GPIO and configure the GPIO pin as a push-pull output//Device_initGPIO();GPIO_setPadConfig(DEVICE_GPIO_PIN_LED1, GPIO_PIN_TYPE_STD);GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED1, GPIO_DIR_MODE_OUT);GPIO_setPadConfig(DEVICE_GPIO_PIN_LED2, GPIO_PIN_TYPE_STD);GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED2, GPIO_DIR_MODE_OUT);//// Configure CPU2 to control the LED GPIO//GPIO_setMasterCore(DEVICE_GPIO_PIN_LED2, GPIO_CORE_CPU2);//// Initialize PIE and clear PIE registers. Disables CPU interrupts.//Interrupt_initModule();//// Initialize the PIE vector table with pointers to the shell Interrupt// Service Routines (ISR).//Interrupt_initVectorTable();//// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)//EINT;ERTM;//// Loop Forever//for(;;){//// Turn on LED//GPIO_writePin(DEVICE_GPIO_PIN_LED1, 0);//// Delay for a bit.//DEVICE_DELAY_US(500000);//// Turn off LED//GPIO_writePin(DEVICE_GPIO_PIN_LED1, 1);//// Delay for a bit.//DEVICE_DELAY_US(500000);}
}//
// End of File
//

CPU2


//
// Included Files
//
#include "driverlib.h"
#include "device.h"//
// Main
//
void main(void)
{//// Initialize device clock and peripherals//Device_init();//// Initialize GPIO and configure the GPIO pin as a push-pull output//// This is configured by CPU1//// Initialize PIE and clear PIE registers. Disables CPU interrupts.//Interrupt_initModule();//// Initialize the PIE vector table with pointers to the shell Interrupt// Service Routines (ISR).//Interrupt_initVectorTable();//// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)//EINT;ERTM;//// Loop Forever//for(;;){//// Turn on LED//GPIO_writePin(DEVICE_GPIO_PIN_LED2, 0);//// Delay for a bit.//DEVICE_DELAY_US(500000);//// Turn off LED//GPIO_writePin(DEVICE_GPIO_PIN_LED2, 1);//// Delay for a bit.//DEVICE_DELAY_US(500000);}
}//
// End of File
//

双核程序在线调试

  1. 编译两个工程,CPU1和CPU2均使用_FLASH。
  2. 点击debug
  3. 在debug中选定CPU1,然后选择固件。


  4. 然后选择CPU2进行更改固件。
  5. 选择CPU1和CPU2,然后分别点击运行。
  6. 运行后
  7. 此时CPU1,CPU2一起运行。

双核程序离线下载

  • 离线下载和在线调试的区别就是,在第1步时,CPU1选择CPU1_FLASH_STANDALONE进行编译。后面2-6完全一样。然后关机重启。
  • 还有一种离线下载方式,直接通过UniFlash进行下载。

分别通过点击CPU1和CPU2,然后选择工程生成的.out进行下载。

后续

http://www.dtcms.com/a/299243.html

相关文章:

  • iOS 26,双版本更新来了
  • MyBatis_3
  • 【iOS】网易云仿写
  • 全文检索官网示例
  • 算法竞赛阶段二-数据结构(35)数据结构单链表模拟实现
  • springboot + vue3 拉取海康视频点位及播放
  • Kafka——Java消费者是如何管理TCP连接的?
  • JavaWeb01——基础标签及样式(黑马视频笔记)
  • [2025CVPR:图象合成、生成方向]WF-VAE:通过小波驱动的能量流增强视频 VAE 的潜在视频扩散模型
  • SSRF_XXE_RCE_反序列化学习
  • 「iOS」——内存五大分区
  • C++核心编程学习--对象特性--对象模型和this指针
  • 旧设备HMI焕新陷阱:操作习惯继承与智能化升级的平衡点把控
  • ​机器学习从入门到实践:算法、特征工程与模型评估详解
  • pose调研
  • # JsSIP 从入门到实战:构建你的第一个 Web 电话
  • Vue》》@ 用法
  • 期货资管软件定制开发流程
  • Matlab学习笔记:自定义函数
  • Vue 3 与 Element Plus 中的 /deep/ 选择器问题
  • 如果在分支A上修改了内容,想要提交更新内容的话,如何与develop上的主分支的最新的代码拉齐
  • linux线程概念和控制
  • Node.js特训专栏-实战进阶:19.dotenv环境变量管理
  • 零基础学习性能测试第三章:jmeter构建性能业务场景
  • [C/C++内存安全]_[中级]_[再次探讨避免悬垂指针的方法和检测空指针的方法]
  • 《从零开始学 JSSIP:JavaScript 实时通信开发实战》
  • QT核心————信号槽
  • Qt 多线程编程最佳实践
  • 《使用Qt Quick从零构建AI螺丝瑕疵检测系统》——6. 传统算法实战:用OpenCV测量螺丝尺寸
  • 基于粒子群算法优化高斯过程回归(PSO-GPR)的多输出回归