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.

[参考译文] TM4C123GH6PM:使用子串时出现 GrStringGet 错误

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/568693/tm4c123gh6pm-grstringget-bug-when-utilizing-sub-string

器件型号:TM4C123GH6PM

   

这是 Tiva 图形库版本2.1.3.156中 GrStringGet 的错误报告;我已经找到了一个解决方案。

我使用的 CSV 文件包含转换后的字符串。  它被转换为未压缩的字符串表,并带有"mkstringtable -u..."。  在文件的一行中、我具有与等效的内容

   "1234567890abcd"、"12345678"、...

第二个字符串是通过引用第一个字符串(其中第一个字符串是前八个字符)通过 mkstringtable 进行编码的。  当使用 GrStringGet ()请求第二个字符串时,我得到了正确的八个字符,之后是两个随机更改的字符(可能是栈上剩余的内容)。  此外,发生这种情况时,GrStringGet()返回的是0,而不是8 (正确的字符串长度)或10 (strlen()报告的返回字符串的实际长度)。  

有问题的字符串正由 GrStringGet ()中的第二个位置处理,注释为“将字符串的这一部分复制到输出缓冲区”。  大多数其他字符串(工作正常)由以下情况处理、注释为"现在复制字符串的最后一部分"。  后一个(工作)案例以以下代码结尾:

//如果我们在遇到本例之前没有复制任何字符,
//初始化输出指针(这会将代码保留在末尾
//返回长度快乐的函数)。 这将是
//假设我们使用未压缩的字符串表。
//
if (!pui8BufferOut)

  pui8BufferOut =(uint8_t *) pcData +(i32Idx + i32Buf);

我认为将该代码添加到有问题的部分可以解决该问题、但我在不添加代码的情况下也完成了同样的操作、方法是重新排列如何嵌套"if"语句、使这两种情况都执行该代码。  我看不到附加文件的方法; 如果找不到文件、我将至少跟踪代码的一个片段。

