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:16位 CCITT 标准的硬件 CRC 始终具有0xFF 的高字节

Guru**** 2538930 points
Other Parts Discussed in Thread: MSP432E401Y

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1163480/msp432e401y-hardware-crc-for-16-bit-ccitt-standard-always-has-0xff-for-upper-byte

器件型号:MSP432E401Y

尊敬的 TI 专家:

我正在尝试在 MSP432E401Y 上实现硬件 CRC。 我需要使用 CRC_polynomial _CRC_16_CCITT 标准来匹配我在 MSP430上计算的硬件 CRC (只有一个标准)。 我正在对4个字节的数据进行计算、每次添加1个字节的数据。 种子(初始值)为0xFFFF。

我在下面附上了代码、这是用于在 MSP432上进行硬件 CRC 计算的标准示例代码。 我只将  src 更改为 4个字节、 src_size  和   CRC 驱动程序用于满足我的需求的参数。

/*
 * Copyright (c) 2019, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 *  ======== crc.c ========
 */
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>

/* Driver Header files */
#include <ti/drivers/UART.h>
#include <ti/drivers/CRC.h>

/* Driver configuration */
#include "ti_drivers_config.h"

/* Expected CRC for CRC_32_IEEE with full endianness reversal */
static const uint32_t expectedCrc = 0x4C4B4461;

/* Example test vector */
static const size_t srcSize = 4;
static const uint8_t src [] = {
    0x12, 0x34, 0x56, 0x78
};

static const char preOpMessage[] = "Performing CRC_32_IEEE with endianness reversal... ";
static const char postOpMessage[] = "Check successful.\r\n";

/* ======== mainThread ======== */
void *mainThread(void *arg0)
{
    int_fast16_t status;
    uint16_t result;

    CRC_Handle handle;
    CRC_Params params;

    UART_Handle uart;
    UART_Params uartParams;

    /* Initialize the drivers */
    CRC_init();
    UART_init();

    /* Create a UART with data processing off. */
    UART_Params_init(&uartParams);
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudRate = 115200;

    uart = UART_open(CONFIG_UART_0, &uartParams);

    if (uart == NULL) {
        /* UART_open() failed */
        while (1);
    }

    UART_write(uart, preOpMessage, sizeof(preOpMessage));

    /* Set data processing options, including endianness control */
    CRC_Params_init(&params);
    params.byteSwapInput = CRC_BYTESWAP_UNCHANGED;
    params.returnBehavior = CRC_RETURN_BEHAVIOR_BLOCKING;
    params.polynomial = CRC_POLYNOMIAL_CRC_16_CCITT;
    params.dataSize = CRC_DATA_SIZE_8BIT;
    params.seed = 0xFFFF;
    //params.programmablePoly = 0x1021;
    //params.programmablePolyOrder = 3;

    /* Open the driver using the settings above */
    handle = CRC_open(CONFIG_CRC_0, &params);
    if (handle == NULL)
    {
        /* If the handle is already open, execution will stop here */
        while(1);
    }

    /* Calculate the CRC of all 32 bytes in the source array */
    status = CRC_calculateFull(handle, src, srcSize, &result);
    if (status != CRC_STATUS_SUCCESS)
    {
        /* If the CRC engine is busy or if an error occurs execution will stop here */
        while(1);
    }

    /* This is another way of achieving the same result; for instance
     * if data is arriving in blocks (over UART) this method may be preferable.
     * CRC_reset() may be used to clear an ongoing partial if the result is no
     * longer needed. CRC_finalise() also resets the state. */
    status = CRC_addData(handle, src, srcSize/2);
    if (status != CRC_STATUS_SUCCESS)
    {
        /* If the CRC engine is busy or if an error occurs execution will stop here */
        while(1);
    }

    status = CRC_addData(handle, &src[srcSize/2], srcSize/2);

    /* Extract the result from the internal state */
    CRC_finalize(handle, &result);

    if (status != CRC_STATUS_SUCCESS)
    {
        /* If the CRC engine is busy or if an error occurs execution will stop here */
        while(1);
    }

    UART_write(uart, postOpMessage, sizeof(postOpMessage));

    /* Close the driver to allow other users to access this driver instance */
    CRC_close(handle);
    UART_close(uart);

    return NULL;
}

我将使用此在线 CRC 计算 器在线 CRC-8 CRC-16 CRC-32计算器(crccalc.com)交叉校验我的结果、结果应在第一行(CRC-16/CCITT-false)。

