rendered paste body // プログラムのチェック
#define CHECKSUM_ENABLED 0x7f /* ここのEEPROMアドレスにかかれているバイトが0ならばチェックサムのチェックをする */
#define CHECKSUM_H 0x7e /* チェックサム(h)のかかれているEEPROMアドレス */
#define CHECKSUM_L 0x7d /* チェックサム(l)のかかれているEEPROMアドレス */
#define PROGRAM_SIZE 2048 /* プログラムメモリのサイズ */
if(eeprom_read_byte((const uint8_t*)CHECKSUM_ENABLED) == 0)
{
unsigned char sum_l = 0, sum_h = 0;
unsigned short addr = PROGRAM_SIZE;
while(--addr)
{
unsigned char b = pgm_read_byte(addr);
sum_l += b;
sum_h += sum_l;
}
if(sum_l != eeprom_read_byte((const uint8_t*)CHECKSUM_L) ||
eeprom_read_byte((const uint8_t*)CHECKSUM_H))
{
for(;;) ; /* エラー */
}
}
/*------ 上と等価 ------*/
asm volatile(
"ldi r21, %4" "\n"
"rcall .pgmcheck_read_eeprom" "\n"
"and r16, r16" "\n"
"brne .pgmcheck_end" "\n" /* eeprom(CHECKSUM_ENABLED) != 0 then end */
"ldi r16, 0" "\n" /* r17 and r16 : checksums */
"ldi r17, 0" "\n"
"movw r30, r16" "\n" /* r30 : program addr */
"ldi r24, %7" "\n" /* r25:r24 : loop counter */
"ldi r25, %8" "\n"
".pgmcheck_loop:" "\n"
"lpm r20, Z+" "\n" /* read from program memory */
"add r16, r20" "\n" /* checksumming */
"add r17, r16" "\n" /* checksumming */
"sbiw r24, 1" "\n" /* loop counter -- */
"brne .pgmcheck_loop" "\n" /* loop not end ? then loop */
"ldi r21, %5" "\n"
"rcall .pgmcheck_read_eeprom" "\n"
"sub r16, r21" "\n" /* check sum l correct ? */
"brne .-2" "\n" /* not then, inifinite loop */
"ldi r21, %6" "\n"
"rcall .pgmcheck_read_eeprom" "\n"
"sub r17, r21" "\n" /* check sum h correct ? */
"brne .-2" "\n" /* not then, infinite loop */
"rjmp .pgmcheck_end" "\n"
".pgmcheck_read_eeprom:" "\n" /* sub routine to read eeprom */
"out %2, r21" "\n"
"sbi %0, %1" "\n"
"in r21, %3" "\n"
"ret" "\n"
".pgmcheck_end:" "\n"
:
:
/*%0*/"M"(_SFR_IO_ADDR(EECR)),
/*%1*/"M"(EERE),
/*%2*/"M"(_SFR_IO_ADDR(EEARL)),
/*%3*/"M"(_SFR_IO_ADDR(EEDR)),
/*%4*/"M"(CHECKSUM_ENABLED),
/*%5*/"M"(CHECKSUM_H),
/*%6*/"M"(CHECKSUM_L),
/*%7*/"M"(PROGRAM_SIZE>>8),
/*%8*/"M"(PROGRAM_SIZE&0xff)
:"r16", "r17", "r18", "r19", "r20", "r21", "r24", "r25", "r30", "r31"
);