This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/TMS320F28035:闪存编程问题 TMS320F28035 uController

Guru**** 2609895 points
Other Parts Discussed in Thread: TMS320F28035

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/687551/ccs-tms320f28035-problem-flash-programming-tms320f28035-ucontroller

器件型号:TMS320F28035

工具/软件:Code Composer Studio

大家好、我在使代码从 TMS320F28035上的闪存运行时遇到了重大问题。

我的代码(用 C 编写)在调试模式(在 RAM 中)下运行时工作良好、运行符合我的预期。 此后、我尝试创建了一个可以编程到闪存中的版本、该版本将在加电时引导和运行。

我参考了应用手册(SPRA958L)中描述的示例和方法、并在本论坛中查看了一些已解决的问题-但没有乐趣。 我认为我选择了正确的示例链接器文件(F28035.cmd、而不是28035_RAM_Ink .cmd 文件)。 当我对器件进行编程时、我会看到一个对话框、指示闪存正在被擦除、然后被写入、并且我可以使用绿色三角形或单步启动代码。 但是、当我关闭电源并断开 XDS110时、它将不会启动。 XRS 引脚(RESET)每~13ms 脉冲低电平~50us、这表明看门狗正在关闭并对器件进行复位、但我已经(我认为)在设置例程(ALA SPRA958L)中将其禁用。

我包含了一个截止版本的代码(我真的不想为所有代码提供任何潜在的帮助)、该代码只会闪烁几个 LED。 如果有人可以提供帮助、我很乐意发布任何必要的额外数据。

我知道这将会非常明显–但在这一点上、我很乐意提供任何帮助、因为我花了很长时间尝试对器件进行编程。

 

j

以下代码:

#include "DSP28x_Project.h"
#include "DSP2803x_Device.h"
//#include "DSP2803x_SYSCTRL.c"
#include "DSP2803x_ADC.c"
#include "EP1401_DSP28035_GPIO.c"
//#include "DSP2803x_PIECTRL.c"
//#include "DSP2803x_PieVect.c

#include
#include

#pragma CODE_SECTION (InitFlash、"ramfuncs");

//全局变量
int LEDToggleCount = 0;        //切换计数以允许 LED 关闭和打开。
INT LED = 0;                   //LED 状态:0 =打开、1 =关闭。

