ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
25 ноября
143307 Топик полностью
modiffer (25.12.2008 12:28, просмотров: 194) ответил Сергей Борщ на А чтение "в лоб", по указателю. Адресное пространство одно.
не удалось по IAP интерфейсу программировать Исходники прилагаются, вопрос: в чем собственно проблема? это некорректный код IAP или проблема загрузчика, или в что не так?.. (Программирую в Keil, отладка через j-link6) Исходник IAP: #include <LPC23xx.H> // Clock Frequency #define XTAL 12000000 // Oscillator Frequency #ifdef BYPASS_PLL #define CPUCLK XTAL // CPU Clock without PLL #else #define CPUCLK (XTAL*5) // CPU Clock with PLL #endif #define CCLK (CPUCLK / 1000) // CPU Clock in kHz // Phase Locked Loop (PLL) definitions #define PLL_BASE 0xE01FC080 // PLL Base Address #define PLLCON_OFS 0x00 // PLL Control Offset #define PLLSTAT_OFS 0x08 // PLL Status Offset #define PLLFEED_OFS 0x0C // PLL Feed Offset #define PLLCON_PLLE 0x01 // PLL Enable #define PLLCON_PLLD 0x00 // PLL Disable #define PLLCON_PLLC 0x03 // PLL Connect #define PLLSTAT_PLOCK 0x0400 // PLL Lock Status struct iap_in { unsigned int cmd; unsigned int par[4]; }; typedef void (*IAP)(struct iap_in *in, unsigned int *result); #define iap_entry ((IAP) 0x7FFFFFF1) // IAP Entry Point /* Default Interrupt Function: may be called when interrupts are disabled */ void def_isr (void) __irq { ; } #ifdef BYPASS_PLL /* * PLL Feed Sequence */ void feed_pll (void) { unsigned int adr, r1, r2; adr = PLL_BASE; __asm { MOV r1, #0xAA MOV r2, #0x55 STR r1, [adr, #PLLFEED_OFS] STR r2, [adr, #PLLFEED_OFS] } } /* * Switch CPU to PLL clock */ void start_pll (void) { PLLCON = PLLCON_PLLE; feed_pll(); while ((PLLSTAT & PLLSTAT_PLOCK) == 0); PLLCON = PLLCON_PLLC; feed_pll(); } /* * Switch CPU to standard XTAL */ void stop_pll(void) { PLLCON = PLLCON_PLLD; feed_pll(); } #endif /* * Convert 'addr' to Sector Number */ unsigned int get_secnum (unsigned int addr) { unsigned int n; n = ((unsigned int) addr >> 13) & 0x1F; // Pseudo Sector Number if (n >= (0x30000 >> 13)) { n -= 14; // High Small 8kB Sectors } else if (n >= (0x10000 >> 13)) { n = 7 + (n >> 3); // Large 64kB Sectors } return (n); // Sector Number } /* * Erase Sector between 'start' and 'end' * Return: IAP Error Code (0 when OK) */ unsigned int erase (unsigned int start, unsigned int end) { struct iap_in iap; // IAP Input Parameters unsigned int result[16]; // IAP Results #ifdef BYPASS_PLL stop_pll(); // IAP requires to run without PLL #endif iap.cmd = 50; // IAP Command: Prepare Sectors for Write iap.par[0] = get_secnum (start); // Start Sector iap.par[1] = get_secnum (end); // End Sector iap_entry (&iap, result); // Call IAP Function if (result[0]) goto exit; // Error occured? iap.cmd = 52; // IAP Command: Erase Flash iap.par[0] = get_secnum (start); // Start Sector iap.par[1] = get_secnum (end); // End Sector iap.par[2] = CCLK; // CPU Clock iap_entry (&iap, result); // Call IAP Function exit: #ifdef BYPASS_PLL start_pll(); // Start PLL #endif return (result[0]); } /* * Program *data to addr, number of bytes specified by size * Return: IAP Error Code (0 when OK) * NOTES: size should be 512, 1024, 4096 or 8192 */ unsigned int program (unsigned int addr, unsigned char *data, unsigned int size) { struct iap_in iap; // IAP Input Parameters unsigned int result[16]; // IAP Results #ifdef BYPASS_PLL stop_pll(); // IAP requires to run without PLL #endif iap.cmd = 50; // IAP Command: Prepare Sectors for Write iap.par[0] = get_secnum (addr); // Start Sector iap.par[1] = iap.par[0]; // End Sector iap_entry (&iap, result); // Call IAP Function if (result[0]) goto exit; // Error occured? iap.cmd = 51; // IAP Command: Copy RAM to Flash iap.par[0] = addr; // Destination Address iap.par[1] = (unsigned int) data; // Source Address iap.par[2] = size; // Number of Bytes iap.par[3] = CCLK; // CPU Clock iap_entry (&iap, result); // Call IAP Function exit: #ifdef BYPASS_PLL start_pll(); // Start PLL #endif return (result[0]); } unsigned char vals[512]; void main (void) { unsigned int i; unsigned int volatile start; for (start = 0; start < 1000000; start++) { ; // wait for debugger connection (about 0.3 sec) } for (i = 0; i < sizeof (vals); i++) { vals[i] = (unsigned char) i; } erase (0x30000, 0x33FFF); program (0x30000, vals, sizeof (vals)); program (0x31000, vals, sizeof (vals)); program (0x32000, vals, sizeof (vals)); while (1); } Детали ошибок: При отладке кода, на железе: erase (0x30000, 0x33FFF); - проходит успешно (т.е.: оба обращение к iap_entry возвращают 0 т.е.: подготовка и стирание памяти проходит успешно) НО при просмотре блоков 0x30000 - 0x33FFF наблюдается что они все же НЕ СТЕРТЫ... При попытке записи: program (0x30000, vals, sizeof (vals)); Подготовка проходит успешно, но запись возвращает 0х09 т.е. ошибку что память не подготовлена, хотя это подготовка прошла успешно... По форумам удалось выяснить что в bootloader-ax ниже версии (1.58 для 21хх) и 1.63 могут быть проблемы с IAP интерфейсом. Кто сталкивался, варианты решение?