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.

[参考译文] 编译器/F28M36P63C2:将字节数组转换为包含浮点值的结构

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/594306/compiler-f28m36p63c2-casting-byte-array-to-struct-containing-floats

器件型号:F28M36P63C2
Thread 中讨论的其他器件:SYSBIOS

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

我有以下结构、它们在 M3和 C28处理器之间共享、并由 PC 通过以太网和共享存储器提供值。 我将从 PC 向 M3和 C28发送相同的数据值。 然后、我将数据缓冲区转换到 PIDCTRL 结构中、并使用以下代码打印该结构的值:

typedef struct _PIDCTRL
{
Float32 设定点;
Float32 公差;
Float32. Kp;
Float32. Ki;
Float32 KD;
Float32. maxOutput;
Float32 最小输出;
UINT16 PIDEnable;
UINT16 状态;
uint16 minStableTimeSec;
uint16 maxSettingTimeSec;
uint16 周期;
uint16 保留;
uint16 字段;
}PIDCTRL; 

// C28 / M3

uint_least8_t 的代码相同* replyData = 

PIDCTRL *pid =(PIDCTRL *) replyData;

DbgInfo ("设置:%f %f %f %f %f %f %f %f %f %u %u %x %x %x"、
pid->SetPoint、pid->Tolerance、pid->Kp、pid->Ki、pid->Kd、pid->minOutput、 PID->maxOutput、pid->minStableTimeSec、pid->maxSettingTimeSec、
replyData[0]、replyData[1]、replyData[2]、replyData[3]);

我正在发送数据值(1.0、2.0、3.0、... 9.0)、这就是我看到的内容。 M3正确地转换并正确打印数据、但 C28不能正确转换浮点、只能转换 uint16字段。

 M3设置:1.0000 2.0000 3.0000 4.0000 5.0000 8.0000 9.0000 6 7             0 80 3f
 C28设置:0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 6 7           0 3f80 0 4000

我还打印了原始缓冲区的前4个字、注意到字节在 C28中交换、我认为 C28和 M3都是小端字节序、并且具有相同的 IEEE 754浮点值。 我是否遗漏了明显的东西?

这里还提供了一些其他信息。 函数 DbgInfo 在内部使用'System_vsnprintf'来打印格式化的值,并且我已将'System.extendedFormats ="%$L%$S%$F%f%f"添加到.cfg 文件中,以便打印可以使用扩展格式。 如果我在 PID_CONF 结构中手动设置浮点字段(例如 pid->KP = 5.324)、我还验证了打印在 C28上是否正常工作。 我已经尝试修改了结构打包、但这似乎也没有帮助。