空初始化端口(空)

   EALLOW;
   /*
    *设置 GPIO 的功能
    *
   GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3;   //GPIO18 = XCKLOUT
   //LED 控制位
   GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 0b00;   //GPIO
   GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 0b00;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0b00;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 0b00;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPAMUX1.bit.GPIO9 = 0b00;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 0b00;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 0b00;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 0b00;  // GPIO 功能 GPIO16-GPIO31
   //未使用
   GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 0;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 0;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPAMUX2.bit.GPIO27 = 0;  // GPIO 功能 GPIO16-GPIO31
   //通信数据位
   GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 0;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 0;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPAMUX1.bit.GPIO5=0;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPAMUX1.bit.GPIO7=0;  // GPIO 功能 GPIO16-GPIO31
   //数字数据
   GpioCtrlRegs.GPAMUX1.bit.GPIO8=0;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 0;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 0;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPBMUX1.bit.GPIO41 = 0;  // GPIO 功能 GPIO16-GPIO31
   GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;  // GPIO 功能 GPIO16-GPIO31
   /*
    *设置 GPIO 的方向
    *
   GpioCtrlRegs.GPADIR.bit.GPIO18 = 1;  // GPIO 是 GP 输出 XCLKOUT
   //LED
   GpioCtrlRegs.GPADIR.bit.GPIO22 = 1;  // GPIO0-GPIO31是 GP 输出
   GpioCtrlRegs.GPADIR.bit.GPIO29 = 1;  // GPIO 是 GP 输出
   GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1;  // GPIO 是 GP 输出
   GpioCtrlRegs.GPBDIR.bit.GPIO33 = 1;  // GPIO 是 GP 输出
   GpioCtrlRegs.GPADIR.bit.GPIO9 = 1;  // GPIO 是 GP 输出
   GpioCtrlRegs.GPADIR.bit.GPIO28 = 1;  // GPIO 是 GP 输出
   GpioCtrlRegs.GPADIR.bit.GPIO23 = 1;  //是 GP 输出
   GpioCtrlRegs.GPADIR.bit.GPIO26 = 1;  //是 GP 输出
   //备件
   GpioCtrlRegs.GPBDIR.bit.GPIO42 = 1;  //是 GP 输出
   GpioCtrlRegs.GPBDIR.bit.GPIO43 = 1;  //是 GP 输出
   GpioCtrlRegs.GPADIR.bit.GPIO27 = 1;  //是 GP 输出
   //通信数据位
   GpioCtrlRegs.GPADIR.bit.GPIO0 = 0;  // GPIO 是 GP 输入
   GpioCtrlRegs.GPADIR.bit.GPIO1 = 1;  // GPIO 为 GP 输出
   GpioCtrlRegs.GPADIR.bit.GPIO2 = 1;  // GPIO 为 GP 输出
   GpioCtrlRegs.GPADIR.bit.GPIO3 = 1;  // GPIO 是 GP 输入
   GpioCtrlRegs.GPADIR.bit.GPIO4 = 0;  // GPIO 是 GP 输入
   GpioCtrlRegs.GPADIR.bit.GPIO5=1;  // GPIO 是 GP 输出
   GpioCtrlRegs.GPADIR.bit.GPIO6 = 1;  // GPIO 为 GP 输出
   GpioCtrlRegs.GPADIR.bit.GPIO7 = 0;  // GPIO 是 GP 输入
   //数字数据
   GpioCtrlRegs.GPADIR.bit.GPIO8 = 0;  // GPIO 是 GP 输入
   GpioCtrlRegs.GPADIR.bit.GPIO25 = 0;  // GPIO 是 GP 输入
   GpioCtrlRegs.GPADIR.bit.GPIO2 = 0;  // GPIO 是 GP 输入
   GpioCtrlRegs.GPBDIR.bit.GPIO44 = 0;  // GPIO 是 GP 输入
   GpioCtrlRegs.GPBDIR.bit.GPIO41 = 0;  // GPIO 是 GP 输入
   GpioCtrlRegs.GPBDIR.bit.GPIO34 = 0;  // GPIO 是 GP 输入
   //禁用中断
   Dint;
   //结束对控制寄存器的编辑
   EDIS;

/*
 *本节设置 ADC 以读取输入电压
 *有5个输入可供读取,因此 SOC0至 SOC4是如此
 * ADC 操作由软件驱动,不使用任何中断。
 *采用一个简单的时间延迟来为 ADC 操作提供时间
 *
空 SetUpADC (空)

   EALLOW;
   //单次采样模式
   AdcRegs.ADCSAMPLEMODE.BIT.SIMULEN0 = 0x00;    //单次采样模式为0和1
   //ADC 端口 B-0 -TB_measure_A     引脚23
   AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 0x00;   /0x00表示软件触发 ADC 过程
   AdcRegs.ADCSOC0CTL.bit.CHSEL   = 0x08;   //SOC0 = ADC-IP B0引脚23
   AdcRegs.ADCSOC0CTL.bit.ACQPS   = 0x09;   //10个时钟周期采样周期
   //ADC 端口 B-1 -导弹_P44V_A   引脚24
   AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 0x00;   /0x00表示软件触发 ADC 过程
   AdcRegs.ADCSOC1CTL.bit.CHSEL   = 0x09;   //SOC1 = ADC-IP B1引脚24
   AdcRegs.ADCSOC1CTL.bit.ACQPS   = 0x09;   //10个时钟周期采样周期
   //单次采样模式
   AdcRegs.ADCSAMPLEMODE.BIT.SIMULEN2 = 0x00;    //单次采样模式用于2和3
   //ADC 端口 B-2 -28V_SENSE_A      引脚25
   AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 0x00;   /0x00表示软件触发 ADC 过程
   AdcRegs.ADCSOC2CTL.bit.CHSEL   = 0x0A;   //SOC2 = ADC-IP B2引脚25
   AdcRegs.ADCSOC2CTL.bit.ACQPS   = 0x09;   //10个时钟周期采样周期
   //ADC 端口 B-3 --44V_SENSE_A      引脚26
   AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 0x00;   /0x00表示软件触发 ADC 过程
   AdcRegs.ADCSOC3CTL.bit.CHSEL   = 0x0B;   //SOC3 = ADC-IP B3引脚26
   AdcRegs.ADCSOC3CTL.bit.ACQPS   = 0x09;   //10个时钟周期采样周期
   //单次采样模式
   AdcRegs.ADCSAMPLEMODE.BIT.SIMULEN4 = 0x00;    //单次采样模式用于4和5
   //ADC 端口 B-4 --TB_Good          引脚27
   AdcRegs.ADCSOC4CTL.bit.TRIGSEL = 0x00;   /0x00表示软件触发 ADC 过程
   AdcRegs.ADCSOC4CTL.bit.CHSEL   = 0x0C;   //SOC3 = ADC-IP B4引脚27
   AdcRegs.ADCSOC4CTL.bit.ACQPS   = 0x09;   //10个时钟周期采样周期
   EDIS;

/*
 *此代码用于将 LED 指示灯熄灭
 *
空初始化 LEDS (空)

   GpioDataRegs.GPADD.bit.GPIO22 = 0;//打开 LED3 (红色)
   GpioDataRegs.GPBDAT.bit.GPIO32 = 0;//打开 LED4 (红色)?
   GpioDataRegs.GPBDAT.bit.GPIO33 = 0;//打开 LED5 (红色)
   GpioDataRegs.GPADD.bit.GPIO23 = 0;//打开 LED6 (红色)
   GpioDataRegs.GPADD.bit.GPIO29 = 0;//打开 LED1 (绿色)?
   GpioDataRegs.GPADD.bit.GPIO26 = 0;//打开 LED2 (绿色)
   GpioDataRegs.GPADD.bit.GPIO9 = 0;//打开 LED7 (绿色)
   GpioDataRegs.GPADD.bit.GPIO28 = 0;//打开 LED8 (绿色)

   GpioDataRegs.GPADD.bit.GPIO22 = 1;//关闭 LED3 (红色)
   GpioDataRegs.GPBDAT.bit.GPIO32=1;//关闭 LED4 (红色)?
   GpioDataRegs.GPBDAT.bit.GPIO33 = 1;//关闭 LED5 (红色)
   GpioDataRegs.GPADD.bit.GPIO23 = 1;//关闭 LED6 (红色)
   GpioDataRegs.GPADD.bit.GPIO29 = 1;//关闭 LED1 (绿色)?
   GpioDataRegs.GPADD.bit.GPIO26 = 1;//关闭 LED2 (绿色)
   GpioDataRegs.GPADD.bit.GPIO9 = 1;//关闭 LED7 (绿色)
   GpioDataRegs.GPADD.bit.GPIO28 = 1;//关闭 LED8 (绿色)

/*
 *此代码初始化通信控制
 *
空初始化通信(空)

   //GpioDataRegs.GPADD.bit.GPIO1 = 0;             //允许 WCU 时钟输入
   GpioDataRegs.GPADAT.bit.GPIO1 = 1;             //测试禁用中的 WCU 时钟
   GpioCtrlRegs.GPAPUD.bit.GPIO0 = 1;       //禁用 PU
   GpioDataRegs.GPADAT.bit.GPIO2 = 1;             //允许数据输出
   GpioDataRegs.GPADAT.bit.GPIO5 = 0;             //允许 RTL 进入
   GpioDataRegs.GPADD.bit.GPIO6 = 1;             //允许 PMG 频率输出

/*
 *这是主函数
 *
/*
 *添加了以下'extern '语句以解决闪存问题。
 *
extern UINT16 RamfuncsLoadStart;
extern UINT16 RamfuncsLoadSize;
extern UINT16 RamfuncsRunStart;
//
extern UINT16 PieVectTableInit;

extern unsigned int econst_loadstart;
extern unsigned int econst_loadsize;
extern unsigned int econst_runstart;


void main (void)

   memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(uint32)&RamfuncsLoadSize);

   InitSysCtrl();
   InitGpio();
   Dint;

//在 attmept 中添加了以下行以解决闪存问题(SPRA958L 应用手册)。  
   /***初始化 PIE_RAM ***/
