DogPawlowa 0 23 февраля, 2011 Опубликовано 23 февраля, 2011 · Жалоба Я расположил загрузчик и приложение в два разных банка, загрузчик ессно в нулевой, что вроде должно гарантировать неубиваемость загрузчика. Тем не менее пару раз из сотни наблюдал слёт загрузчика во время программирования банка приложения. Пытаюсь понять, в чем может быть причина. Если у кого есть мысли буду благодарен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Axel 1 24 февраля, 2011 Опубликовано 24 февраля, 2011 · Жалоба ...Если у кого есть мысли буду благодарен. Я использую отдельный банк для периодически обновляемых таблиц (проц R5F211B4). Около полутора сотен попыток были успешными. Может чего в коде неаккуратно... Или дополнительный кондер на питание... Или бубен... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 24 февраля, 2011 Опубликовано 24 февраля, 2011 · Жалоба Может чего в коде неаккуратно... Спасибо за инфо. Если можно, гляньте код. Он мне достался по наследству, что-то я правил, но в чем-то физически не мог разобраться, решал другие проблемы. А завтра заколачивание ящиков для отправки заказчику. unsigned char EraseFlash( void) { #ifdef FLASH_32 unsigned char * ers_addr=(unsigned char *)BEGIN_32; #endif #ifdef FLASH_64 unsigned char * ers_addr=(unsigned char *)BEGIN_64; #endif unsigned char erase_result; __disable_interrupt(); fmr0 = 0x01; // flash control register set asm(" "); // Description for preventing the abbreviation by optimization fmr0 = 0x03; // CPU rewrite enable fmr1 = 0x80; asm(" "); // Description for preventing the abbreviation by optimization fmr1 = 0x82; // EW1 mode fmr02 = 0; // Lock bit disable select bit fmr02 = 1; // Must write a 0 then a 1 in succession to SET fmr15 = 1; fmr15 = 0; // block0 enable bit *ers_addr = 0x50; // Clear status register *ers_addr = 0x20; // Block erase command write *ers_addr = 0xd0; // Block erase command write while( fmr00 != 1 ); // Ready check // Erase status check if( fmr07 == 1 ) { *ers_addr = 0x50; // Clear status register erase_result = IAP_ERASE_ERR; } else { erase_result = IAP_COMPLETE; } // flash control register reset fmr0 = 0x00; // CPU rewrite disable return erase_result; } unsigned char WriteFlash( unsigned char *write_addr_, unsigned char *write_data_, unsigned int size ) { unsigned char program_result = IAP_COMPLETE; int ii; unsigned char * fp=write_addr_; unsigned char * dp=write_data_; /* flash control register set */ fmr0 = 0x01; asm(" "); /* Description for preventing the abbreviation by optimization */ fmr0 = 0x03; /* CPU rewrite enable */ fmr1 = 0x80; asm(" "); /* Description for preventing the abbreviation by optimization */ fmr1 = 0x82; /* EW1 mode */ fmr02 = 0; // Lock bit disable select bit fmr02 = 1; // Must write a 0 then a 1 in succession to SET fmr15 = 1; fmr15 = 0; // block0 enable bit for( ii = 0; ii < size; ii++ ) { *fp = 0x50; // Clear status register *fp = 0x40; *fp = *dp; while( fmr00 != 1 ); // Ready check // Program status check if( fmr06 == 1 ) { // Program error *fp = 0x50; // Clear status register program_result = IAP_PROGRAM_ERR; break; } fp++; dp++; } // flash control register reset fmr0 = 0x00;//0x01; // CPU rewrite disable return program_result; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Axel 1 24 февраля, 2011 Опубликовано 24 февраля, 2011 · Жалоба Мой код практически такой-же: u8 flash_write(u8 *prog_data) { u8 i; u8 res = COMPLETE; u8 *write_addr = (u8 *)(*((u16 *)prog_data)); u16 size = *(u16 *)(prog_data + 2); u8 *data_addr = (u8 *)(prog_data + 4); asm("fclr i"); fmr0 = 0x01; asm(" "); fmr0 = 0x03; // CPU rewrite enable fmr1 = 0x80; asm(" "); fmr1 = 0x82; // EW1 mode for( i = 0; i < size; i++ ) { write_addr[i] = 0x40; write_addr[i] = data_addr[i]; while( fmr00 != 1 ); if( fmr06 == 1 ) // Program error { *write_addr = 0x50; // Clear stutus register res = DATA_PROGRAM_ERR; break; } } fmr0 = 0x01; // CPU rewrite disable asm("fset i"); return res; } / u8 block_erase(u8 block_num) { u8 res = COMPLETE; u8 *ers_addr; switch(block_num) { case 0: ers_addr = (u8 *)BLOCK_A; break; case 1: ers_addr = (u8 *)BLOCK_B; break; case 2: ers_addr = (u8 *)BLOCK_0; break; default: return ERASE_ERR; } asm("fclr i"); fmr0 = 0x01; asm(" "); fmr0 = 0x03; // CPU rewrite enable fmr1 = 0x80; asm(" "); fmr1 = 0x82; // EW1 mode *ers_addr = 0x20; // Block erase command write *ers_addr = 0xd0; // Block erase command write while( fmr00 != 1 ); if( fmr07 == 1 ) { *ers_addr = 0x50; // Clear stutus register res = ERASE_ERR; } fmr0 = 0x01; // CPU rewrite disable asm("fset i"); return res; } Может что-нибудь с запретом прерываний? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 25 февраля, 2011 Опубликовано 25 февраля, 2011 · Жалоба Мой код практически такой-же: Может что-нибудь с запретом прерываний? Спасибо большое, буду сравнивать. Прерывания запрещены. У меня нет ни анализа напряжения питания, ни WDT в загрузчике, может в этом причина. По сравнению с предыдущим чужим загрузчиком, стирающим оба банка, этот работает намного устойчивее, поэтому и случаи сброса его и причину трудно вычислить. Добавлено: Вроде выяснили, что резистор подтяжки сигнала Mode на плате, с которой больше всего работали, был припаян только одной стороной. Надеюсь, что так и было Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться