333333
CRC码的 Simulink仿真实验
陆正福
, 官金兰 , 吴立芝
(云南大学数学系 , 昆明 650091)
摘要 : 介绍了 CRC码的原理 , 给出了基于 Simulink进行循环冗余校验码的仿真实验过程 , 对于类似的实验具有借鉴意义 。
关 键 词 : CRC码 ; 仿真 ; Simulink仿真
中图分类号 : TP391
6 文献标识码 : B 文章编号 : 1672 - 4550 (2007) 05 - 0045 - 04
9; TP301
第 5卷 第 5期
实 验 科 学 与 技 术
·54·
·计算机及网络技术应用 ·
Simulink Simulation Experiment of CRC Codes
LU Zheng
fu, GUAN J in
lan, WU L i
zhi
(Department of Mathematics, Yunnan University, Kunm ing 650091, China)
Abstract: The p rincip le of cyclic redundant check codes ( CRC)
CRC based on Simulink in Matlab is p resented.
Key words: CRC codes;
simulation;
simulink
is briefly introduced in this paper, and the simulating p rocess for
It can be used as reference for any sim ilar experiment.
1 引 言
循环冗余码 CRC ( Cyclic Redundancy Check)是
数据传输过程中的检错码 。从网络体系结构看 ,
CRC码一般用于数据链路层 , 并且是硬件实现 。
在一些特定的应用领域 , CRC码也可以用于高层 ,
并且用软件实现 。本文研究 CRC码的软件实现 。
在代数编码理论中 , CRC 码是一种循环码 ,
且为系统码 。CRC码的编码过程和译码过程都与
二元域上的多项式模除运算有关 , 从工程应用的角
度考虑 , 可利用高级程序设计语言 、汇编语言实现
CRC码的编码与译码 , 但是 CRC码的位并行快速
算法具有一定难度 [ 1 ] 。因此有必要寻求更能突出
原理的实验方法 , 我们选择了基于 Matlab和 Simu
link的仿真实验方法 。
2 CRC校验原理
假设被校验数据是一组二元代码 (0 、1 代码 )
形式表示的代码序列 , 并将该序列视为二元有限域
GF (2)上的多项式的系数 。于是可定义被校验数据
(被除式 )为多项式 M ( x) ; 约定生成多项式 (除式 )
为 G ( x) , Xdeg ( G ( x) ) M ( x) 除以 G ( x )所产生的余
式为 R ( x) , R ( x )的系数即为所要求的冗余校验
位 。问题的关键在于生成多项式的选取 。生成多项
式应能满足下列要求 :
(1) 0不是生成多项式的零点 , 即常数项为
1, 使其可检测任意一个错 ;
(2) 1是生成多项式的零点 , 即非零系数项的
个数为偶数 , 也即 ( x + 1) | G ( x) , 使其可检测任
意奇数个错 ;
(3) G ( x) / ( x + 1)的周期足够大 , 使其在限定
被校验数据块长度的前提下能检测任意两个错误;
(4) G ( x)的次数 ( degree)不应太低 , 应使其
可检测一定长度范围的突发错 。
CRC码算法的数学原理详见于代数编码 、纠
错码 、数据通信 、计算机网络方面的文献 [ 2 ] , 不
再赘述 。本文仅从算法的角度为后面的实验进行术
语的准备 。
例如 , CC ITT推荐的 16 位 CRC 码的生成多项
式是 G ( x) = x16 + x12 + x5 + 1。利用该码可以检测被
校验数据所有的一位或两位错误 ; 所有具有奇数位
错误 ; 所有低于 16 位的突发性错误 ; 且对大于 16
收稿日期 : 2007 - 02 - 09
基金项目 : 国家自然科学基金资助项目 (10561009) , 云南大学中青年骨干教师培养计划专项经费资助项目 , 云南大学
理 (工 )科校级科研重点项目 (2003Z010C) 。
作者简介 : 陆正福 (1965 - ) ,男 , 教授 , 主要研究方向 : 信息安全 、协议工程 、网络计算 、网络仿真等 。
π
π
1
·64·
实 验 科 学 与 技 术
2007年 10月
9 。这种级别
位的突发性错误检测出的概率为 99
的错误检测正是计算机网络通信信息传输所需要的。
3 M atlab下的 CRC码 [ 3 - 5 ]
在 MATLAB 中 , CRC 编码器有两种 , 即通用
CRC编码器和 CRC - N 编码器 , 这两个 CRC编码
器比较接近 , 它们之间的区别在于后者提供了 6个
常用的 CRC 生 成 多 项 式 , 使 用 起 来 比 较 方 便 。
CRC编码的一般过程如下 : 把输入的数据左移 r
位 , 然后除以生成多项式 P, 得到一个余式 , 这个
余式就是 CRC编码后产生的循环冗余码 , 把这个
余式附加到原始的信息序列的末尾 , 就得到了经过
CRC编码的输出信号序列 。
3
1 通用 CRC编码器
通用 CRC编码器根据输入的一帧数据计算得
到这帧数据的循环冗余码 , 并且把这个循环冗余码
附加到帧数据后面 , 形成输出数据流 。
如果通用 CRC编码器的输入数据的帧长度等
于 n, 生成多项式的最高次数等于 r, 对每帧数据
产生 k个校验和 ( CHECKSUM ) , 则 CRC编码器的
工作流程如下 :
(1) 把输入的一帧数据等分成 k 个部分 , 每
个部分 w i 的长度是 n / k;
( 2) 在每个部分的数据 w i 后面添加 r个二进
制位 (并且这 r个二进制位的数值等于通用 CRC编
码器的初始状态 ) , 得到二进制序列 S i;
( 3) 计算 S i 的循环冗余码 Ci;
( 4) 把循环冗余码 Ci 添加到 W i 的后面 , 得
到二进制序列 ui;
( 5) 把所有的 ui 连接起来形成数据帧 。
3
2 CRC - N 编码器
CRC - N 编码器 (CRC - N Generator)计算每一
个输入信号帧的循环冗余码 ( CRC ) , 并把计算得
到的循环冗余码附加到输入帧的末尾 。CRC - N 编
码器是通用 CRC编码器的简化 , 它的工作方式与
通用 CRC编码器类似 , 但是它提供了若干个经常
使用的生成多项式 , N 就表示这些生成多项式的最
高次数 。
3
3 CRC检测器 (CRC - N 检测器 )
与通用 CRC生成器 、CRC - N 生成器相对应 ,
CRC检测器也有两种 : 即通用 CRC检测器与 CRC
- N 检测器 。这两种检测器具有相同的工作原理 ,
它们首先从接收到的二进制序列中分离出信息序列
和 CRC, 然 后 根 据 接 收 端 的 信 息 序 列 重 新 计 算
CRC。如果重新计算得到的 CRC与接收到的 CRC
相等 , 则认为接收序列是正确的 ; 否则 , 则认为接
收序列存在着传输错误 。
4 CRC码的 Simulink仿真实现
4
1 仿真模型
CRC 码 的 仿 真 模 型 主 要 由 Bernoulli B inary
Generator (贝努利二进制序列生成器模块 ) , Zero
pad (零填充模块 ) , CRC - N Generator (CRC - N 生
成器 ) , CRC - N Syndrome Detector ( CRC - N 检测
器 )和 4 个输出模块 TO Workspace ( simout) 组成 。
通过设计各个模块的参数就可以得到仿真结果 。
通过 Simulink启动仿真模型运行 , 就可得到仿
真结果 。
另外 , 通过 Simulink中的 S函数也可以得到同
样的仿真结果 。与 CRC码仿真实现对应的是一个
离散状态的 S函数 , 其输入模块为 Bernoulli B inary
Gnerator模块 , 通过 S函数模块仿真后 , 把结果输
出到 To Workspace中 , 在这里选用的 CRC码的生
成多项式是 CRC - 16, 即为 G ( x) = x16 + x15 + x2 +
1, 消息为 D5, 对应的二进制序列为 m = [ 1 1 0 1
0 1 0 1 ]
4
function [ sys, x0, str, ts] = crcfunc ( t, x, u, flag) 定义 S函数
m = [ 1 1 0 1 0 1 0 1 ]; 消息对应的二进制序列
G = [ 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 ]; 生成多项式 G ( x) =
x16 + x1 5 + x2 + 1对应的二进制序列
switch flag, 根据 flag的值进行不同的 S函数操作
case 0
2 对应的 S函数代码 [ 3 ]
[ sys, x0, str, ts] = mdlInitializeSizes(m , G) ;
case 2
sys =mdlUpdate ( t, x, u, m , G) ;
case 3
sys =mdlOutputs( t, x, u, m, G) ;
case{1, 4, 9}
sys = [ ];
otherwise
error( [
unhandled flag =
, num2 str( flag) ] ) ;
end
function [ sys, x0, str, ts] =mdlInitializeSizes(m , G) 初始化 S
函数
sizes = sim sizes;
sizes
NumContStates = 0;
3
3
3
3
1
3
3
3
3
3
3
3
3
3
3
3
3
第 5卷 第 5期
Experiment Science & Technology
sizes
NumD iscStates = 1;
sizes
NumOutputs = 1;
sizes
Num Inputs = 1;
sizes
D irFeedthrough = 1;
NumSamp leTimes = 1;
sizes
sys = sim sizes( sizes) ;
x0 = ones(2, 1) ;
str = [ ];
ts = [ 1 0 ];
for i = 1: 24
if( i < = 8)
M ( i) =m ( i) ;
M ( i) = 0; 在消息后面补 16个零
else
end
end
R =M ( i)
| | G( i) 将 M 与 G进行模 2运算 ,相当于异
或运算
function sys =mdlUpdates( t, x, u, m , G) 更新离散状态
sys = R;
function sys =mdlOutputs( t, x, u, m , G) 计算输出结果
sys = R;
5 C语言实现的 CRC模块的嵌入
在实 际 工 作 中 , 往 往 存 在 用 其 他 语 言 实 现
CRC码的算法 , 因此有必要给出嵌入方法 。下面
我们用 C 语言实现 CRC 码的编译原理 , 并通过
Matlab的 MEX函数嵌入到 Matlab平台得到运行结
果 。下面是 CRC的 MEX函数对应的代码 , 在这个
程序中 , 输入的是字符串形式的信息 。
/
/
C语言编写的 MEX文件
头文件申明
/
/
#include
#include
#include < stdio
h >
#include < stdlib
h >
寄存器中的最高位
/
#define register_ topbit ( register_ run & ( 1 < < ( Register_
width - 1) ) ) > > (Register_width - 1)
/
/
信息的最高位
/
#define message _ topbit (message [ i ] & ( 1 < < (Message _
width - 1) ) ) > > ( Message_width - 1)
·74·
crc;
{
char
message;
unsigned short
int m = 0;
char
buff;
unsigned short bufflen = 1;
int status;
int ndim s;
const int
dim s;
得到输入参数 mxA rray数组的维数
/
ndim s =mxGetNumberOfD imensions(p rhs[ 0 ] ) ;
/
由输入参数 mxA rray数组得到一维整型数组
/
dim s =mxGetD imensions(p rhs[ 0 ] ) ;
/
for(m = 0; m < ndim s; m + + )
一维数组的大小
/
/
{
bufflen
}
bufflen + = 1;
= dim s[m ];
/
为接受 M atlab字符阵列字符串的 C字符串指针动
态分配内存
/
buff = ( char
) mxCalloc ( bufflen, sizeof( char) ) ;
得到输入参数 mxA rray数组的 C字符串指针
/
status =mxGetString (p rhs[ 0 ] , buff, bufflen) ;
/
把 C字符串指针赋给 crc_C ITT函数的参数 x
message = buff;
/
/
为输出参数 mxA rray数组创建数值矩阵
/
p lhs [ 0 ] = mxCreateNumericMatrix ( 1, 1, mxU INT16 _
/
CLASS, mxREAL) ;
/
由输出参数 mxA rray数组得到数值矩阵的数据指
针 ,并赋 crc_C ITT函数的参数 y
crc =mxGetData (p lhs[ 0 ] ) ;
/
调用
crc_C ITT函数
/
crc_C ITT(message, crc) ;
/
}
C语言编写的 crc_C ITT函数
/
int crc_C ITT( char message[ ] , short crc[ ] )
/
{
/
生成多项式
/
unsigned short polynom = 0x1021;
/
校验位宽度
/
int polynom _width = 16;
/
寄存器初值
/
unsigned short register
register_init = 0x0000;
入口程序
/
void mexFunction ( int nlhs, mxA rray
/
p lhs [ ] , int nrhs, const
/
寄存器值
/
mxA rray
p rhs[ ] )
unsigned short register
3
3
3
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
3
3
3
/
/
{
/
/
/
/
/
实 验 科 学 与 技 术
2007年 10月
·84·
register_run = register_init;
寄存器宽度
/
int Register_width = 16;
unsigned short joinone = 0x0001;
判断寄存器和信息最高位是否为 1
/
int isone_register = 0;
int isone_message = 0;
一个字符有八位
/
/
intM essage_width = 8;
int message_width = 8;
int i = 0, j = 0, I = 0;
信息的长度
/
/
I = strlen (message) ;
/
按位运算实现 CRC算法
对原有信息的操作
/
/
/
for( i = 0; i < I; i + + )
message_width = 8;
while (message_width -
- > 0)
/
{
isone_register = 0;
isone_message = 0;
判断寄存器和信息最高位是否为 1
if( register_topbit)
isone_register = 1;
else
isone_register = 0;
if(message_topbit)
isone_message = 1;
else
isone_message = 0;
寄存器左移一位 ,末尾默认是 0
/ register_run < < = 1;
如果移入寄存器的信息最高位为 1,寄存器末尾变为 1
if( register_topbit)
register_run < < = 1;
register_run = register_run^polynom;
register_run < < = 1;
{
}
else
}
}
crc[ 0 ] = register_run;
下面是在 Matlab中运行上述代码得到的结果 :
To get started, select MATLAB Help or Demos from the
Help menu
> > mex crc_C ITT
C
> > mex crc_C ITT
c
> > message =
123456789
message = 123456789
> > crc = crc_C ITT(message)
crc =
12739 (十进制表示 )
> > dec2hex ( crc)
ans =
31C3 (十六进制表示 )
6 结束语
差错控制在计算机网络中是一个不可或缺的功
能和服务 。借助一定的符号计算软件和仿真软件进
行实验可以避开硬件实验的条件问题 、编程实验的
难度问题 , 从而可以快速 、可视化地观察实验结
果 , 具有省时低耗的优势 。
if( isone_message)
信息左移一位
/
register_run = register_run^joinone;
参 考 文 献
message[ i] < < = 1;
如果寄存器的最高位为 1,用寄存器与生成多项式异或
/
的结果对寄存器重新赋值
/
[ 1 ] 陆正福 , 何英 , 杨邓奇 , 等
模归约算法的数学基
云南大学学报 : 自然科学版 , 2005, 27
础研究 [ J ]
(4) : 305 - 309
register_run = register_run^polynom;
[ 2 ] 王新梅 , 肖国镇
纠错码 ———原理与方法 [M ]
西
if( isone_register)
}
}
对附加位的操作
/
while (polynom _width -
/
- > 0)
{
安 : 西安电子科技大学出版社 , 2000
[ 3 ] 刘敏 , 魏玲
MATLAB 通信仿真与应用 [M ]
北京 :
国防工业出版社 , 2003
[ 4 ] 苏晓生
掌握 MATLAB及其工程应用 [M ]
北京 : 科
学出版社 , 2002
[ 5 ] 陈桂明
应用 MATLAB建模与仿真 [M ]
北京 : 科学
如果寄存器的最高位为 1,用寄存器与生成多项式异或
/
的结果对寄存器重新赋值 ,否则寄存器左移一位
/
出版社 , 2001