Dron_Gus 2 12 июля, 2007 Опубликовано 12 июля, 2007 · Жалоба Отладчик в таких ситуациях может только мешать. Советую попробовать без него. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Annuta 0 12 июля, 2007 Опубликовано 12 июля, 2007 · Жалоба Спасибо, Dron_Gus!... да именно из-за этого плата и перегружалась... Теперь не перегружаеься... но и не работает.... :( __ramfunc int EFCWrite(u32 adr, u8 *pbuf, u32 Len, u32 NeedReset) { u32 l; unsigned int *pflash; unsigned int page; unsigned int region; unsigned int i; l=0; while (l<Len) { pflash = (unsigned int *)adr; page = (adr & 0x3FFFF)/EFC_PAGE_SIZE; region = (page/EFC_PagesInTheLockRegion); if (AT91C_BASE_MC->MC_FSR & (region << 16)) { // lock set, clear it AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN)&(50 <<16)) | AT91C_MC_FWS_2FWS; AT91C_BASE_MC->MC_FCR = (0x5A << 24) | (region << 8 ) |AT91C_MC_FCMD_UNLOCK; } while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY)); for (i = 0; i < EFC_PAGE_SIZE_UINT; i++) *(pflash + i ) = *(pbuf + i); AT91C_BASE_MC->MC_FCR = (0x5A << 24) | (page << 8 ) |AT91C_MC_FCMD_START_PROG; while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY)); l+=EFC_PAGE_SIZE; adr+=EFC_PAGE_SIZE; } if (NeedReset) { __asm("sub r0, r0,r0;"); __asm("bx r0;"); } return (Len * AT91C_IFLASH_PAGE_SIZE); } вот - делаю как... Прошивка доходит до волшебной строчки AT91C_BASE_MC->MC_FCR = (0x5A << 24) | (page << 8 ) |AT91C_MC_FCMD_START_PROG; ... и всё... дальше... тормоз!... Возвращает "0" .. естевтсвенно... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexBoy 0 12 июля, 2007 Опубликовано 12 июля, 2007 · Жалоба вот - делаю как... Прошивка доходит до волшебной строчки AT91C_BASE_MC->MC_FCR = (0x5A << 24) | (page << 8 ) |AT91C_MC_FCMD_START_PROG; ... и всё... дальше... тормоз!... Возвращает "0" .. естевтсвенно... в это фрагменте ошибочка, pbuf у вас объявлен как "u8 *pbuf" соответственно читается по 1 байту а пишется по 4. pbuf должен быть "unsigned int *" или заведите локальную переменную и сделайте преобразование к этому типу. for (i = 0; i < EFC_PAGE_SIZE_UINT; i++) *(pflash + i ) = *(pbuf + i); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timofey_219 0 12 июля, 2007 Опубликовано 12 июля, 2007 · Жалоба В функцию EFCWrite(); передается адрес 0x0030000 - область ОЗУ после ремапа, причем получается 196 608 байт, хотя у этого контроллера 64 кб ОЗУхи или я не прав? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexBoy 0 13 июля, 2007 Опубликовано 13 июля, 2007 · Жалоба В функцию EFCWrite(); передается адрес 0x0030000 - область ОЗУ после ремапа, причем получается 196 608 байт, хотя у этого контроллера 64 кб ОЗУхи или я не прав? прав на 100% #define TestAddr 0x0030000 при вызове EFCWrite(adr, pbuf, Len, NeedReset) adr должен показывать на адрес внутри флеша #define AT91C_IFLASH ((char *)0x00100000) // Internal FLASH base address #define AT91C_IFLASH_SIZE ((unsigned int) 0x00040000) // Internal FLASH size in byte (256 Kbytes) причем не на начало, чтобы не стереть программу, можно так: #define TestAddr (AT91C_IFLASH+AT91C_IFLASH_SIZE-sizeof(buf1)) To Annuta: Полезно иногда заглядывать в файл AT91SAM7X256.h, там все константы описаны, чтоб не делать таких ошибок с размещением. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timofey_219 0 13 июля, 2007 Опубликовано 13 июля, 2007 · Жалоба To Annuta: Полезно иногда заглядывать в файл AT91SAM7X256.h, там все константы описаны, чтоб не делать таких ошибок с размещением. Она просто учится :) Про ремап я просто забыл сообщить :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Annuta 0 13 июля, 2007 Опубликовано 13 июля, 2007 · Жалоба Получилось!!! Спасибо БОЛЬШОЕ всем за помощь!!! :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Waso 1 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба Мне в AT91 нужно менять только одно слово во флеше. Обязательно ли для этого читать всю страницу, содержащую слово, менять его и записывать всю страницу обратно? Или можно канибудь проще? Мне не ради простоты а ради удлинения срока службы флеша... (реализую файловую систему. файлы будут больше читаться, писАться - редко, но тем не менее...) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба Мне в AT91 нужно менять только одно слово во флеше. Обязательно ли для этого читать всю страницу, содержащую слово, менять его и записывать всю страницу обратно?Если менять с единиц на нолики - не обязательно. Если с ноликов на единицы - да, обязательно. Причем не обязательно читать-менять-писать. Достаточно прочитать и записать в теневой буфер всю страницу, а потом сверху в буфер дописать изменяемые данные: volatile uint32_t* pTmp = (uint32_t*)((uint32_t)&Config_flash & ~0x7F); uint32_t* pSegmentEnd = (uint32_t*)(((uint32_t)&Config_flash & ~0x7F) + 128); while(pTmp < pSegmentEnd) // copy to shadow buffer { uint32_t Data = *pTmp; *pTmp++ = Data; } uint32_t *pSrc = (uint32_t*)&TmpConfig; uint32_t *pDst = (uint32_t*)&Config_flash; while(pDst < (uint32_t*)((config_t*)&Config_flash + 1)) { *pDst++ = *pSrc++; } Flash::RewritePage((uint32_t const*)&Config_flash); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_dem 0 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба сколько же у вас памяти жрет проект, если вы пишете на CPP ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба сколько же у вас памяти жрет проект, если вы пишете на CPP ? Примерно столько же. А удобства неравненно больше. Обсуждалось неоднократно, хотя бы тут. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Waso 1 25 октября, 2007 Опубликовано 25 октября, 2007 · Жалоба 2 Сергей Борщ. Смысл понятен, но реализация в примере темновата. volatile uint32_t* pTmp = (uint32_t*)((uint32_t)&Config_flash & ~0x7F); uint32_t* pSegmentEnd = (uint32_t*)(((uint32_t)&Config_flash & ~0x7F) + 128); while(pTmp < pSegmentEnd) // copy to shadow buffer { uint32_t Data = *pTmp; *pTmp++ = Data; }Разве ~0x7F не равно 0x80 ? Каков смысл такой записи как у Вас? Тело цикла while тоже кажется избыточным моему неопытному глазу: Сначала присваиваем переменной Data то, на что указывает pTmp, затем, если я правильно понимаю работу постинкремента, сначала присваиваем тому на что указывает pTmp значение Data и после этого увеличиваем сам адрес указателя. Зачем кидать туда-сюда значение *pTmp ?? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 25 октября, 2007 Опубликовано 25 октября, 2007 · Жалоба Разве ~0x7F не равно 0x80 ? Каков смысл такой записи как у Вас?Нет, не равно. ~0x7F для ARM равно 0xFFFFFF80. Вот и вы попались. Вообще-то совсем правильно было бы ~0x7FULL, тогда такая запись обнуляла бы 5 младших бит в любой целочисленной переменной. Но я пока не выработал в себе такую привычку, наверное пора начинать. Зачем кидать туда-сюда значение *pTmp ?Tmp объявлен как volatile *. Без временной переменной получили бы warning компилятора о непредсказуемом порядке доступа к volatile (IAR выдает его всегда, если в выражении встречается более одной volatile-переменной). Без volatile компилятор имел бы полное право выкинуть весь цикл. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Angle 0 21 ноября, 2007 Опубликовано 21 ноября, 2007 · Жалоба У меня такая проблема не могу записать во внутреннюю флэш. Контроллер AT91SAM7A3, компилятор Keil. В настройках проекта Оptions->Target ограничил размер ROM с 0x40000 до 0x30000 Кусок кода void EFC_Init(void) { unsigned long clkus; // Calculate Flash Microsecond Cycle Number - Approximate (no Library Code) //clkus = (1074*(clk >> 10)) >> 20; // Master Clock Cycles in 1.0us clkus = (1611*(MCK >> 10)) >> 20; // Master Clock Cycles in 1.5us // Set Flash Microsecond Cycle Number // Set Flash Waite State to max. (Single Cycle Access at Up to 30 MHz) AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN) & (clkus << 16)) | AT91C_MC_FWS_3FWS; AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS; } int EFC_WritePage(DWORD adr, DWORD *pbuf) { unsigned int *pflash; unsigned int page; unsigned int i; pflash = (unsigned int *)adr; page = (adr - 0x00100000)/AT91C_IFLASH_PAGE_SIZE; AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_UNLOCK |AT91C_MC_PAGEN & (page << 8)); // Wait until the end of Command while ((AT91C_BASE_MC->MC_FSR & AT91C_MC_EOL) != AT91C_MC_EOL); for (i = 0; i <AT91C_IFLASH_PAGE_SIZE/4; i++) *(pflash + i ) = *(pbuf + i); AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_START_PROG |(AT91C_MC_PAGEN & (page << 8)); // Wait until the end of Command while ((AT91C_BASE_MC->MC_FSR & AT91C_MC_EOP) != AT91C_MC_EOP); // Check for Errors if (AT91C_BASE_MC->MC_FSR & (AT91C_MC_PROGE | AT91C_MC_LOCKE)) return (1); return (0); } #define TestAddr AT91C_IFLASH+AT91C_IFLASH_SIZE-AT91C_IFLASH_PAGE_SIZE BYTE TestEFC(void) { DWORD buf1[256]; int i; BYTE result; for(i=1;i<=63;i++) buf1[i]=i; EFC_Init(); result=(BYTE)EFC_WritePage((DWORD)TestAddr,(DWORD*)buf1); return result; } Прогамма зависает после выполнения строки кода while ((AT91C_BASE_MC->MC_FSR & AT91C_MC_EOL) != AT91C_MC_EOL); В чем может быть причина ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 21 ноября, 2007 Опубликовано 21 ноября, 2007 · Жалоба Прогамма зависает после выполнения строки кода while ((AT91C_BASE_MC->MC_FSR & AT91C_MC_EOL) != AT91C_MC_EOL); В чем может быть причина ? Кусочек, пишущий в FCR и ожидающий после этого готовности FSR должен исполняться из ОЗУ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться