Bläddra i källkod

New ML support - checksum and signature

Robert Pelnar 6 år sedan
förälder
incheckning
7619e94040
4 ändrade filer med 51 tillägg och 18 borttagningar
  1. 21 10
      Firmware/Marlin_main.cpp
  2. 22 3
      Firmware/language.c
  3. 4 1
      Firmware/language.h
  4. 4 4
      Firmware/ultralcd.cpp

+ 21 - 10
Firmware/Marlin_main.cpp

@@ -1113,7 +1113,7 @@ uint8_t lang_xflash_enum_codes(uint16_t* codes)
 		printf_P(_n(" _lt_count        = 0x%04x (%d)\n"), header.count, header.count);
 		printf_P(_n(" _lt_chsum        = 0x%04x\n"), header.checksum);
 		printf_P(_n(" _lt_code         = 0x%04x (%c%c)\n"), header.code, header.code >> 8, header.code & 0xff);
-		printf_P(_n(" _lt_resv1        = 0x%08lx\n"), header.reserved1);
+		printf_P(_n(" _lt_sign         = 0x%08lx\n"), header.signature);
 
 		addr += header.size;
 		codes[count] = header.code;
@@ -1190,7 +1190,7 @@ void setup()
 #ifdef DEBUG_SEC_LANG
 	lang_table_header_t header;
 	uint32_t src_addr = 0x00000;
-	if (lang_get_header(3, &header, &src_addr))
+	if (lang_get_header(1, &header, &src_addr))
 	{
 //this is comparsion of some printing-methods regarding to flash space usage and code size/readability
 #define LT_PRINT_TEST 2
@@ -1207,7 +1207,7 @@ void setup()
 		printf_P(_n(" _lt_count = 0x%04x (%d)\n"), header.count, header.count);
 		printf_P(_n(" _lt_chsum = 0x%04x\n"), header.checksum);
 		printf_P(_n(" _lt_code  = 0x%04x (%c%c)\n"), header.code, header.code >> 8, header.code & 0xff);
-		printf_P(_n(" _lt_resv1 = 0x%08lx\n"), header.reserved1);
+		printf_P(_n(" _lt_sign = 0x%08lx\n"), header.signature);
 #elif (LT_PRINT_TEST==2) //optimized printf
 		printf_P(
 		 _n(
@@ -1225,7 +1225,7 @@ void setup()
 		 header.count, header.count,
 		 header.checksum,
 		 header.code, header.code >> 8, header.code & 0xff,
-		 header.reserved1
+		 header.signature
 		);
 #elif (LT_PRINT_TEST==3) //arduino print/println (leading zeros not solved)
 		MYSERIAL.print(" _src_addr = 0x");
@@ -1252,7 +1252,7 @@ void setup()
 		MYSERIAL.print((char)(header.code & 0xff), 0);
 		MYSERIAL.println(")");
 		MYSERIAL.print(" _lt_resv1 = 0x");
-		MYSERIAL.println(header.reserved1, 16);
+		MYSERIAL.println(header.signature, 16);
 #endif //(LT_PRINT_TEST==)
 #undef LT_PRINT_TEST
 
@@ -1265,7 +1265,22 @@ void setup()
 			if ((i % 16) == 15) putchar('\n');
 		}
 #endif
-#if 1
+		uint16_t sum = 0;
+		for (uint16_t i = 0; i < header.size; i++)
+			sum += (uint16_t)pgm_read_byte((uint8_t*)(_SEC_LANG_TABLE + i)) << ((i & 1)?0:8);
+		printf_P(_n("_SEC_LANG_TABLE checksum = %04x\n"), sum);
+		sum -= header.checksum; //subtract checksum
+		printf_P(_n("_SEC_LANG_TABLE checksum = %04x\n"), sum);
+		sum = (sum >> 8) | ((sum & 0xff) << 8); //swap bytes
+		if (sum == header.checksum)
+			printf_P(_n("Checksum OK\n"), sum);
+		else
+			printf_P(_n("Checksum NG\n"), sum);
+	}
+	else
+		printf_P(_n("lang_get_header failed!\n"));
+
+#if 0
 		for (uint16_t i = 0; i < 1024*10; i++)
 		{
 			if ((i % 16) == 0) printf_P(_n("%04x:"), _SEC_LANG_TABLE+i);
@@ -1273,10 +1288,6 @@ void setup()
 			if ((i % 16) == 15) putchar('\n');
 		}
 #endif
-	}
-	else
-		printf_P(_n("lang_get_header failed!\n"));
-
 
 #if 0
 	SERIAL_ECHOLN("Reading eeprom from 0 to 100: start");

+ 22 - 3
Firmware/language.c

@@ -28,6 +28,9 @@ uint8_t lang_is_selected(void) { return 1; }
 //reserved xx kbytes for secondary language table
 const char _SEC_LANG[LANG_SIZE_RESERVED] PROGMEM_I2 = "_SEC_LANG";
 
+//primary language signature
+const uint32_t _PRI_LANG_SIGNATURE[1] __attribute__((section(".progmem0"))) = {0xffffffff};
+
 //lang_table pointer
 lang_table_t* lang_table = 0;
 
@@ -56,8 +59,12 @@ uint8_t lang_select(uint8_t lang)
 	{
 		if (pgm_read_dword(((uint32_t*)_SEC_LANG_TABLE)) == LANG_MAGIC) //magic valid
 		{
-			lang_table = _SEC_LANG_TABLE; // set table pointer
-			lang_selected = lang; // set language id
+			if (lang_check(_SEC_LANG_TABLE))
+				if (pgm_read_dword(((uint32_t*)(_SEC_LANG_TABLE + 12))) == pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE)))) //signature valid
+				{
+					lang_table = _SEC_LANG_TABLE; // set table pointer
+					lang_selected = lang; // set language id
+				}
 		}
 	}
 #else //W25X20CL
@@ -70,6 +77,18 @@ uint8_t lang_select(uint8_t lang)
 	return 0;
 }
 
+uint8_t lang_check(uint16_t addr)
+{
+	uint16_t sum = 0;
+	uint16_t size = pgm_read_word((uint16_t*)(addr + 4));
+	uint16_t lt_sum = pgm_read_word((uint16_t*)(addr + 8));
+	uint16_t i; for (i = 0; i < size; i++)
+		sum += (uint16_t)pgm_read_byte((uint8_t*)(addr + i)) << ((i & 1)?0:8);
+	sum -= lt_sum; //subtract checksum
+	sum = (sum >> 8) | ((sum & 0xff) << 8); //swap bytes
+	return (sum == lt_sum);
+}
+
 uint8_t lang_get_count()
 {
 #ifdef W25X20CL
@@ -98,7 +117,7 @@ uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* off
 		uint16_t ui = _SEC_LANG_TABLE; //table pointer
 		memcpy_P(header, ui, sizeof(lang_table_header_t)); //read table header from progmem
 		if (offset) *offset = ui;
-		return (header == LANG_MAGIC)?1:0; //return 1 if magic valid
+		return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid
 	}
 	W25X20CL_SPI_ENTER();
 	uint32_t addr = 0x00000; //start of xflash

+ 4 - 1
Firmware/language.h

@@ -52,7 +52,7 @@ typedef struct
 	uint16_t count;      //+6
 	uint16_t checksum;   //+8
 	uint16_t code;       //+10
-	uint32_t reserved1;  //+12
+	uint32_t signature;  //+12
 } lang_table_header_t;
 
 //lang_table_t structure - (size= 16byte + 2*count)
@@ -98,10 +98,13 @@ extern uint8_t lang_selected;
 extern const char _SEC_LANG[LANG_SIZE_RESERVED];
 extern const char* lang_get_translation(const char* s);
 #define _SEC_LANG_TABLE ((((uint16_t)&_SEC_LANG) + 0x00ff) & 0xff00)
+//extern const uint32_t _PRI_LANG_SIGNATURE;
 #endif //(LANG_MODE != 0)
 
 //selects language, eeprom is updated in case of success
 extern uint8_t lang_select(uint8_t lang);
+//performs checksum test of secondary language data
+extern uint8_t lang_check(uint16_t addr);
 //returns total number of languages (primary + all in xflash)
 extern uint8_t lang_get_count(void);
 //reads lang table header and offset in xflash or progmem

+ 4 - 4
Firmware/ultralcd.cpp

@@ -3682,16 +3682,16 @@ void lcd_set_progress() {
 static void lcd_language_menu()
 {
 	START_MENU();
-	if (lang_is_selected()) MENU_ITEM(back, _T(MSG_SETTINGS), 0);
-	MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(0)), 0);
+	if (lang_is_selected()) MENU_ITEM(back, _T(MSG_SETTINGS), 0); //
+	MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(0)), 0); //primary language
 	uint8_t cnt = lang_get_count();
 #ifdef W25X20CL
 	if (cnt == 2) //display secondary language in case of clear xflash 
 		MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(1)), 1);
 	else
-		for (int i = 2; i < cnt; i++) //skip seconday language - solved in lang_select
+		for (int i = 2; i < cnt; i++) //skip seconday language - solved in lang_select (MK3)
 #else //W25X20CL
-		for (int i = 1; i < cnt; i++) //all seconday languages
+		for (int i = 1; i < cnt; i++) //all seconday languages (MK2/25)
 #endif //W25X20CL
 			MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(i)), i);
 	END_MENU();