Steve

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

    这是我的 GrStringGet()的修改版本:

    //
    //
    //! 此函数从当前字符串表返回字符串。
    //!
    //! \param i32Index 是要检索的字符串的索引。
    //! \param pcData 是用于存储字符串的缓冲区的指针。
    //! \param ui32Size 是 pcData 提供的缓冲区的大小。
    //!
    //! 此函数将从字符串表中返回一个字符串,其语言
    为//! 由 GrStringLanguageSet()函数设置。 在\e iIndex
    //!中传递的值 参数是被请求的字符串、将在
    //中返回! 在\e pcData 参数中提供的缓冲区。 数据量
    //! 返回的值将受到 ui32Size 参数的限制。
    //!
    //! return 返回在\e pcData 缓冲区中返回的有效字节数。
    ////
    *****************
    uint32_t
    GrStringGet (int32_t i32Index、char * pcData、uint32_t ui32Size)
    {
    uint32_t ui32Len、ui32Offset、ui32SubCode[16];
    int32_t i32Pos、i32Idx、i32Bit、i32Skip、i32Buf;
    uint8_t * pui8BufferOut;
    const uint8_t * pui8String;
    
    assert (i32Index < g_ui16NumStrings);
    assert(pcData !=0);
    
    //
    //初始化输出缓冲器状态。
    //
    i32Pos = 0;
    pui8BufferOut = 0;
    
    //
    //如果由另一个字符串组成,我们需要处理它
    //这可以嵌套多个层,所以我们继续
    //
    ui32SubCode[i32Pos]= g_pui32StringTable[(g_ui16Language *
    g_ui16NumStrings)+ i32Index];
    
    if (sc_get_LEN (ui32SubCode[i32Pos]))
    {
    //
    //递归
    //
    while (i32Pos < 16)
    {
    //
    //从之前的字符串复制部分(如果有)。
    //
    i32Idx = SC_GET_INDEX (ui32SubCode[i32Pos++]);
    
    ui32SubCode[i32Pos]= g_pui32StringTable[(g_ui16Language *
    G_ui16NumStrings)+
    i32Idx];
    
    if (!sc_get_LEN (ui32SubCode[i32Pos]))
    {
    //
    //未链接,只需字符串
    //
    中断;
    }
    }
    
    
    //
    //现在向后工作。
    //
    i32Idx = 0;
    
    //
    //将字符串分成几个部分。
    //
    while (i32Pos >= 0)
    {
    //
    //在字符串表中获取偏移量。
    //
    ui32Offset = SC_GET_OFF (ui32SubCode[i32Pos]);
    
    if (ui32Offset = SC_is_NULL)
    {
    //
    //空字符串。
    //
    pcData[i32Idx]= 0;
    }
    否则、IF (ui32Offset 和 SC_FLAG_COMPLEed)
    {
    //
    //这是一个压缩字符串,因此初始化指向的指针
    //压缩数据。
    //
    pui8String = g_pui8StringData +(ui32Offset & SC_OFFSET_M);
    
    //
    //初始化位变量。
    //
    i32Bit = 0;
    i32Skip = 0;
    
    //
    //指向当前缓冲区输出位置。
    //
    pui8BufferOut =(uint8_t *) pcData + i32Idx;
    
    //
    //如果 OUT 缓冲区超出最大大小,则只需中断即可
    //输出并返回到目前为止我们拥有的内容。
    //
    if ((char *) pui8BufferOut >(pcData + ui32Size))
    {
    中断;
    }
    
    //
    //现在通过解压缩位来构建实数字符串。
    //
    if (!sc_get_LEN (ui32SubCode[i32Pos])&&
    SC_GET_INDEX (ui32SubCode[i32Pos])
    {
    i32Skip = SC_GET_INDEX (ui32SubCode[i32Pos]);
    
    if (i32Pos)
    {
    ui32Len = SC_GET_LEN (ui32SubCode[i32Pos - 1]);
    }
    其他
    {
    ui32Len =(i32Skip & 0x3f);
    }
    
    i32Skip >=6;
    i32Idx += ui32Len;
    ui32Len += i32Skip;
    }
    否则 if (i32Pos)
    {
    //
    //获取部分字符串的长度。
    //
    ui32Len = SC_GET_LEN (ui32SubCode[i32Pos - 1])- i32Idx;
    i32Idx += ui32Len;
    }
    否则、如果(!sc_get_LEN (ui32SubCode[0])&&
    SC_GET_INDEX (ui32SubCode[0])
    {
    ui32Len = SC_GET_INDEX (ui32SubCode[0]);
    i32Skip = ui32Len >> 6;
    ui32Len =(ui32Len & 0x3f)+ i32Skip;
    }
    其他
    {
    //
    //任意作为空字符结束字符串。
    //
    ui32Len = 1024;
    }
    
    for (;ui32Len;ui32Len--)
    {
    //
    //为每个字符打包6位
    //
    *pui8BufferOut =(* pui8String >> i32Bit)& 0x3f;
    
    if (i32Bit >= 2)
    {
    *pui8BufferOut |=(*++pui8String <<(8 - i32Bit))& 0x3f;
    }
    
    i32Bit =(i32Bit + 6)& 0x7;
    
    if (!* pui8BufferOut)
    {
    //
    //字符串末尾
    //
    中断;
    }
    
    if (i32Skip)(i32Skip)
    {
    i32跳过--;
    继续;
    }
    
    //
    //将删除的位放回
    //
    *pui8BufferOut |= 0x40;
    
    //
    //现在查找我们映射到其他的几个特殊字符
    //字符。
    //
    if (* pui8BufferOut ='`')
    {
    *pui8BufferOut =';
    }
    否则 if (*pui8BufferOut ='~')
    {
    *pui8BufferOut ='-';
    }
    否则 if (*pui8BufferOut =0x7f)
    {
    *pui8BufferOut ='.';
    }
    否则,如果(*pui8BufferOut ='\')
    {
    *pui8BufferOut =':';
    }
    
    //
    //增加指针,如果指针现在,则中断
    //超出提供的缓冲区的末尾。
    //
    pui8BufferOut++;
    
    if ((char *) pui8BufferOut >=(pcData + ui32Size))
    {
    中断;
    }
    }
    
    否则 if (i32Pos)
    {
    //
    //另一个字符串的一部分
    //
    ui32Len = SC_GET_LEN (ui32SubCode[i32Pos - 1])- i32Idx;
    
    //
    //防止此副本超出缓冲区的末尾
    //已提供。
    //
    if ((i32Idx + ui32Len)> ui32Size)
    {
    ui32Len = ui32Size - i32Idx;
    }
    
    //
    //将字符串的这一部分复制到输出缓冲区。
    //
    for (i32Buf = 0;i32Buf < ui32Len;i32Buf++)
    {
    pcData[i32Idx + i32Buf]= g_pui8StringData[ui32Offset +
    i32Buf];
    }
    
    i32Idx += ui32Len;
    }
    其他
    {
    if (sc_get_index (ui32SubCode[0])&&!sc_get_LEN (ui32SubCode[0])}
    {
    //
    //将字符串的这一部分复制到输出缓冲区。
    //
    for (i32Buf = 0;i32Buf < SC_GET_INDEX (ui32SubCode[0]);i32Buf++)
    {
    if ((i32Idx + i32Buf)< ui32Size)
    {
    pcData[i32Idx + i32Buf]= g_pui8StringData}
    
    
    
    
    
    
    
    
    
    
    
    ;{i32Idx + i32Buf]}字符串的最后一个/{u32Offset}/}次/{i32Buf}次/}次/次/次/次/次/次/次/次/次/次/次/次/次/次/次
    //
    for (i32Buf = 0;i32Buf <(ui32Size - i32Idx);i32Buf++)
    {
    //
    将字符串复制到输出缓冲区。
    //
    pcData[i32Idx + i32Buf]= g_pui8StringData[ui32Offset +
    i32Buf];
    
    //
    如果按 null,则终止副本。
    //
    if (pcData[i32Idx + i32Buf]==0)
    {
    break;
    }
    
    //
    
    
    //如果我们在遇到这种情况之前没有复制任何字符,
    //初始化输出指针(这将使代码保持在
    //返回长度快乐的函数的末尾)。
    如果我们使用未压缩的字符串表、这将是//情况。
    //
    if (!pui8BufferOut)
    {
    pui8BufferOut =(uint8_t *) pcData +(i32Idx + i32Buf);
    }
    
    
    i32Pos--;
    }
    
    //
    //返回复制到输出缓冲区的字节数。
    //
    if (pui8BufferOut)
    {
    ui32Len =((uint32_t) pui8BufferOut -(uint32_t) pcData);
    
    //
    //空如果有空间,则终止字符串。
    //
    if (ui32Len < ui32Size)
    {
    pcData[ui32Len]= 0;
    }
    }
    其他
    {
    ui32Len = 0;
    }
    
    return (ui32Len);
    }
    

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

    感谢您报告此问题。 我们无法在下一个 TivaWare 版本中进行更改、但我们将在错误跟踪系统中记录相同的内容