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.

[参考译文] TMS570LS3137:利用 DMA 的具有自动模式的 CRC

Guru**** 2482105 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/704987/tms570ls3137-crc-with-auto-mode-utilizing-dma

器件型号:TMS570LS3137

您好!

在我的引导加载程序中、我希望利用嵌入式 CRC 控制器计算应用程序映像的 CRC、然后再跳转到该映像。

我认为具有 DMA 的自动模式将是最快的。

TI 能否提供计算大闪存区域单个 CRC 的示例代码? (假设应用程序映像大于1 MB)

我想生成单个 CRC、而不是每个1Kb 的多个 CRC 等

提前感谢您

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

    是的、您可以使用自动模式在 CPU 后台检查 CRC。 您不必每1KB 执行一次 CRC 计算和校验。

    将 PCOUNT 编程为1 MB、将 SCOUNT 编程为1。 我将为您编写一个示例。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢、期待该示例。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    在以下 URL www.ti.com/.../spna235中,文件 CRC64_calc.c 和函数 calc_CRC64()用于64位数据。

    假设应用程序映像的大小不是8的倍数、假设"app_size mode 8 = 4"。 如何将剩余的4个字节包含到 CRC 计算中? 我要问的是下面的第二个案例。

    1- app_size = 800字节=> calc_CRC64 (100)
    2- APP_SIZE = 804字节=> calc_CRC64 (100)、但剩余的4个字节会怎么样?

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

    以下是一个示例:

    /*用户代码开始(2)*/
    #define FRAME_COUNT 4096
    #define Element_count 32. /*64位双字*/

    G_dmaCTRL dma_config;// DMA 控制数据包配置堆栈

    /*用户代码结束*/

    int main (空)

    /*用户代码开始(3)*/
    /*手动清除 ESM 错误*/
    esmREG->SR1[2]= 0x00000008U;
    esmREG->SSR2 = 0x00000008U;
    esmREG->EKR = 0x0000000A;
    esmREG->EKR = 0x00000005;

    _enable_IRQ ();

    crcInit();
    crcREG1->PCOUNT_REG1 = frame_count * element_count;/* 4096*32 doubleworks, 1MBytes*/
    crcREG1->SCOUNT_REG1 = 1;
    crcEnableNotification (crcREG1,1);

    dmaEnable();

    DMA_CONFIG.Sadd = 0x00020000; /*应用程序起始地址*/
    dma_config.dADD =(uint32_t)&(crcREG1->PSA_SIGREGL1);
    DMA_CONFIG.CHCTRL = 0;
    DMA_CONFIG.FRCNT = FRAME_COUNT;
    DMA_CONFIG.ELCNT = Element_count;

    DMA_CONFIG.ELDOFFSET = 0;
    DMA_CONFIG.ELSOFFSET = 0;
    DMA_CONFIG.FRDOFFSET = 0;
    DMA_CONFIG.FRSOFFSET = 0;
    DMA_CONFIG.PORTASGN = 1;
    DMA_CONFIG.RDSIZE = ACCESS_64_BIT;
    DMA_CONFIG.WRSIZE = ACCESS_64_BIT;
    dma_config.tType = block_transfer;
    dma_config.ADDMODERD = ADDR_INC1;
    DMA_CONFIG.ADDMODEWR = ADDR_FIXED;
    DMA_CONFIG.AUTOINIT = AUTOINIT_OFF;

    //为接收设置 DMA 控制数据包
    dmaSetCtrlPacket (DMA_CH0、DMA_CONFIG);
    dmaSetChEnable (0、dma_SW);

    while (1);
    /*用户代码结束*/

    返回0;
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    从该示例中、如果左边小于8个字节、则会附加零。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢 QJ。

    我决定使用半自动 CPU 模式。 奇怪的是,我第一次计算 CRC 时,PSA_SECSIGREGL1/H1为0x0,某些值存储在 PSA_SIGREGL1/H1中。 但是、在后续计算中、PSA_SIGREGL1/H1为0x0、PSA_SECSIGREGL1/H1具有第一次计算 CRC 后在 PSA_SECSIGREGL1/H1中观察到的值。

    在半自动 CPU 模式下、我知道应该读取 PSA_SECSIGREGL1/H1以获取 CRC 值。

    不知道为什么 CRC 值存储在 PSA_SIGREGL1/H1中用于第一次 CRC 计算?

    下面是我得到的结果:

    int main()

    rtiInit();

    sciInit();

    /**-配置 CRC */

    crcInit();

    sciEnableNotification (sciREG、SCI_RX_INT     );

    sciEnableNotification (sciREG、SCI_TX_INT     );

    rtiEnableNotification (rtiNOTIFICATION_COMPARE0 );

    _enable_IRQ ();

    CRC_TMS570 (START_ADDRESS、SIZE);  

    // PSA_SECSIGREGL1/H1为0x0,某些值存储在 PSA_SIGREGL1/H1中,例如 X 和 Y

    CRC_TMS570 (START_ADDRESS、SIZE);

    // PSA_SIGREGL1/H1为0x0,PSA_SECSIGREGL1/H1具有 X 和 Y

     

    CRC_TMS570 (START_ADDRESS、SIZE);

    // PSA_SIGREGL1/H1为0x0,PSA_SECSIGREGL1/H1具有 X 和 Y

    uint64_t crc_tms570 (uint32_t start_address、uint32_t size)

    volatile uint32_t counter = 0;
    uint32_t Pcount =大小/8;
    /**-设置信道模式*/
    crcREG->CTRL2=0x00000000;
    crcREG->CTRL2 |=(CRC_SEMI CPU);

    dmaEnable();

    crcREG->CTRL2 &=0xFFFFFFFCU;
    crcREG->CTRL2 |= CRC_SEMI CPU;
    crcREG->PCOUNT_REG1 = Pcount;
    crcREG->SCOUNT_REG1 = 1;

    crcChannelReset (crcREG、0);

    /*-分配 DMA 请求:带有请求线的通道0 - 26 */
    dmaReqAssign (DMA_CH0,26);
    /*-配置 DMA 控制数据包*/
    dmaConfigCtrlPacket (start_address、(uint32_t)(&(crcREG->PSA_SIGREGL1))、Pcount、ADDR_INC1、ADDR_FIXED、 AUTOINIT_ON);
    /*-设置 DMA 控制数据包*/
    dmaSetCtrlPacket (DMA_CH0、g_dmaCTRLPKT);
    /*-将 DMA 通道设置为在软件请求时触发*/
    dmaSetChEnable (DMA_CH0、DMA_SW);

    while ((crcREG->BUSY & 0x1))

    COUNTER++;
    如果((计数器% 0x20000)=0)

    dwdReset();

    dmaDisable();
    //首次调用此 CRC_TMS570 ()时,PSA_SECSIGREGL1/H1为0x0,某些值存储在 PSA_SIGREGL1/H1中
    uint64_t CRC_ACTUAL =(((uint64) crcREG->PSA_SIGREGL1 <<32U)|(uint64) crcREG->PSA_SIGREGH1);
    //但是,在此 CRC_TMS570 ()的后续调用中,PSA_SIGREGL1/H1为0x0,PSA_SECSIGREGL1/H1具有一些值
    // PSA_SECSIGREGL1/H1应存储 CRC 值,无论首次或后一次调用
    //那么, 为什么 CRC 值存储在 PSA_SIGREGL1/H1中以进行第一次 CRC 计算
    //uint64_t CRC_ACTUAL =(((uint64) crcREG->PSA_SECSIGREGL1 << 32U)|(uint64) crcREG->PSA_SECSIGREGH1);
    返回 CRC_ACTUAL;  

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

    您是对的、在半 CPU 模式下、CPU 应该从 PSA 扇区签名寄存器读取、而不是从 PSA 签名寄存器读取。

    在半自动 CPU 模式下、当压缩数据模式的一个扇区时、CRC 控制器会生成压缩完成中断。 存储在 PSA 签名寄存器中的签名被复制到 PSA 扇区签名寄存器中、然后 PSA 签名寄存器被清零。

    PSA 扇区签名寄存器中的值应在压缩完成中断的 ISR 中读取。 在此之前、PSA_SECSIGREG 不会更新。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    在某些特定情况下、我会在所有 CRC 相关寄存器上看到"BAD0BAD0"模式。 而 CCS 调试会话则成为不会再发生的情况。
    我正在尝试半自动 CPU 模式。
    什么会导致 CRC 寄存器具有此"BAD0BAD0"模式?

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

    器件断开 JTAG 连接、或禁用 CRC 模块。 CCS 无法读取 CRC 寄存器的内容。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    看起来器件正在进行系统复位。 您能否探测 nRST 引脚以查看发生这种情况时是否变为低电平?

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

    我再也看不到"BAD0BAD0"模式。 但是、CRC 完成中断 有时不会触发。 请您查看 以下功能吗? 不确定我做了什么错?

    int main()
    {。。
    crcInit();
    enableCRCNotification (CrcREG、CRC_CH1_CC);

    静态 uint64_t CRC_64 (uint32_t start_address、uint32_t size)

    uint32_t Pcount =大小/8;

    /**-设置信道模式*/
    crcREG->CTRL2=0x00000000;
    crcREG->CTRL2 |=(CRC_SEMI CPU);

    dmaEnable();

    crcREG->CTRL2 &=0xFFFFFFFCU;//通道0
    crcREG->CTRL2 |= CRC_SEMI CPU
    crcREG->PCOUNT_REG1 = Pcount
    crcREG->SCOUNT_REG1 = 1

    crcChannelReset (crcREG、0);

    /*-分配 DMA 请求:带有请求线的通道0 - 26 */
    dmaReqAssign (DMA_CH0,26);
    /*-配置 DMA 控制数据包*/
    dmaConfigCtrlPacket (start_address、(uint32_t)(&(crcREG->PSA_SIGREGL1))、Pcount、ADDR_INC1、ADDR_FIXED、 AUTOINIT_OFF);
    /*-设置 DMA 控制数据包*/
    dmaSetCtrlPacket (DMA_CH0、g_dmaCTRLPKT);
    /*-将 DMA 通道设置为在软件请求时触发*/
    dmaSetChEnable (DMA_CH0、DMA_SW);

    while ((dmaREG->GCTRL &(1 << 14))&&(crcREG->BUSY & 0x1));

    dmaDisable();

    uint64_t CRC = crcGetSectorSig (crcREG、0);
    /*清除 CH1_CCIT 位*/
    crcREG->status = CRC_CH1_CC;
    返回 CRC;

    静态空 dmaConfigCtrlPacket (uint32_t Sadd、uint32_t dadd、uint32_t dsize、uint8_t Add_RD_mode、uint8_t Add_WR_mode、uint8_t AIM)

    G_dmaCTRLPKT.Sadd =添加;//源地址*/
    G_dmaCTRLPKT.DADD =添加;/*目标地址*/
    G_dmaCTRLPKT.CHCTRL = 0;/*通道控制*/
    G_dmaCTRLPKT.FRCNT = 1;/*帧计数*/
    G_dmaCTRLPKT.ELCNT = dsize;/*元素计数*/
    G_dmaCTRLPKT.ELDOFFSET = 0;/*元素目标偏移量*
    G_dmaCTRLPKT.ELSOFFSET = 0;/*元素目标偏移量*
    G_dmaCTRLPKT.FRDOFFSET = 0;/*帧目标偏移量*
    G_dmaCTRLPKT.FRSOFFSET = 0;/*帧目标偏移量*
    G_dmaCTRLPKT.PORTASGN = 4;/*端口 b *
    G_dmaCTRLPKT.RDSIZE = ACCESS_64_BIT;/*读取大小*
    G_dmaCTRLPKT.WRSIZE = ACCESS_64_BIT;/*写入大小*
    G_dmaCTRLPKT.tType = block_transfer;/* transfer type *
    G_dmaCTRLPKT.ADDMODERD = ADD_RD_MODE;/*地址模式读取*
    G_dmaCTRLPKT.ADDMODEWR = ADD_WR_MODE;/*地址模式写入*
    G_dmaCTRLPKT.AUTOINIT = AIM;/* autocinit */

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

    我在您的代码中看不到问题。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我还观察到:

    crcREG->SCOUNT_REG1 = 1;

    crcREG->Pcount <= 0x0FFF8/8 (65528/8)-- > CRC isin 扇区签名寄存器并校正

    crcREG->Pcount >=(0x10000 / 8)(65536 /8)-->扇区签名寄存器为0

    我想计算 CRC,比如1MB 数据。 扇区计数为1、图形计数为(1MB /8)。 但我的观察结果告诉我、我一直处于模式计数(65528/8)。
    TRM 告诉我20位被指定用于模式计数,因此我应该能够将(1MB/8)分配给模式计数寄存器,它应该起作用。

    如果 Pcount 小于或等于(0x0FFF8/8)[(65528/8)],请帮助我了解 CRC 计算为何起作用?

    我如何实现至少1MB 数据的单个 CRC 的目标[1个扇区和至少(1MB/8)的计数]?

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

    您好!

    DMA 传输的最大帧计数为0x1FFF。 如果帧计数和元素计数在有效范围内、则 CRC 计算有效。

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

    您可以使用 PCOUNT=1MB 字节/8、FCOUNT=0xFFF8/8、且 ECOUNT=PCOUNT/FCOUNT。