打印
[Kinetis]

小端CRC参数设置(已解决)

[复制链接]
3830|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
CRC, TI, se, FOR, NET
本帖最后由 FSL_TICS_A 于 2014-3-4 17:08 编辑

采用Kinetis硬件计算crc,如果是使用大端计算都可得到正确结果。但是使用小端时,计算结果都是错误的。
/*
* There are multiple 16-bit CRC polynomials in common use, but this is
* *the* standard CRC-32 polynomial, first popularized by Ethernet.
* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0
*/
#define CRCPOLY_LE 0xedb88320
#define CRCPOLY_BE 0x04c11db7

/**
* crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32
* @crc: seed value for computation.  ~0 for Ethernet, sometimes 0 for
*        other uses, or the previous crc32 value if computing incrementally.
* @p: pointer to buffer over which CRC is run
* @len: length of buffer @p
* In fact, the table-based code will work in this case, but it can be
* simplified by inlining the table in ?: form.
*/
u32 crc32_le(u32 crc, unsigned char const *p, size_t len)
{
        int i;
        while (len--) {
                crc ^= *p++;
                for (i = 0; i < 8; i++)
                        crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
        }
        return crc;
}

/**
* crc32_be() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32
* @crc: seed value for computation.  ~0 for Ethernet, sometimes 0 for
*        other uses, or the previous crc32 value if computing incrementally.
* @p: pointer to buffer over which CRC is run
* @len: length of buffer @p
* In fact, the table-based code will work in this case, but it can be
* simplified by inlining the table in ?: form.
*/

u32 crc32_be(u32 crc, unsigned char const *p, size_t len)
{
        int i;
        while (len--) {
                crc ^= *p++ << 24;
                for (i = 0; i < 8; i++)
                        crc =
                            (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE :
                                          0);
        }
        return crc;
}

// Definitions
typedef struct _CRC_CTRL
{
    uint8_t transpose_w; //TOT
    uint8_t transpose_r; //TOTR
    uint8_t fxor;         //bit 26 FXOR
    uint8_t width;
}CRC_CTRL_DEF;

//for Transpose write(read)
#define CRC_ORDER_NORMAL    0x00
#define CRC_REVERSE_BITS    0x01
#define CRC_REVERSE_BOTH    0x02
#define CRC_REVERSE_BYTE    0x03
//width
#define CRC_BITS_16         0x00
#define CRC_BITS_32         0x01
//FXOR
#define CRC_NO_FXOR         0x00
#define CRC_FXOR            0x01

void hw_crc_config(uint32_t poly, CRC_CTRL_DEF ctrl)
{
       CRC_CTRL = ((ctrl.width << CRC_CTRL_TCRC_SHIFT) & CRC_CTRL_TCRC_MASK)
             | ((ctrl.fxor  << CRC_CTRL_FXOR_SHIFT) & CRC_CTRL_FXOR_MASK)
             | ((ctrl.transpose_r << CRC_CTRL_TOTR_SHIFT) & CRC_CTRL_TOTR_MASK)
             | ((ctrl.transpose_w << CRC_CTRL_TOT_SHIFT ) & CRC_CTRL_TOT_MASK );
       CRC_GPOLY = poly;
}

uint32_t hw_crc_cal_32(uint32_t seed, uint8_t const *msg, uint32_t length)
{
     CRC_CTRL |= CRC_CTRL_WAS_MASK;
    CRC_CRC = seed;
    CRC_CTRL &= ~CRC_CTRL_WAS_MASK;
    while (length--) {
        CRC_CRCLL = *msg++;
    }
    return CRC_CRC;
}


//测试程序
const uint8_t dbg_crc_msg[] = "abcdef0123456789ghjkloqwertyuizx";

void dbg_crc32_le_all(void)
{
    CRC_CTRL_DEF ctrl_reg;
    uint32_t length;
    uint16_t hw_crc;
    uint16_t sw_crc;
    uint8_t buf[64];
    uint32_t i;
    uint32_t *p=(uint32_t*)dbg_crc_msg;

    ctrl_reg.transpose_w = CRC_REVERSE_BOTH;
    ctrl_reg.transpose_r = CRC_ORDER_NORMAL;
    ctrl_reg.fxor = CRC_NO_FXOR;
    ctrl_reg.width = CRC_BITS_32;

    for (ctrl_reg.transpose_w = 0; ctrl_reg.transpose_w < 0x04; ctrl_reg.transpose_w++)
    {
        for (ctrl_reg.transpose_r = 0; ctrl_reg.transpose_r < 0x04; ctrl_reg.transpose_r++)
        {
            for (ctrl_reg.fxor = 0; ctrl_reg.fxor <2; ctrl_reg.fxor++)
            {
                TRACE("\n\n-|crc:0x00 tot:%02x totr:%02X fxor:%X",ctrl_reg.transpose_w,ctrl_reg.transpose_r,
                      ctrl_reg.fxor);
                hw_crc_config(CRCPOLY_LE,ctrl_reg);
                for (length = 0; length < 32; length+=4)
                {
                    hw_crc = hw_crc_cal_32(0,dbg_crc_msg,length);
                    sw_crc =   crc32_le(0,dbg_crc_msg,length);
                    TRACE("\n-|hw:%04X sw:%04X",hw_crc,sw_crc);
                }
                TRACE("\n\n-|crc:~0 tot:%02x totr:%02X fxor:%X",ctrl_reg.transpose_w,ctrl_reg.transpose_r,
                      ctrl_reg.fxor);
                 hw_crc_config(CRCPOLY_LE,ctrl_reg);
                for (length = 0; length < 32; length+=4)
                {
                    hw_crc = hw_crc_cal_32(~0,dbg_crc_msg,length);
                    sw_crc =   crc32_le(0,dbg_crc_msg,length);
                    TRACE("\n-|hw:%04X sw:%04X",hw_crc,sw_crc);
                }     
            }
        }
    }
}
小端试过所有的TOT和TOTR,初值,和读取反模式组合都测试过,但是都与软件算的不一样。大端的都成功。 有人可以指点一下吗。谢谢。





   

相关帖子

沙发
chasedreamsl|  楼主 | 2014-2-28 11:45 | 只看该作者
注:u32 crc32_be(u32 crc, unsigned char const *p, size_t len);和u32 crc32_le(u32 crc, unsigned char const *p, size_t len)移植linux内核。

使用特权

评论回复
板凳
FSL_TICS_Jeremy| | 2014-2-28 13:43 | 只看该作者
你好,楼主!!
你可以通过以下链接,了解一下Kinetis的CRC模块。
https://bbs.21ic.com/icview-679844-1-1.html

使用特权

评论回复
地板
chasedreamsl|  楼主 | 2014-2-28 14:02 | 只看该作者
FSL_TICS_Jeremy 发表于 2014-2-28 13:43
你好,楼主!!
你可以通过以下链接,了解一下Kinetis的CRC模块。
https://bbs.21ic.com/icview-679844-1-1.ht ...

学习了下链接里的CRC。 但是仍不能解决问题。 针对小端模式u32 crc32_le(u32 crc, unsigned char const *p, size_t len)的TOT和TOTR总共16种方式的组合,以及初值为0或~0都测试过。所有才有此一问。

使用特权

评论回复
5
FSL_TICS_Robin| | 2014-2-28 15:06 | 只看该作者
如果你的输入选择了byte转置,那么存入寄存器的数据顺序需注意。

使用特权

评论回复
6
chasedreamsl|  楼主 | 2014-2-28 15:13 | 只看该作者
FSL_TICS_Robin 发表于 2014-2-28 15:06
如果你的输入选择了byte转置,那么存入寄存器的数据顺序需注意。

没明白,能具体点说明byte转置时存入寄存器的数据顺序吗。

使用特权

评论回复
7
FSL_TICS_Robin| | 2014-2-28 15:35 | 只看该作者
chasedreamsl 发表于 2014-2-28 15:13
没明白,能具体点说明byte转置时存入寄存器的数据顺序吗。

请问楼主的硬件CRC例程是官网上下载的吗?

使用特权

评论回复
8
chasedreamsl|  楼主 | 2014-2-28 15:37 | 只看该作者
FSL_TICS_Robin 发表于 2014-2-28 15:35
请问楼主的硬件CRC例程是官网上下载的吗?

不是,不知道官网还有这方面例程。

使用特权

评论回复
9
FSL_TICS_Robin| | 2014-2-28 15:48 | 只看该作者
chasedreamsl 发表于 2014-2-28 15:37
不是,不知道官网还有这方面例程。

请问楼主芯片型号?

使用特权

评论回复
10
chasedreamsl|  楼主 | 2014-2-28 16:11 | 只看该作者
FSL_TICS_Robin 发表于 2014-2-28 15:48
请问楼主芯片型号?

MK21DN512

使用特权

评论回复
11
FSL_TICS_Robin| | 2014-2-28 16:49 | 只看该作者
本帖最后由 FSL_TICS_Robin 于 2014-2-28 16:54 编辑
chasedreamsl 发表于 2014-2-28 16:11
MK21DN512


你参考一下CodeWarrior软件安装目录下的CRC例程:
E:\Program Files\Freescale\CW MCU v10.5\MCU\CodeWarrior_Examples\Kinetis_Examples\k40\crc_demo

K21 50MHz的例程包中的确没有CRC的例程

使用特权

评论回复
12
chasedreamsl|  楼主 | 2014-2-28 17:18 | 只看该作者
本帖最后由 chasedreamsl 于 2014-2-28 17:20 编辑
FSL_TICS_Robin 发表于 2014-2-28 16:49
你参考一下CodeWarrior软件安装目录下的CRC例程:
E:\Program Files\Freescale\CW MCU v10.5\MCU\CodeWar ...

谢谢您的回复。把这部分代码移植后,仍然不会有正确结果。 我看不是4字节倍数的问题。 就单是我原来的程序也是4字节整传进去的,也不会产生这个问题。

使用特权

评论回复
13
chasedreamsl|  楼主 | 2014-2-28 17:20 | 只看该作者

本帖最后由 chasedreamsl 于 2014-2-28 14:28 编辑


采用Kinetis硬件计算crc,如果是使用大端计算都可得到正确结果。但是使用小端时,计算结果都是错误的。
/*
* There are multiple 16-bit CRC polynomials in common use, but this is
* *the* standard CRC-32 polynomial, first popularized by Ethernet.
* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0
*/
#define CRCPOLY_LE 0xedb88320

/**
* crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32
* @crc: seed value for computation.  ~0 for Ethernet, sometimes 0 for
*        other uses, or the previous crc32 value if computing incrementally.
* @p: pointer to buffer over which CRC is run
* @len: length of buffer @p
* In fact, the table-based code will work in this case, but it can be
* simplified by inlining the table in ?: form.
*/
u32 crc32_le(u32 crc, unsigned char const *p, size_t len)
{
        int i;
        while (len--) {
                crc ^= *p++;
                for (i = 0; i < 8; i++)
                        crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
        }
        return crc;
}
有人帮忙用这个软件算法跟硬件算法实现的结果相等吗。  对于那些参数,所有的组合我都试过了。

使用特权

评论回复
14
FSL_TICS_Robin| | 2014-2-28 17:39 | 只看该作者
请给出你的数据和你觉得正确的结果

使用特权

评论回复
15
chasedreamsl|  楼主 | 2014-2-28 17:47 | 只看该作者
FSL_TICS_Robin 发表于 2014-2-28 17:39
请给出你的数据和你觉得正确的结果

所有数据都可以。硬件产生的和软件【u32 crc32_le(u32 crc, unsigned char const *p, size_t len)】计算的结果一样就行。  从CRC16,只要是小端模式的算法都没有正确计算过。 可能是哪里有问题,但是找不到。

使用特权

评论回复
16
FSL_TICS_Robin| | 2014-2-28 18:17 | 只看该作者
建议你去提交一个技术服务请求
https://www.freescale.com/zh-Hans/webapp/servicerequest.create_SR.framework

用英文描述一下你的问题,这样国内、外工程师均能帮助你解决问题。

使用特权

评论回复
17
FSL_TICS_A| | 2014-3-4 17:09 | 只看该作者
楼主你好,非常感谢你对我们的支持~~
请问你的问题解决了吗?  如尚未解决,请继续在帖子中讨论。

如果问题已经得到解决,请参考以下结贴方法:
1、首先在网页的右侧有“我要结贴”,点击进入,界面如下所示:
2、在分数处给分,把相应的分给掉。可以给一个人,也可以给多个人。
3、点击左上角的结贴给分。
这样就把一个贴给结了



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

78

帖子

1

粉丝