Derek

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

    那么、replyData 是否指向共享存储器? 另外,我想弄清楚 PIDCTRL 是什么样的--你已经共享了 PID_CONF,它似乎有一些相同的字段,但不是全部。 您能澄清一下吗?

    谢谢、
    惠特尼
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Whitney。 抱歉、我在问题中输入了错误的结构! 我使用 PIDCTRL 结构更新了原始帖子。

    replyData 不在共享存储器中、数据从共享存储器复制到 L0-L3中。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您的澄清。 原始数据看起来是我所期望的。 仍然不确定为什么浮点数不是正确的。 DbgInfo()有什么变化?

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

    它会构建字符串消息并通过自定义协议将其发送回控制台进行打印。 DbgInfo 最终会调用此函数来构建消息并将其发送(通过共享存储器和以太网返回到 PC 以进行输出)。

    ERROR_code TFProtocolDebug::SendMsg (级别、char*格式、...)
    {
    ERROR_code eResult = TFE_Uninitialized;
    
    TFTempBuffer myBuf (160);
    va_list _va;
    va_start (_va、格式);
    #if defined (__TI_ARM_V7M3__)|| defined (__TMS320C28XX__)
    // TI RTOS:ARM Cortex M3或 C28 DSP
    //
    system_vsnprintf (myBuf、myBuf.size ()、format、__va);
    #elif defined (__linux__)
    vsnprintf (myBuf、myBuf.size ()、format、__va);
    #else
    // Windows
    //
    vsprintf_s (myBuf、myBuf.size ()、format、__va);
    #endif
    va_end (_va);
    
    if (初始化){
    if (level <= maxOutputLevel){
    //根据传入参数构造基本输出字符串
    TFProtocolMsg * pMsgBufPtr;
    
    //获取缓冲区,以便我们可以发送消息
    //
    eResult = pTfRouter->GetMessageBuffer(&pMsgBufPtR);
    if (eResult =TFE_SUCCESS)
    {
    
    //获取指向有效载荷的指针并将其转换为我们的消息类型
    //
    TFProtocolDebugMsg * pDebugMsg = reinterpret_cast (pMsgBufPtr ->有效载荷);
    if (pDebugMsg == nulptr)
    {
    eResult = tfe_invalid;//如果我们得到 NULL 指针(安全检查)
    ,不要崩溃}
    其他
    {
    TFTempBuffer myCopy (bytes_to 八位位组(160));
    strncpypack (((char*) myCopy.ptr()、八位位组到字节(myCopy.size())、(const char*) myBuf);
    tf_uint16 len =(tf_uint16) strlen (myBuf);
    pDebugMsg->level = level;
    pDebugMsg->length = len + 1;
    memcpy (pDebugMsg->text、myCopy.ptr ()、bytes_TO_octaget (pDebugMsg->length));
    
    //准备要发送的消息
    //
    eResult = FinalizeMessage (目的、
    (tf_uint16)(BYTESOF (pDebugMsg->level)+ BYTESOF (pDebugMsg->length)+ pDebugMsg->length)、
    pMsgBufPtr);
    
    #ifdef __big_ENDIAN__
    //协议必须负责字节交换其标头数据
    pDebugMsg->level = htole16 (pDebugMsg->level);
    pDebugMsg->length = htole16 (pDebugMsg->length);
    #endif
    
    
    if (eResult =TFE_SUCCESS)
    {
    //途中发送消息
    //
    eResult = pTfRouter->SendMessage (&pMsgBufPtr);
    }
    
    }
    
    }否则{
    eResult = TFE_SUCCESS;
    }
    }
    返回 eResult;
    }
    

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

    只是一些更新。 通过将数据复制到本地缓冲区并转换本地缓冲区、我能够使其正常工作:

    uint_least8_t * replyData = 
    
    tf_int8 size = sizeof (PIDCTRL);
    tf_uint8 buf[size];
    memcpy (buf、replyData、size);
    
    
    PIDCTRL *pid =(PIDCTRL *) buf;//这起作用 

    我还打印了 replyData (@0000996d)和 buf (@0000a04c)的地址、它们都根据我的 cmd 文件位于 L0-3 SARAM 中:

     L03SARAM                 :origin = 0x008000、length = 0x004000
     S04SHRAM                  :origin = 0x00C000、length = 0x005000

    映射文件将此区域指定为 HeapMem:

    00008100    204 (00008100)    _ti_sysbios_堆_HeapMem_instance_State_0_Buf_A
    0000e104    384 (0000e100)    _m3/ipc_func_addr

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

    我尝试将"plyData"缓冲器放置在存储器的不同位置(L0-L3、S0-S4 (C28是主器件)、甚至是 M0-1)、它们都表现出相同的错误转换症状。

    我还尝试对 temp 缓冲区执行 memcpy、然后将 temp 缓冲区恢复到原始"plyData"缓冲区中、执行了强制转换、但仍然不起作用。

    目前、我只是使用 memcopying 数据和使用该缓冲区的权变措施、但这并不理想。 我开始认为这是编译器问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您的更新。 我的直觉是、在线路的某个位置、C28上的16位字符和 M3上的8位字符会导致一些问题、但我不确定您所描述的实验和结果是否一定支持该理论。

    您是否能够使用 CCS 中的存储器浏览器研究各种缓冲器和字符串、或者您当前仅限于使用 print 语句进行调试?

    惠特尼