数据:0x12、0x34、0x56、0x78

我从代码 0xFFEC 获取的结果

来自在线计算器的结果:0x30EC

下面是在线计算器结果的快照。

无论我尝试哪种数据组合、较低字节(本例中为 EC)都是正确的、但较高字节是 FF 或其他一些错误值。

我在 MSP432上实现 CRC 驱动程序时是否出错?

我们非常感谢您的任何帮助。

谢谢。

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

    您好!

     我将深入研究它、然后再与您联系。  

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

    您好!

     出于某种原因、尽管  CRC 硬件计算出校验和为030EC、但下面的行未正确地将 CRC 校验和保存到结果变量中。 您可以在寄存器窗口中查看 CRC 模块以进行确认。  SDK CRC 驱动程序也是我所不熟悉的。 我不确定它有什么问题。  

    第111行  crc_calculateFull (handle、src、srcSize、&result);

    我建议您首先在 calculateCpu 中的断点处放置一个断点。 当您逐步执行此函数时、请观察 CCM_CRCWEED 值在每次写入新字节时是如何变化的。 如您所见、CRCWEED 变为0x30EC。 CRC 值未正确保存到结果变量中。  

     我还尝试使用本机 CRC 外设驱动程序而不是 TI-RTOS CRC 驱动程序、并且能够重现相同的校验和。 请查看以下内容。  为了使硬件 CRC 与在线 CRC 计算器相匹配、我做了几件事情。  

     输入数据需要为0x78563412。 将0x12345678放在在线计算器上时、它取0x12作为第一个字节、然后取0x34作为第二个字节、以此类推。 但是、对于硬件、0x12345678的第一个字节实际上是0x78、而不是0x12。  

     -由于要将8位指定为输入数据的大小,因此数组中的项目数应为4,因为输入数据0x78563412中有四个字节。  

    #include <stdbool.h>
    #include <stdint.h>
    #include "ti/devices/msp432e4/driverlib/inc/hw_ccm.h"
    #include "ti/devices/msp432e4/driverlib/driverlib.h"
    #include "pinout.h"
    #include "uartstdio.h"
    
    //*****************************************************************************
    //
    //! \addtogroup example_list
    //! <h1>CRC-32 Demo (crc32)</h1>
    //!
    //! Simple demo showing a CRC-32 operation using the CCM module.
    //!
    //! Please note that the use of uDMA is not required for the operation of the
    //! CRC module.  It is for demostration purposes only.
    //
    //*****************************************************************************
    
    //*****************************************************************************
    //
    // Configuration defines.
    //
    //*****************************************************************************
    #define CCM_LOOP_TIMEOUT        500000
    
    
    
    //*****************************************************************************
    //
    // The error routine that is called if the driver library encounters an error.
    //
    //*****************************************************************************
    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
    }
    #endif
    
    uint32_t g_ui32Result=0;
    
    uint32_t ui32datain;
    
    int
    main(void)
    {
        ui32datain = 0x78563412;
        
        //
        // Enable the CRC module.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_CCM0);
        //
        // Wait for the CRC module to be ready.
        //
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_CCM0))
        {
        }
        //
        // Configure the CRC module.
        //
        CRCConfigSet(CCM0_BASE,
                     CRC_CFG_INIT_SEED |
                     CRC_CFG_TYPE_P1021 |
                     CRC_CFG_SIZE_8BIT);
        //
        // Set the seed value.
        //
        CRCSeedSet(CCM0_BASE, 0xFFFF);
    
        g_ui32Result = CRCDataProcess(CCM0_BASE, &ui32datain, 4, false);
    
    
        while(1);
    }

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

    您好!

     我想我已经开始工作了。 请查看下面我用红色修改的内容。  

    /*示例测试向量*/
    静态常量 size_t srcSize = 4;
    静态常量 uint8_t src []={
    0x12、0x34、0x56、0x78
    };

    静态 const char preOpMessage[]="执行字节序反转的 CRC_32_IEEE ... ";
    静态常量字符 postOpMessage[]="检查成功。\r\n\r\n;

    /*===== mainThread ==== *
    void * mainThread (void * arg0)

    INT_fast16_t 状态;
    uint16_t 结果; //使结果为 uint16_t  

    CRC_Handle 句柄;
    CRC_PARAMS 参数;

    UART_Handle UART;
    UART_Params uartParams;

    /*初始化驱动程序*/
    crc_init();
    UART_INIT();

    /*创建一个数据处理关闭的 UART。 *
    UART_PARAMS_INIT (uartParams);
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_return_full;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudrate = 115200;

    UART = UART_OPEN (CONFIG_UART_0、uartParams);

    if (UART == NULL){
    /* UART_open()失败*/
    while (1);

    UART_WRITE (UART、preOpMessage、sizeof (preOpMessage));

    /*设置数据处理选项,包括字节序控制*/
    CRC_PARAMS_INIT (params);
    params.byteSwapInput = CRC_BYTESWAP_unchanged;
    Params.returnBehavior = crc_return_Behavie_blocking;
    params.polynomial = crc_polynomial _crc_16_CCITT;
    params.dataSize = crc_data_size_32位;//使其成为32位数据大小,即使输入存储在8位数组中。
    params.seed = 0xFFFF;

    /*使用上述设置打开驱动程序*/
    句柄= CRC_OPEN (CONFIG_CRC_0、params);
    if (handle == NULL)

    /*如果句柄已打开,则执行将在此处停止*/
    while (1);

    /*计算源数组中所有32个字节的 CRC */
    status = crc_calculateFull (handle、src、srcSize、&result);
    if (status!= CRC_STATUS_SUCCESS || RESULT!=预期的 Crc)

    /*如果 CRC 引擎忙或发生错误,执行将在此处停止*/
    while (1);

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

    您好、Charles、  

    感谢您返回我并找到解决方法(使用 CRC_DATA_SIZE _32位)

    但是、这意味着我无法使用  下面的 CRC_addData 代码将数据添加到 CRC 模块、因为它到达通信总线、这是正确的吗? 我尝试过、但在检查 CRC_STATUS_SUCCESS 时结果失败。

    status = CRC_addData(handle, &src[srcSize/2], srcSize/2);
    
    /* Extract the result from the internal state */
    CRC_finalize(handle, &result);
    
    if (status != CRC_STATUS_SUCCESS)
        {
            /* If the CRC engine is busy or if an error occurs execution will stop here */
            while(1);
        }

    此外、应用程序需要计算小至3字节的数据的 CRC。 如果我像下面那样更改了 srcSize 和 src 数据、则 CRC_calculateFull  和 CRC_addData 方法的计算将不再有效。

    /* Example test vector */
    static const size_t srcSize = 3;
    static const uint8_t src [] = {
    0x12, 0x34, 0x56
    };

    在 TI-RTOS 上、您是否有权使用此权变措施来计算3个数据字节上的16位 CCITT CRC?

    感谢您在这方面的帮助。



    至于 CRC 外设驱动程序、我担心使用 TI-RTOS 是我们项目的一项要求。 CRC 外设驱动程序是否可以从 TI-RTOS 中使用? 如果没有,我认为这是不可行的。

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

    您好!

     我需要修改 TI-RTOS 驱动程序时出现问题。 请查看下面我做了什么、它对我来说很有用。  

    首先、我修改了 CRCMSP432E4.c 文件。 这是一个 SDK 文件、我将其复制到当前工程以进行修改。 处理 crc_data_size_8bit 时存在拼写错误问题。 与最初的情况一样、它将具有等于0xFF 的16位字的高字节。 我修改的行是第263行。 可以通过更巧妙的方法来更改驱动程序、例如也支持8位多项式、但对于特定的16位 CRC16_CCITT 要求、这将起作用。

    我从

    *((uint8_t*) resultLocation)=(uint8_t) crcResult;

    至:

    *((uint16_t*) resultLocation)=(uint16_t) crcResult;

     e2e.ti.com/.../CRCMSP432E4.c

    其次、您需要手动添加 DeviceFamily_MSP432E401Y 符号、以便正确编译上述驱动程序文件。  

    第三、这是我在该示例中拥有的内容。 见下文附件。 我使用3个字节作为输入、它提供了正确的结果。  

    e2e.ti.com/.../crc16_5F00_ccitt.c

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

    您好、Charles、  

    我现在有一个 CCITT CRC16、对于给定的缓冲区、我可以在 MSP432上计算该缓冲区、该缓冲区与在 MSP430上计算的 CRC16相匹配。  

    您认为值得向 TI 通知 MSP432E401Y TI-RTOS CRC 驱动程序的此驱动程序错误/问题吗? 即使使用此变通办法、驱动程序仍然不可靠、因为根据 API 文档、可能有更多的功能无法正常工作。 也许他们可以提供 TI-RTOS 驱动程序库的更新?

    不管怎样,我的问题现在已经解决了。 非常感谢您的解决方法。