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.

[参考译文] 编译器/MSP432E401Y:可变参数函数蓝调?

Guru**** 2558250 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/891277/compiler-msp432e401y-variadic-function-blues

器件型号:MSP432E401Y

工具/软件:TI C/C++编译器

您好!

尝试将可变参数函数与可变数量的争论一起使用时、我遇到了以下问题:

使用的 snprintf()函数对 fmt 或格式字符串有效。 但是、格式化字符串之后的参数变量列表会"打印"栈的地址、而不是栈的内容。 堆栈地址正确。 单步执行调试代码并使用内存浏览器、我可以验证堆栈内容是否正确。 但是、正在打印栈地址而不是内容。

有什么想法我做了什么错?

使用 TI-CCS 9.2 TI-Comiler:18.12.3

simplelink_msp432e4_sdk_3_20_00_10

这是我的代码块、它可以简单地打印 snprintf... 缓冲区中。 RAM 缓冲器、用于在此上下文中进行后续重检。

空 MyLog2RAM (char *fmt、...) {

   /*声明 va_list 类型变量*/
   va_list var_args;

   int n;

   /*锁定*/
   SEM_WAIT (互斥 MakeRetentant);

   /*使用...初始化 va_list 变量 fmt 之后*/
   va_start (var_args、fmt);

   n = snprintf (strSysLogRAM.ptrLog2RAMNext、strSysLogRAM.uiRAMFree、fmt、var_args);

   如果(0 > n){/*'cat' a potential error */

       /*解锁*/
       SEM_post (mutexMakeRetentant);

       /*清理 va_list */
       va_end (var_args);
       返回;
   }

   /*更新 RAM 缓冲器结构。 'n'等于字符数,不包括(!)
    *'\0'终止字符。 因此可以放置下一个字符串
    *在下一个可能的位置 n+1处。 这可能是最后一个
    *消息被"截断"。 我们接受这种做法、以使事情变得简单。
    *

   N++;

   if ( strSysLogRAM.uiRAMFree >= n ){

       strSysLogRAM.ptrLog2RAMNext += n;
       strSysLogRAM.uiMsg++;
       strSysLogRAM.uiRAMUSed     += n;
       strSysLogRAM.uiRAMFree     --= n;

   }

   if (0 == strSysLogRAM.uiRAMFree){

       strSysLogRAM.ptrLog2RAMNext = cBuffRAMLog;
   }

   /*解锁*/
   SEM_post (mutexMakeRetentant);

   /*清理 va_list */
   va_end (myargs);

}// MyLog2RAM

执行相同的操作、但使用 TI 内置的 Display 函数 Display_printf (...) 它的工作原理。 但它确实会打印到串行端口。

宏扩展看起来是一样的。 但是,代码/编译器中的某个位置必须有错误?

是否有任何关于我接下来可以做些什么来找出其根本原因的想法?

Markus

这个扩展的宏可以工作:

执行{
   if (DBGLVL_INFO >= iDebugLevel){
       Display_doPrintf (dbgInfo、0、0、->调试信息:"复位原因%d\n"、(SYSCTL_Type            *)(((uint32_t) 0x400FE000))->RESC);
       }
  } while (0)

在串行端口终端上打印以下内容: ->调试信息:复位原因19、正确

这个扩展的宏不起作用:

执行{
   if (DBGLVL_INFO >= iDebugLevel){
       MyLog2RAM (->调试信息:"复位原因%d\n"、((SYSCTL_Type            *)((uint32_t) 0x400FE000)->RESC);
       }
   } while (0)

它会将以下内容"打印"到 RAM 缓冲区: ->调试信息:复位会导致 53674196、这是错误的?!

十六进制值是这个大十进制数:0x_2000_0CD4、它位于 MSP432的 RAM 部分。 在单步执行代码时使用内存浏览器、我得到"0x13 00 00"、这实际上是十进制标识中的 int 值为19。 没错。 但是、为什么打印的是栈地址而不是栈内容?

在两个版本中,调用宏语句都是相同的:DBGI (“重置原因%d\n",sysctl->RESC);

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

    >n = snprintf (strSysLogRAM.ptrLog2RAMNext、strSysLogRAM.uiRAMFree、fmt、var_args);

    请尝试 vsnprintf():

    >n = vsnprintf (strSysLogRAM.ptrLog2RAMNext、strSysLogRAM.uiRAMFree、fmt、var_args);

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

    您好、Bruce、

    谢谢! 这就是问题所在。 这里将介绍 snprintf 与 vsnprintf 的关系

    www.ibm.com/.../vsnprintf.htm

    都是如此。 谢谢!

    BR

    Markus

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

    谢谢!