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
|
|
414 FILE *fp, * fpout;
|
|
415 size_t len;
|
|
416 unsigned char buf[1050000];
|
|
417 char *file = argv[2];
|
|
418 int type = atoi(argv[1]);
|
|
419 unsigned int pruefsumme;
|
|
420
|
|
421 //write File with length and cheksum
|
|
422 char filename[500], filenameout[510] ;
|
|
423 sprintf(filename,"%s",file);
|
|
424 int filelength = strlen(filename);
|
|
425 filename[filelength -4] = 0;
|
|
426
|
|
427 if (NULL == (fp = fopen(file, "rb")))
|
|
428 {
|
|
429 printf("Unable to open %s for reading\n", file);
|
|
430 return -1;
|
|
431 }
|
|
432 len = fread(buf, sizeof(char), sizeof(buf), fp);
|
|
433 printf("%d bytes read (hex: %#x )\n", len,len);
|
|
434 // unsigned int checksum = crc32c_checksum(buf, len);
|
|
435 unsigned int checksum = CRC_CalcBlockCRC((uint32_t *)buf, (uint32_t)(len/4));
|
|
436 printf("The checksum of %s is %#x\n", file, checksum);
|
|
437
|
|
438 fclose(fp);
|
|
439 if(type == 0)
|
|
440 sprintf(filenameout,"%s_upload.bin",filename);
|
|
441 else
|
|
442 if(type == 2)
|
|
443 sprintf(filenameout,"OSTC4_FONT_upload.bin",filename);
|
|
444 else
|
|
445 sprintf(filenameout,"%s_upload.bin",filename);
|
|
446
|
|
447 unsigned char buf2[4];
|
|
448
|
|
449 buf2[0] = 0xFF & (len >> 24);;
|
|
450 buf2[1] = 0xFF & (len >> 16);;
|
|
451 buf2[2] = 0xFF & (len >> 8);
|
|
452 buf2[3] = 0xFF & len;
|
|
453 fpout = fopen(filenameout, "wb");
|
|
454 fwrite(buf2,sizeof(char),4,fp);
|
|
455
|
|
456
|
|
457 unsigned char buf3offset[4];
|
|
458 unsigned char bufVersion[4];
|
|
459 if(type == 2)
|
|
460 {
|
|
461 buf3offset[0] = 0x10;
|
|
462 buf3offset[1] = 0x00;
|
|
463 buf3offset[2] = 0x03;
|
|
464 buf3offset[3] = 0x20;
|
|
465 bufVersion[0] = buf[0x00];
|
|
466 bufVersion[1] = buf[0x01];
|
|
467 bufVersion[2] = buf[0x02];
|
|
468 bufVersion[3] = buf[0x03];
|
|
469 }
|
|
470 else
|
|
471 if(type == 0)
|
|
472 {
|
|
473 buf3offset[0] = 0xFE;
|
|
474 buf3offset[1] = 'R';
|
|
475 buf3offset[2] = 'T';
|
|
476 buf3offset[3] = 'E';
|
|
477 bufVersion[0] = buf[0x5000];
|
|
478 bufVersion[1] = buf[0x5001];
|
|
479 bufVersion[2] = buf[0x5002];
|
|
480 bufVersion[3] = buf[0x5003];
|
|
481 }
|
|
482 else
|
|
483 {
|
|
484 buf3offset[0] = 0xFF;
|
|
485 buf3offset[1] = 0;
|
|
486 buf3offset[2] = 'H';
|
|
487 buf3offset[3] = 'W';
|
|
488 bufVersion[0] = buf[0x10000];
|
|
489 bufVersion[1] = buf[0x10001];
|
|
490 bufVersion[2] = buf[0x10002];
|
|
491 bufVersion[3] = buf[0x10003];
|
|
492 }
|
|
493
|
|
494 fwrite(buf3offset,sizeof(char),4,fp);
|
|
495
|
|
496 pruefsumme = len + (256*256*256*buf3offset[0]) + (256*256*buf3offset[1]) + (256*buf3offset[2]) + buf3offset[3];
|
|
497 fwrite(&pruefsumme,sizeof(char),4,fp);
|
|
498
|
|
499 fwrite(bufVersion,sizeof(char),4,fp);
|
|
500
|
|
501 for(int i = 0;i <len;i++)
|
|
502 {
|
|
503 if(fwrite(&buf[i],1,1,fpout) != 1)
|
|
504 printf("error writing\n");
|
|
505 }
|
|
506
|
|
507
|
|
508 buf2[0] = 0xFF & (checksum >> 24);// & 0xFF000000;
|
|
509 buf2[1] = 0xFF & (checksum >> 16);
|
|
510 buf2[2] = 0xFF & (checksum >> 8);
|
|
511 buf2[3] = 0xFF & checksum;
|
|
512
|
|
513 fwrite(buf2,sizeof(char),4,fp);
|
|
514
|
|
515 }
|
|
516
|
|
517
|
|
518
|
|
519
|
|
520
|