📄 crc.c
字号:
/**********************************************************************
*
* Filename: crc.c
*
* Description: A table-driven implementation of CRC-CCITT checksums.
*
**********************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include <time.h>
#include <unistd.h>
#include <sys/alt_timestamp.h>
/*
* The CRC parameters. Currently configured for CCITT.
* Simply modify these to switch to another CRC standard.
*/
#define POLYNOMIAL 0x1021
#define INITIAL_REMAINDER 0xFFFF
#define FINAL_XOR_VALUE 0x0000
/*
* The width of the CRC calculation and result.
* Modify the typedef for an 8 or 32-bit CRC standard.
*/
typedef unsigned short width;
#define WIDTH (8 * sizeof(width))
#define TOPBIT (1 << (WIDTH - 1))
/*
* An array containing the pre-computed intermediate result for each
* possible byte of input. This is used to speed up the computation.
*/
width crcTable[256];
/**********************************************************************
*
* Function: crcInit()
*
* Description: Initialize the CRC lookup table. This table is used
* by crcCompute() to make CRC computation faster.
*
* Notes: The mod-2 binary long division is implemented here.
*
* Returns: None defined.
*
**********************************************************************/
void
crcInit(void)
{
width remainder;
width dividend;
int bit;
/*
* Perform binary long division, a bit at a time.
*/
for (dividend = 0; dividend < 256; dividend++)
{
/*
* Initialize the remainder.
*/
remainder = dividend << (WIDTH - 8);
/*
* Shift and XOR with the polynomial.
*/
for (bit = 0; bit < 8; bit++)
{
/*
* Try to divide the current data bit.
*/
if (remainder & TOPBIT)
{
remainder = (remainder << 1) ^ POLYNOMIAL;
}
else
{
remainder = remainder << 1;
}
}
/*
* Save the result in the table.
*/
crcTable[dividend] = remainder;
}
} /* crcInit() */
/**********************************************************************
*
* Function: crcCompute()
*
* Description: Compute the CRC checksum of a binary message block.
*
* Notes: This function expects that crcInit() has been called
* first to initialize the CRC lookup table.
*
* Returns: The CRC of the data.
*
**********************************************************************/
unsigned short crcCompute(unsigned char * message, unsigned int nBytes)
{
unsigned int offset;
unsigned char byte;
width remainder = INITIAL_REMAINDER;
/*
* Divide the message by the polynomial, a byte at time.
*/
for (offset = 0; offset < nBytes; offset++)
{
byte = (remainder >> (WIDTH - 8)) ^ message[offset];
remainder = crcTable[byte] ^ (remainder << 8);
}
/*
* The final remainder is the CRC result.
*/
return (remainder ^ FINAL_XOR_VALUE);
} /* crcCompute() */
/**********************************************************************
*
* Function: main()
*
* Description: computes CRC for data block after copying from flash to SRAM
*
* Notes: This function expects that crcInit() has been called
* first to initialize the CRC lookup table.
* This Fuction has been modified from the original file
* for the purposes of a Nios custom instruction lab/demo
*
* Returns: n/a
*
**********************************************************************/
int main(void)
{
#define data_block_begin 0x600000
#define data_block_end 0x63ffff
#define data_sram_copy 0x8a0000
unsigned short int crc_result;
unsigned int hex_digits;
unsigned int* read_data;
unsigned int* write_data;
// unsigned char * byte_pointer;
unsigned int data_block_length;
alt_u32 num_ticks = 0;
alt_u32 time1, time2, timer_overhead;
// Copy data block to SRAM so that Flash access time does not effect results
write_data = (int*)data_sram_copy;
for (read_data = (int*)data_block_begin; (int*)read_data <= (int*)data_block_end; read_data++)
{
*write_data = *read_data;
write_data++;
}
crcInit();
data_block_length = (char*)data_block_end - (char*)data_block_begin + 1;
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0);
// Start Timer:
if(alt_timestamp_start() < 0)
{
printf("Timer init failed \n");
exit(0);
}
// Get the number of clocks it takes + record time stamp:
time1 = alt_timestamp();
time2 = alt_timestamp();
timer_overhead = time2 - time1;
time1 = alt_timestamp();
for (hex_digits = 0; hex_digits <= 0x80; hex_digits++)
{
crc_result = crcCompute((char*)data_sram_copy, data_block_length);
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,hex_digits>>3);
}
time2 = alt_timestamp();
num_ticks = time2 - time1 - timer_overhead;
printf ("\nCRC for Data Block = 0x%x.\n", crc_result);
printf("CPU time(ms): %.*f\n", 2, ((float)num_ticks/(float)alt_timestamp_freq()) * (float)1000);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -