49
+ − 1 #include <iostream>
+ − 2
+ − 3 /* run this program using the console pauser or add your own getch, system("pause") or input loop */
+ − 4
+ − 5
+ − 6
+ − 7
+ − 8 #include <stdlib.h>
+ − 9
+ − 10 /******************************************************************************/
+ − 11 /* Start of crcmodel.h */
+ − 12 /******************************************************************************/
+ − 13 /* */
+ − 14 /* Author : Ross Williams (ross@guest.adelaide.edu.au.). */
+ − 15 /* Date : 3 June 1993. */
+ − 16 /* Status : Public domain. */
+ − 17 /* */
+ − 18 /* Description : This is the header (.h) file for the reference */
+ − 19 /* implementation of the Rocksoft^tm Model CRC Algorithm. For more */
+ − 20 /* information on the Rocksoft^tm Model CRC Algorithm, see the document */
+ − 21 /* titled "A Painless Guide to CRC Error Detection Algorithms" by Ross */
+ − 22 /* Williams (ross@guest.adelaide.edu.au.). This document is likely to be in */
+ − 23 /* "ftp.adelaide.edu.au/pub/rocksoft". */
+ − 24 /* */
+ − 25 /* Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia. */
+ − 26 /* */
+ − 27 /******************************************************************************/
+ − 28 /* */
+ − 29 /* How to Use This Package */
+ − 30 /* ----------------------- */
+ − 31 /* Step 1: Declare a variable of type cm_t. Declare another variable */
+ − 32 /* (p_cm say) of type p_cm_t and initialize it to point to the first */
+ − 33 /* variable (e.g. p_cm_t p_cm = &cm_t). */
+ − 34 /* */
+ − 35 /* Step 2: Assign values to the parameter fields of the structure. */
+ − 36 /* If you don't know what to assign, see the document cited earlier. */
+ − 37 /* For example: */
+ − 38 /* p_cm->cm_width = 16; */
+ − 39 /* p_cm->cm_poly = 0x8005L; */
+ − 40 /* p_cm->cm_init = 0L; */
+ − 41 /* p_cm->cm_refin = TRUE; */
+ − 42 /* p_cm->cm_refot = TRUE; */
+ − 43 /* p_cm->cm_xorot = 0L; */
+ − 44 /* Note: Poly is specified without its top bit (18005 becomes 8005). */
+ − 45 /* Note: Width is one bit less than the raw poly width. */
+ − 46 /* */
+ − 47 /* Step 3: Initialize the instance with a call cm_ini(p_cm); */
+ − 48 /* */
+ − 49 /* Step 4: Process zero or more message bytes by placing zero or more */
+ − 50 /* successive calls to cm_nxt. Example: cm_nxt(p_cm,ch); */
+ − 51 /* */
+ − 52 /* Step 5: Extract the CRC value at any time by calling crc = cm_crc(p_cm); */
+ − 53 /* If the CRC is a 16-bit value, it will be in the bottom 16 bits. */
+ − 54 /* */
+ − 55 /******************************************************************************/
+ − 56 /* */
+ − 57 /* Design Notes */
+ − 58 /* ------------ */
+ − 59 /* PORTABILITY: This package has been coded very conservatively so that */
+ − 60 /* it will run on as many machines as possible. For example, all external */
+ − 61 /* identifiers have been restricted to 6 characters and all internal ones to */
+ − 62 /* 8 characters. The prefix cm (for Crc Model) is used as an attempt to avoid */
+ − 63 /* namespace collisions. This package is endian independent. */
+ − 64 /* */
+ − 65 /* EFFICIENCY: This package (and its interface) is not designed for */
+ − 66 /* speed. The purpose of this package is to act as a well-defined reference */
+ − 67 /* model for the specification of CRC algorithms. If you want speed, cook up */
+ − 68 /* a specific table-driven implementation as described in the document cited */
+ − 69 /* above. This package is designed for validation only; if you have found or */
+ − 70 /* implemented a CRC algorithm and wish to describe it as a set of parameters */
+ − 71 /* to the Rocksoft^tm Model CRC Algorithm, your CRC algorithm implementation */
+ − 72 /* should behave identically to this package under those parameters. */
+ − 73 /* */
+ − 74 /******************************************************************************/
+ − 75
+ − 76 /* The following #ifndef encloses this entire */
+ − 77 /* header file, rendering it indempotent. */
+ − 78 #ifndef CM_DONE
+ − 79 #define CM_DONE
+ − 80
+ − 81 /******************************************************************************/
+ − 82
+ − 83 /* The following definitions are extracted from my style header file which */
+ − 84 /* would be cumbersome to distribute with this package. The DONE_STYLE is the */
+ − 85 /* idempotence symbol used in my style header file. */
+ − 86
+ − 87 #ifndef DONE_STYLE
+ − 88
+ − 89 typedef unsigned long ulong;
+ − 90 typedef unsigned char * p_ubyte_;
+ − 91
+ − 92 #ifndef TRUE
+ − 93 #define FALSE 0
+ − 94 #define TRUE 1
+ − 95 #endif
+ − 96
+ − 97 /* Change to the second definition if you don't have prototypes. */
+ − 98 #define P_(A) A
+ − 99 /* #define P_(A) () */
+ − 100
+ − 101 /* Uncomment this definition if you don't have void. */
+ − 102 /* typedef int void; */
+ − 103
+ − 104 #endif
+ − 105
+ − 106 /******************************************************************************/
+ − 107
+ − 108 /* CRC Model Abstract Type */
+ − 109 /* ----------------------- */
+ − 110 /* The following type stores the context of an executing instance of the */
+ − 111 /* model algorithm. Most of the fields are model parameters which must be */
+ − 112 /* set before the first initializing call to cm_ini. */
+ − 113 typedef struct
+ − 114 {
+ − 115 int cm_width; /* Parameter: Width in bits [8,32]. */
+ − 116 ulong cm_poly; /* Parameter: The algorithm's polynomial. */
+ − 117 ulong cm_init; /* Parameter: Initial register value. */
+ − 118 bool cm_refin; /* Parameter: Reflect input bytes? */
+ − 119 bool cm_refot; /* Parameter: Reflect output CRC? */
+ − 120 ulong cm_xorot; /* Parameter: XOR this to output CRC. */
+ − 121
+ − 122 ulong cm_reg; /* Context: Context during execution. */
+ − 123 } cm_t;
+ − 124 typedef cm_t *p_cm_t;
+ − 125
+ − 126 /******************************************************************************/
+ − 127
+ − 128 /* Functions That Implement The Model */
+ − 129 /* ---------------------------------- */
+ − 130 /* The following functions animate the cm_t abstraction. */
+ − 131
+ − 132 void cm_ini P_((p_cm_t p_cm));
+ − 133 /* Initializes the argument CRC model instance. */
+ − 134 /* All parameter fields must be set before calling this. */
+ − 135
+ − 136 void cm_nxt P_((p_cm_t p_cm,int ch));
+ − 137 /* Processes a single message byte [0,255]. */
+ − 138
+ − 139 void cm_blk P_((p_cm_t p_cm,p_ubyte_ blk_adr,ulong blk_len));
+ − 140 /* Processes a block of message bytes. */
+ − 141
+ − 142 ulong cm_crc P_((p_cm_t p_cm));
+ − 143 /* Returns the CRC value for the message bytes processed so far. */
+ − 144
+ − 145 /******************************************************************************/
+ − 146
+ − 147 /* Functions For Table Calculation */
+ − 148 /* ------------------------------- */
+ − 149 /* The following function can be used to calculate a CRC lookup table. */
+ − 150 /* It can also be used at run-time to create or check static tables. */
+ − 151
+ − 152 ulong cm_tab P_((p_cm_t p_cm,int index));
+ − 153 /* Returns the i'th entry for the lookup table for the specified algorithm. */
+ − 154 /* The function examines the fields cm_width, cm_poly, cm_refin, and the */
+ − 155 /* argument table index in the range [0,255] and returns the table entry in */
+ − 156 /* the bottom cm_width bytes of the return value. */
+ − 157
+ − 158 /******************************************************************************/
+ − 159
+ − 160 /* End of the header file idempotence #ifndef */
+ − 161 #endif
+ − 162
+ − 163 /******************************************************************************/
+ − 164 /* End of crcmodel.h */
+ − 165 /******************************************************************************/
+ − 166
+ − 167
+ − 168 /******************************************************************************/
+ − 169 /* Start of crcmodel.c */
+ − 170 /******************************************************************************/
+ − 171 /* */
+ − 172 /* Author : Ross Williams (ross@guest.adelaide.edu.au.). */
+ − 173 /* Date : 3 June 1993. */
+ − 174 /* Status : Public domain. */
+ − 175 /* */
+ − 176 /* Description : This is the implementation (.c) file for the reference */
+ − 177 /* implementation of the Rocksoft^tm Model CRC Algorithm. For more */
+ − 178 /* information on the Rocksoft^tm Model CRC Algorithm, see the document */
+ − 179 /* titled "A Painless Guide to CRC Error Detection Algorithms" by Ross */
+ − 180 /* Williams (ross@guest.adelaide.edu.au.). This document is likely to be in */
+ − 181 /* "ftp.adelaide.edu.au/pub/rocksoft". */
+ − 182 /* */
+ − 183 /* Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia. */
+ − 184 /* */
+ − 185 /******************************************************************************/
+ − 186 /* */
+ − 187 /* Implementation Notes */
+ − 188 /* -------------------- */
+ − 189 /* To avoid inconsistencies, the specification of each function is not echoed */
+ − 190 /* here. See the header file for a description of these functions. */
+ − 191 /* This package is light on checking because I want to keep it short and */
+ − 192 /* simple and portable (i.e. it would be too messy to distribute my entire */
+ − 193 /* C culture (e.g. assertions package) with this package. */
+ − 194 /* */
+ − 195 /******************************************************************************/
+ − 196
+ − 197 #include "crcmodel.h"
+ − 198
+ − 199 /******************************************************************************/
+ − 200
+ − 201 /* The following definitions make the code more readable. */
+ − 202
+ − 203 #define BITMASK(X) (1L << (X))
+ − 204 #define MASK32 0xFFFFFFFFL
+ − 205 #define LOCAL static
+ − 206
+ − 207 /******************************************************************************/
+ − 208
+ − 209 ulong reflect P_((ulong v,int b))
+ − 210 {
+ − 211 int i;
+ − 212 ulong t = v;
+ − 213 for (i=0; i<b; i++)
+ − 214 {
+ − 215 if (t & 1L)
+ − 216 v|= BITMASK((b-1)-i);
+ − 217 else
+ − 218 v&= ~BITMASK((b-1)-i);
+ − 219 t>>=1;
+ − 220 }
+ − 221 return v;
+ − 222 }
+ − 223
+ − 224 /******************************************************************************/
+ − 225
+ − 226 LOCAL ulong widmask (p_cm_t p_cm)
+ − 227 {
+ − 228 return (((1L<<(p_cm->cm_width-1))-1L)<<1)|1L;
+ − 229 }
+ − 230
+ − 231 /******************************************************************************/
+ − 232
+ − 233 void cm_ini (p_cm_t p_cm)
+ − 234 {
+ − 235 p_cm->cm_reg = p_cm->cm_init;
+ − 236 }
+ − 237
+ − 238 /******************************************************************************/
+ − 239
+ − 240 void cm_nxt (p_cm_t p_cm,int ch)
+ − 241 {
+ − 242 int i;
+ − 243 ulong uch = (ulong) ch;
+ − 244 ulong topbit = BITMASK(p_cm->cm_width-1);
+ − 245
+ − 246 if (p_cm->cm_refin) uch = reflect(uch,8);
+ − 247 p_cm->cm_reg ^= (uch << (p_cm->cm_width-8));
+ − 248 for (i=0; i<8; i++)
+ − 249 {
+ − 250 if (p_cm->cm_reg & topbit)
+ − 251 p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly;
+ − 252 else
+ − 253 p_cm->cm_reg <<= 1;
+ − 254 p_cm->cm_reg &= widmask(p_cm);
+ − 255 }
+ − 256 }
+ − 257
+ − 258 /******************************************************************************/
+ − 259
+ − 260 void cm_blk (p_cm_t p_cm,p_ubyte_ blk_adr,ulong blk_len)
+ − 261 {
+ − 262 while (blk_len--) cm_nxt(p_cm,*blk_adr++);
+ − 263 }
+ − 264
+ − 265 /******************************************************************************/
+ − 266
+ − 267 ulong cm_crc (p_cm_t p_cm)
+ − 268 {
+ − 269 if (p_cm->cm_refot)
+ − 270 return p_cm->cm_xorot ^ reflect(p_cm->cm_reg,p_cm->cm_width);
+ − 271 else
+ − 272 return p_cm->cm_xorot ^ p_cm->cm_reg;
+ − 273 }
+ − 274
+ − 275 /******************************************************************************/
+ − 276
+ − 277 ulong cm_tab (p_cm_t p_cm,int index)
+ − 278 {
+ − 279 int i;
+ − 280 ulong r;
+ − 281 ulong topbit = BITMASK(p_cm->cm_width-1);
+ − 282 ulong inbyte = (ulong) index;
+ − 283
+ − 284 if (p_cm->cm_refin) inbyte = reflect(inbyte,8);
+ − 285 r = inbyte << (p_cm->cm_width-8);
+ − 286 for (i=0; i<8; i++)
+ − 287 if (r & topbit)
+ − 288 r = (r << 1) ^ p_cm->cm_poly;
+ − 289 else
+ − 290 r<<=1;
+ − 291 if (p_cm->cm_refin) r = reflect(r,p_cm->cm_width);
+ − 292 return r & widmask(p_cm);
+ − 293 }
+ − 294
+ − 295 /******************************************************************************/
+ − 296 /* End of crcmodel.c */
+ − 297 /******************************************************************************/
+ − 298
+ − 299 #define uint32_t unsigned int
+ − 300 #define uint8_t unsigned char
+ − 301
+ − 302 uint32_t CRC_CalcBlockCRC(uint32_t *buffer, uint32_t words)
+ − 303 {
+ − 304 cm_t crc_model;
+ − 305 uint32_t word_to_do;
+ − 306 uint8_t byte_to_do;
+ − 307 int i;
+ − 308
+ − 309 // Values for the STM32F generator.
+ − 310
+ − 311 crc_model.cm_width = 32; // 32-bit CRC
+ − 312 crc_model.cm_poly = 0x04C11DB7; // CRC-32 polynomial
+ − 313 crc_model.cm_init = 0xFFFFFFFF; // CRC initialized to 1's
+ − 314 crc_model.cm_refin = FALSE; // CRC calculated MSB first
+ − 315 crc_model.cm_refot = FALSE; // Final result is not bit-reversed
+ − 316 crc_model.cm_xorot = 0x00000000; // Final result XOR'ed with this
+ − 317
+ − 318 cm_ini(&crc_model);
+ − 319
+ − 320 while (words--)
+ − 321 {
+ − 322 // The STM32F10x hardware does 32-bit words at a time!!!
+ − 323
+ − 324 word_to_do = *buffer++;
+ − 325
+ − 326 // Do all bytes in the 32-bit word.
+ − 327
+ − 328 for (i = 0; i < sizeof(word_to_do); i++)
+ − 329 {
+ − 330 // We calculate a *byte* at a time. If the CRC is MSB first we
+ − 331 // do the next MS byte and vica-versa.
+ − 332
+ − 333 if (crc_model.cm_refin == FALSE)
+ − 334 {
+ − 335 // MSB first. Do the next MS byte.
+ − 336
+ − 337 byte_to_do = (uint8_t) ((word_to_do & 0xFF000000) >> 24);
+ − 338 word_to_do <<= 8;
+ − 339 }
+ − 340 else
+ − 341 {
+ − 342 // LSB first. Do the next LS byte.
+ − 343
+ − 344 byte_to_do = (uint8_t) (word_to_do & 0x000000FF);
+ − 345 word_to_do >>= 8;
+ − 346 }
+ − 347
+ − 348 cm_nxt(&crc_model, byte_to_do);
+ − 349 }
+ − 350 }
+ − 351
+ − 352 // Return the final result.
+ − 353
+ − 354 return (cm_crc(&crc_model));
+ − 355 }
+ − 356
+ − 357
+ − 358 unsigned checksum(void *buffer, size_t len, unsigned int seed)
+ − 359 {
+ − 360 unsigned char *buf = (unsigned char *)buffer;
+ − 361 size_t i;
+ − 362
+ − 363 for (i = 0; i < len; ++i)
+ − 364 seed += (unsigned int)(*buf++);
+ − 365 return seed;
+ − 366 }
+ − 367
+ − 368 unsigned int crc32c_checksum(unsigned char* message, int length) {
+ − 369 int i, j;
+ − 370 unsigned int byte, crc, mask;
+ − 371 static unsigned int table[256] = {0};
+ − 372
+ − 373 /* Set up the table, if necessary. */
+ − 374
+ − 375 if (table[1] == 0) {
+ − 376 for (byte = 0; byte <= 255; byte++) {
+ − 377 crc = byte;
+ − 378 for (j = 7; j >= 0; j--) { // Do eight times.
+ − 379 mask = -(crc & 1);
+ − 380 crc = (crc >> 1) ^ (0xEDB88320 & mask);
+ − 381 }
+ − 382 table[byte] = crc;
+ − 383 }
+ − 384 }
+ − 385
+ − 386 /* Through with table setup, now calculate the CRC. */
+ − 387 i = 0;
+ − 388 crc = 0xFFFFFFFF;
+ − 389 while (length--) {
+ − 390 byte = message[i];
+ − 391 crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF];
+ − 392 i = i + 1;
+ − 393 }
+ − 394 return ~crc;
+ − 395 }
+ − 396
+ − 397
+ − 398
+ − 399
+ − 400
+ − 401
+ − 402 /******************************************************************************/
+ − 403
+ − 404 /* MAIN */
+ − 405 /* ----------------------- */
+ − 406 /* */
+ − 407
+ − 408
+ − 409 #include <stdio.h>
+ − 410 #include <string.h>
+ − 411 int main(int argc, char** argv) {
+ − 412
+ − 413
162
+ − 414 if (argc != 3) {
+ − 415 fprintf(stderr, "Usage: OSTC4pack_V4 <type> <bin file>\n");
+ − 416 return(-1);
+ − 417 }
+ − 418
699
+ − 419 FILE *fp;
49
+ − 420 size_t len;
+ − 421 unsigned char buf[1050000];
+ − 422 char *file = argv[2];
+ − 423 int type = atoi(argv[1]);
+ − 424 unsigned int pruefsumme;
+ − 425
+ − 426 //write File with length and cheksum
699
+ − 427 char filename[500], filenameout[511];
49
+ − 428 sprintf(filename,"%s",file);
+ − 429 int filelength = strlen(filename);
+ − 430 filename[filelength -4] = 0;
+ − 431
+ − 432 if (NULL == (fp = fopen(file, "rb")))
+ − 433 {
+ − 434 printf("Unable to open %s for reading\n", file);
+ − 435 return -1;
+ − 436 }
+ − 437 len = fread(buf, sizeof(char), sizeof(buf), fp);
699
+ − 438 printf("%d bytes read (hex: %#x )\n", (uint32_t)len, (uint32_t)len);
49
+ − 439 // unsigned int checksum = crc32c_checksum(buf, len);
+ − 440 unsigned int checksum = CRC_CalcBlockCRC((uint32_t *)buf, (uint32_t)(len/4));
+ − 441 printf("The checksum of %s is %#x\n", file, checksum);
+ − 442
+ − 443 fclose(fp);
+ − 444 if(type == 0)
+ − 445 sprintf(filenameout,"%s_upload.bin",filename);
+ − 446 else
+ − 447 if(type == 2)
162
+ − 448 sprintf(filenameout,"%s_upload.bin",filename);
49
+ − 449 else
+ − 450 sprintf(filenameout,"%s_upload.bin",filename);
+ − 451
+ − 452 unsigned char buf2[4];
+ − 453
+ − 454 buf2[0] = 0xFF & (len >> 24);;
+ − 455 buf2[1] = 0xFF & (len >> 16);;
+ − 456 buf2[2] = 0xFF & (len >> 8);
+ − 457 buf2[3] = 0xFF & len;
699
+ − 458 fp = fopen(filenameout, "wb");
49
+ − 459 fwrite(buf2,sizeof(char),4,fp);
+ − 460
+ − 461
+ − 462 unsigned char buf3offset[4];
+ − 463 unsigned char bufVersion[4];
+ − 464 if(type == 2)
+ − 465 {
+ − 466 buf3offset[0] = 0x10;
+ − 467 buf3offset[1] = 0x00;
+ − 468 buf3offset[2] = 0x03;
+ − 469 buf3offset[3] = 0x20;
+ − 470 bufVersion[0] = buf[0x00];
+ − 471 bufVersion[1] = buf[0x01];
+ − 472 bufVersion[2] = buf[0x02];
+ − 473 bufVersion[3] = buf[0x03];
+ − 474 }
+ − 475 else
+ − 476 if(type == 0)
+ − 477 {
+ − 478 buf3offset[0] = 0xFE;
+ − 479 buf3offset[1] = 'R';
+ − 480 buf3offset[2] = 'T';
+ − 481 buf3offset[3] = 'E';
+ − 482 bufVersion[0] = buf[0x5000];
+ − 483 bufVersion[1] = buf[0x5001];
+ − 484 bufVersion[2] = buf[0x5002];
+ − 485 bufVersion[3] = buf[0x5003];
+ − 486 }
+ − 487 else
+ − 488 {
+ − 489 buf3offset[0] = 0xFF;
+ − 490 buf3offset[1] = 0;
+ − 491 buf3offset[2] = 'H';
+ − 492 buf3offset[3] = 'W';
+ − 493 bufVersion[0] = buf[0x10000];
+ − 494 bufVersion[1] = buf[0x10001];
+ − 495 bufVersion[2] = buf[0x10002];
+ − 496 bufVersion[3] = buf[0x10003];
+ − 497 }
+ − 498
+ − 499 fwrite(buf3offset,sizeof(char),4,fp);
+ − 500
+ − 501 pruefsumme = len + (256*256*256*buf3offset[0]) + (256*256*buf3offset[1]) + (256*buf3offset[2]) + buf3offset[3];
+ − 502 fwrite(&pruefsumme,sizeof(char),4,fp);
+ − 503
+ − 504 fwrite(bufVersion,sizeof(char),4,fp);
+ − 505
+ − 506 for(int i = 0;i <len;i++)
+ − 507 {
699
+ − 508 if(fwrite(&buf[i],1,1,fp) != 1)
49
+ − 509 printf("error writing\n");
+ − 510 }
+ − 511
+ − 512
+ − 513 buf2[0] = 0xFF & (checksum >> 24);// & 0xFF000000;
+ − 514 buf2[1] = 0xFF & (checksum >> 16);
+ − 515 buf2[2] = 0xFF & (checksum >> 8);
+ − 516 buf2[3] = 0xFF & checksum;
+ − 517
+ − 518 fwrite(buf2,sizeof(char),4,fp);
699
+ − 519
+ − 520 fclose(fp);
49
+ − 521 }