//   PieCtrlRegs.PIECTRL.bit.ENPIE = 0;//禁用 PIE
//   EALLOW;
//   memcpy (((uint16 *)&PieVectTable+6、(uint16 *)&PieVectTableInit+6、256-6);

   InitAdc();
   //初始化端口
   InitializePorts();
   //初始化 LED (关闭)
   IntialiseLEDS();
   //启用通信缓冲区
   InitializeComms();
   //配置 ADC
   SetUpADC();
   //读取 PMG 检测到的状态
   PMGConnected();
   IntialiseLEDS(); //odd -两个 LED 在应该关闭时亮起!!!!
   GpioDataRegs.GPBDAT.bit.GPIO32=1;
   GpioDataRegs.GPADAT.bit.GPIO29 = 1;
//测试代码
//结束测试代码
   while (1)
   {
       IF (LEDToggleCount = 20)
       {
           GpioDataRegs.GPADD.bit.GPIO22 = LED;                  //切换 LED
           LED =(!LED);
           LEDToggleCount = 0;
       }
       其他
       {
       LEDToggleCount++;
       }
       GpioDataRegs.GPADD.bit.GPIO26 = 0;//关闭 LED2 (绿色)
       GpioDataRegs.GPADD.bit.GPIO26 = 1;//关闭 LED2 (绿色)
   /*
    *现在,sequnce 只会无限重复....
    *或至少直到断电
    *
    *
   }

 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 John:

    您是否已将 CodeStartBranch.asm 文件包含在项目中?

    您是否已确保将器件配置为引导至闪存?

    这可能是您的问题所在。

    此致、
    SAL
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Sal、

    是的、CodeStartBracnch.asm 包含在工程中(可在 CCS 的 Project Explorer 窗口中看到)。 配置下还有 CodeStartBracnch.obj 条目。

    我"认为"我已将器件配置为引导至闪存... 但是、我很高兴看到有人引导我通过按钮进行按下、并选择选项、以确保正确无误。

    实际上、我一直在为该项目而担心这么长时间、我可能无意中设置了一个会增加问题的选项。

    如果我从头开始、并且有一个简单的代码位使几个 LED 闪烁(切换几个 GPIO 端口)、那么我需要设置什么选项来使代码在加电时从闪存运行? 如果我能超越这一点,我相信我能够向前迈进。

    感谢您的帮助。

    j

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您需要确认引导模式选择引脚已正确设置为引导至闪存。

    您还可以连接到器件并加载引导 ROM 符号。 然后使用 EMU 引导模式选项将器件设置为引导至闪存。 然后、您可以开始单步执行引导 ROM 以确保它分支到闪存入口点、还可以检查 codestartbranch codestart 段是否放置在该位置。 您可以在不运行引导 ROM 的情况下完成最后一部分。 您可以使用内存浏览器确认带有"LB _c_int00"的 codestart 段被放置在正确的位置。

    请访问 www.ti.com/.../sprugo0b.pdf

    此致、
    SAL
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Sal、

    感谢你的帮助。

    您建议的是修复此问题的引导选项引脚-特别是 GPIO34、我已连接到上电时为0V 的信号。 这会阻止器件启动到闪存中。 虽然相关文档中提到在加电时读取此引脚以确定启动模式、但数据表引脚配置页面将其描述为通用功能、我错过了这种情况会有问题。 幸运的是、该设计可以轻松更改。

    我确实让代码在闪存中工作、只是为了发现一些其他问题(全部分类)。

    当单步执行代码时、这些步骤在与代码无关的序列中跳转。 通过将"optimization"(优化)选项设置为 off (关闭)来解决此问题。 如果为了速度目的需要优化、我该如何单步执行代码并了解我在哪里? 此外、我发现正在优化局部变量(即在简单延迟环路中)、这样代码就不会运行。 最初、我通过将 count 变量设置为全局变量(不是理想值)来解决此问题。 当优化被关闭时、问题似乎已经消失、我可以有局部变量。 优化器的这种正常行为是否正常?

    再次感谢您的帮助

    j
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 John:

    当您在代码生成工具中打开优化器时、编译器将优化指令。 很多时候、这意味着删除不必要的代码并重新排序操作。

    如果您需要确保对存储器位置或变量(例如局部变量)的访问未进行优化、则需要使用易失性密钥字将它们声明为"volatile"。 您无需将变量设为全局变量、只需使用 volatile 关键字进行声明。

    此致、
    SAL