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.

[参考译文] SM320F28335-EP:生成异常的 sprintf 函数出现问题

Guru**** 2535750 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/592866/sm320f28335-ep-problem-with-sprintf-function-that-generate-an-exception

器件型号:SM320F28335-EP

您好!

我正在使用 F28335 EP Micro。

我使用在闪存中保存和运行代码的链接器文件。

现在我尝试使用 sprintf 函数、但当微控制器执行它时、系统会生成异常并完成工作。

我在互联网上搜索、我发现这是一个常见问题。 我也关注论坛上的一些主题(链接 ),但它对我没有帮助。

我在链接器中将堆栈更改为0x800、堆大小更改为0x800、但它仍然不起作用。

我注意到、如果我用这种方式编写"sprintf (buff、"Test");"它可以正常工作。 但是、如果我以这种方式编写函数"sprintf (buff、"Test %d"、var);"它会失败并生成异常。

我尝试了我在论坛上找到的所有建议、但我无法在项目中使用 sprintf。

非常感谢你的帮助。

此致、
Andrea  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    安德烈
    您能否发布所做更改的相关文件?
    现在、我要将其移至 C2000论坛。 它们可以提供更好的调试见解。
    此致、
    涉水
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我在 F28335 cmd 上做了一些工作,并修改了此部分:
    堆栈 :> RAML5 PAGE = 1 (原始为.stack :> RAMM1 页= 1)

    我使用闪存存储器来存储和运行程序。

    我使用的完整文件发布如下:

    /*
    //######################################################################################################################
    //
    //文件:F28335.cmd
    //
    //标题:F28335器件的链接器命令文件
    //
    //######################################################################################################################
    //$TI 发行版:F2833x/F2823x 头文件和外设示例 V142 $
    //$Release Date:2016年11月1日$
    //版权所有:版权所有(C) 2007-2016德州仪器(TI)公司-
    // http://www.ti.com/ 保留所有权利$
    //######################################################################################################################
    *

    /*===================================================================
    //适用于 Code Composer Studio V2.2和更高版本
    //--------------------------------------------------------
    //除了该内存链接器命令文件外,
    //将头文件链接器命令文件直接添加到工程中。
    //链接时需要标头链接器命令文件
    //将外设结构设置到内部的适当位置
    //存储器映射。
    //
    //在中找到了头文件链接器文件 \DSP2833x_Headers\cmd
    //
    //对于 BIOS 应用程序,添加: DSP2833x_Headers_BIOS.cmd
    //对于非 BIOS 应用程序添加:DSP2833x_Headers_nonBIOS.cmd
    =================================================================================================== *

    /*===================================================================
    //对于 V2.2之前的 Code Composer Studio
    //--------------------------------------------------------
    // 1)使用以下-l 语句之一来包含
    //项目中的头链接器命令文件。 头文件链接器
    //将外设结构链接到正确的文件
    //存储器映射中的位置 *

    /*取消注释此行以仅包括非 BIOS 应用程序的文件*/
    /*-l DSP2833x_Headers_nonBIOS.cmd */

    /*取消注释此行以仅包括 BIOS 应用程序的文件*/
    /*-l DSP2833x_Headers_BIOS.cmd */

    /* 2)在项目中添加路径 \DSP2833x_headers\cmd 至
    库搜索路径位于 project->build options、linker tab、
    库搜索路径(-I)。
    /*================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================ *

    /*定义 F28335的内存块开始/长度
    PAGE 0将用于组织程序段
    第1页将用于组织数据段

    注:
    F28335上的存储器块是一致的(即相同的
    物理存储器)。
    不应该是相同的存储器区域
    同时为 PAGE 0和 PAGE 1定义。
    这样做将导致程序损坏
    和/或数据。

    L0/L1/L2和 L3存储器块被镜像-即
    它们可以在高内存或低内存中访问。
    为简单起见、其中仅使用了一个实例
    链接器文件。

    可组合连续 SARAM 存储器块
    如果需要创建更大的存储器块。
    *


    存储器

    第0页:/*程序内存*/
    /*内存(RAM/FLASH/OTP)块可移动到第1页进行数据分配*/

    ZONE0 :origin = 0x004000、length = 0x001000 /* XINTF 区域0 */
    RAML0 :origin = 0x008000、length = 0x001000 /*片上 RAM 块 L0 */
    RAML1. :origin = 0x009000,length = 0x001000 /*片上 RAM 块 L1 */
    RAML2. :origin = 0x00A000、length = 0x001000 /*片上 RAM 块 L2 */
    RAML3. :origin = 0x00B000、length = 0x001000 /*片上 RAM 块 L3 */
    ZONE6 :origin = 0x0100000、length = 0x100000 // XINTF 区域6 */
    ZONE7A :origin = 0x0200000、length = 0x00FC00 /* XINTF 区域7-程序空间*/
    FLASHH :origin = 0x300000、length = 0x008000 /*片上闪存*/
    FLASHG :origin = 0x308000、length = 0x008000 /*片上闪存*/
    FLASHF :origin = 0x310000,length = 0x008000 /*片上闪存*/
    FLASHE :origin = 0x318000、length = 0x008000 /*片上闪存*/
    FLASHD :origin = 0x320000,length = 0x008000 /*片上闪存*/
    FLASHC :origin = 0x328000、length = 0x008000 /*片上闪存*/
    FLASHA :origin = 0x338000、length = 0x007F80 /*片上闪存*/
    csm_RSVD:origin = 0x33FF80,length = 0x000076 /* FLASHA 的一部分。 当 CSM 正在使用时、使用所有0x0000进行编程。 *
    开始 :origin = 0x33FFF6、length = 0x000002 /* FLASHA 的一部分。 用于"引导至闪存"引导加载程序模式。 *
    CSM_PWL :origin = 0x33FFF8,length = 0x000008 /* FLASHA 的一部分。 FLASHA 中的 CSM 密码位置*/
    OTP :origin = 0x380400,length = 0x000400 /*片上 OTP */
    ADC_CAL :origin = 0x380080、length = 0x000009 保留存储器中的/* ADC_cal 函数*/

    IQTABLES:origin = 0x3FE000,length = 0x000b50 /*引导 ROM 中的 IQMath 表*/
    IQTABLES2:origin = 0x3FEB50,length = 0x00008c /*引导 ROM 中的 IQMath 表*/
    FPUTABLES:origin = 0x3FEBDC,length = 0x0006A0 /*引导 ROM 中的 FPU 表*/
    ROM :origin = 0x3FF27C、length = 0x000D44 /*引导 ROM */
    复位 :origin = 0x3FFFC0,length = 0x000002 /*引导 ROM 的一部分*/
    矢量 :origin = 0x3FFFC2,length = 0x00003E /*引导 ROM 的一部分*/

    第1页:/*数据存储器*/
    /*内存(RAM/FLASK/OTP)块可被移动至 PAGE0以进行程序分配*/
    /*寄存器保留在第1页上 *

    BOOT_RSVD:origin = 0x000000,length = 0x000050 // M0的一部分,引导 ROM 将此用于堆栈*/
    RAMM0 :origin = 0x000050、length = 0x0003B0 /*片上 RAM 块 M0 */
    RAMM1 :origin = 0x000400、length = 0x000400 /*片上 RAM 块 M1 */
    RAML4. :origin = 0x00C000、length = 0x001000 /*片上 RAM 块 L1 */
    RAML5. :origin = 0x00D000、length = 0x001000 /*片上 RAM 块 L1 */
    RAML6. :origin = 0x00E000、length = 0x001000 /*片上 RAM 块 L1 */
    RAML7. :origin = 0x00F000、length = 0x001000 /*片上 RAM 块 L1 */
    ZONE7B :origin = 0x20FC00,length = 0x000400 /* XINTF 区域7 -数据空间*/
    FLASHB :origin = 0x330000、length = 0x008000 /*片上闪存*/


    /*将段分配给内存块。
    注:
    DSP28_CodeStartBranch.asm 中用于重定向代码的 codestart 用户定义段
    闪存时执行
    ramfuncs 用户定义的段来存储将从闪存复制到 RAM 中的函数
    *

    部分


    /*分配计划领域:*/
    /*闪存 API 函数可以按如下所示组合在一起。
    定义的符号_Flash28_API_LoadStart、_Flash28_API_LoadEnd
    和_Flash28_API_RunStart 用于将 API 函数复制出
    闪存存储器的内存空间、并加至 SARAM */

    Flash28_API:

    -lFlash28335_API_V210.lib (.econst)
    -lFlash28335_API_V210.lib (.text)
    } 负载= FLASHD、
    运行= RAML0、
    Load_start (_Flash28_API_LoadStart)、
    Load_End (_Flash28_API_LoadEnd)、
    RUN_START (_Flash28_API_RunStart)、
    PAGE = 0
    .cinit :> FLASHA PAGE = 0
    .pinit :> FLASHA、 PAGE = 0
    .text :> FLASHA PAGE = 0
    codestart :>开始 PAGE = 0
    ramfuncs :LOAD = FLASHD,
    运行= RAML0、
    load_start (_RamfuncsLoadStart)、
    load_end (_RamfuncsLoadEnd)、
    run_start (_RamfuncsRunStart)、
    load_size (_RamfuncsLoadSize)、
    PAGE = 0

    csmpasswds :>CSM_PWL PAGE = 0
    csm_rsvd :>csm_RSVD page = 0

    /*分配未初始化的数据段:*/
    堆栈 :> RAML5 PAGE = 1.
    ebss :> RAML4 PAGE = 1.
    等斯梅姆 :> RAMM1 PAGE = 1.

    /*初始化段进入闪存*/
    /*要使 SDFlash 对这些内容进行编程、必须将它们分配到第0页*/
    .econst :> FLASHA PAGE = 0
    切换 :> FLASHA PAGE = 0

    /*分配 IQ 数学区域:*/
    IQMath :> FLASHC PAGE = 0 /*数学代码*/
    IQmathTables :> IQTABLES,PAGE = 0,TYPE = NOLOAD

    /*如果调用 IQNexp()或 IQexp(),请取消注释以下部分
    库中的函数、以便利用
    引导 ROM 中的相关 IQ Math 表(这可以节省空间和引导 ROM
    1个等待状态)。 如果此部分未注释、则为 IQmathTables2
    将被加载到其他存储器(SARAM、闪存等)中并将采用
    上行空间、但0等待状态是可能的。
    *
    /*
    IQmathTables2:> IQTABLES2,PAGE = 0,TYPE = NOLOAD


    IQMath.lib (IQmathTablesRam)


    *

    FPUmathTables:> FPUTABLES,PAGE = 0,TYPE = NOLOAD

    /*分配可通过 DMA 访问的 RAM 段:*/
    DMARAML4. :> RAML4, PAGE = 1.
    DMARAML5. :> RAML5, PAGE = 1.
    DMARAML6. :> RAML6, PAGE = 1.
    DMARAML7. :> RAML7, PAGE = 1.

    /*分配 XINTF 区域7的0x400来存储数据*/
    ZONE7DATA :>ZONE7B,PAGE = 1.

    /*.reset 是编译器使用的标准段。 它包含*/
    /* C 代码_c_int00起始地址。 /*
    /*当使用引导 ROM 时,此部分和 CPU 矢量*/
    /*不需要表。 因此、默认类型设置为*/
    /* DSECT */
    复位 :>重置, PAGE = 0、TYPE = DSECT
    矢量 :>引导程序 PAGE = 0、TYPE = DSECT

    /*分配 ADC_cal 函数(出厂时已预先编程到 TI 保留存储器中)*/
    .adc_cal :LOAD = ADC_CAL、PAGE = 0、TYPE =空载



    /*
    //============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
    //文件结束。
    //============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
    *


    如何处理 sprintf 函数?

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

    很抱歉我没能早点回来。 您是否仍有此问题?

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

    是的、

    我仍然遇到 sprintf 问题。

    我按照某些论坛中的建议增加了堆和堆栈大小、但对我不起作用。

    你对我有什么建议吗?

    谢谢你。

    此致、

    Andrea

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

    您能告诉我有关 buff 变量的更多信息吗? 如何以及在何处声明它? 我想知道它的存储位置。

    您遇到了什么例外情况? 您能给我提供更多详细信息吗?

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

    尊敬的惠特尼:

    非常感谢您的支持、很抱歉耽误您的时间、但我必须继续进行我的项目。

    今天、为了回答您的问题、我进行了进一步的测试。

    我的代码如下:

    unsigned char 爆炸 F28335_Setup()

    unsigned char explorerF28335_setup_status = EXPL_F28335_NO_ERROR;

    char bubuy[50];

    unsigned char temp_test = 10;

      爆炸 F28335_initio();

      爆炸 F28335_InitTimer();

      爆炸 F28335_InitSCI();

      sprintf (buff、"测试 printf");             /*This function go weel and the program go forward*/

      SCIX_SendString (SCI_A_ID、&buff [0]);

      sprintf (buff、“测试 printf %d”、temp_test);/*此函数不起作用并导致错误

      SCIX_SendString (SCI_A_ID、&buff [0]);

    #if debug_mode

      SCIX_SendString (SCI_A_ID、"Hello I m the TI Explorer board kit \n");

      SCIX_SendString (SCI_A_ID、"板 IO 初始化完成\n");

      SCIX_SendString (SCI_A_ID、"定时器初始化完成\n");

      SCIx_SendString (SCI_A_ID、"SCI Init Complete \n");

    #endif

      return (explorerF28335_setup_status);

    }/**/;

    我注意到、第一个 sprintf 运行良好、而第二个 sprintf 具有无法控制的行为并阻止微控制器。

    我附加到调试设置的两个映像以及执行前后的步骤。

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

    1.如果删除了所有断点,您是否仍然在控制台中得到此仿真错误,或者您是否得到了与 ITRAP 或类似的错误类型不同的错误?

    2.作为一个实验,你能否尝试注释掉第一个 sprintf,看看第二个 sprintf 是否仍然失败?

    3.我注意到您的链接器命令文件显示堆栈和一些与 DMA 相关的部分都在 LS5中。 您是否将 DMARAML5用于 DMA? 我只想确保 DMA 不会破坏您的堆栈。

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

    您是否解决了此问题?

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

    尊敬的惠特尼:
    感谢您的发帖。

    现在、我正忙于处理项目的文档。

    我只执行了测试1和2、但我遇到了相同的问题。 我还尝试刷写微控制器并在没有调试器的情况下运行应用程序,因此没有早餐, 但执行时 sprintf 以相同的方式失败。

    下周我想检查第3点。 我认为这可能是调试过程中的一个正确步骤。

    很抱歉耽误你的时间。
    再次感谢您的支持和建议。

    此致、
    Andrea