Annuta 0 6 июля, 2007 Опубликовано 6 июля, 2007 (изменено) · Жалоба Привет! У меня плата на AT91SAM7x256 - первый раз в жизни пытаюсь работать с внутреней флэш ... :07: вот пишу что-то в память __ramfunc u32 EFC_WritePage(u32 adr, u32 *pbuf) { unsigned int *pflash; unsigned int page; unsigned int region; unsigned int i; pflash = (unsigned int *)adr; page = (0x00310000)/EFC_PAGE_SIZE; region = (page/EFC_PagesInTheLockRegion); EFC_Init(); 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)); return 1; } __ramfunc void EFCWrite(u32 adr, u8 *pbuf, u32 Len, u32 NeedReset) { u32 l; l=0; while (l<Len) { EFC_WritePage(adr, (u32*)&(pbuf[l])); l+=EFC_PAGE_SIZE; adr+=EFC_PAGE_SIZE; } } и кусочек xcl файла //************************************************************************* // Read-only segments mapped to Flash 256K. //************************************************************************* -DROMSTART=00000040 -DROMEND=00030000 //************************************************************************* // Read/write segments mapped to RAM. //************************************************************************* -DRAMSTART=00200000 -DRAMEND=0020FFFF При попытке что-то записать из памяти стирается прошивка... то стириется то ли затирается - не мгу понять!... Хотя адреса не перекрещеваются... Не понимаю... ЧЕМ это вызвано! :smile3046: ... и в xcl написано "Read-Only" ...это значит что я могу только читать -- что надо прописать чтоб можно было и писать ? Спасибо! Изменено 6 июля, 2007 пользователем Annuta Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timofey_219 0 6 июля, 2007 Опубликовано 6 июля, 2007 (изменено) · Жалоба По собственному опыту не советую использовать внутреннюю флэш. При записи очень часто возникал глюк: страница стирается, а записывать не записывается. При проверке выяснилось что бит готовности не всегда вставал в положение "флэш занята". Лучше всего использовать внешнюю spi-ную например. А по теме: что передаете в эту функцию EFCWrite(u32 adr, u8 *pbuf, u32 Len, u32 NeedReset)? Чему равна переменная EFC_PAGE_SIZE? Изменено 6 июля, 2007 пользователем Timofey Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IV_K 0 6 июля, 2007 Опубликовано 6 июля, 2007 · Жалоба в xcl из области ROM исключите страницы, которые пользуете при сохранении данных, чтоб линкер программу туда не пихал, скорее всего затираете нужный кусок кода, а так с внктренней влеш в самах вроде все нормально, я ни разу с глюками не сталкивался.. при записи запретите все прерывания! то что в комментах в xcl написано это ерунда.. страницы можно писать Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timofey_219 0 7 июля, 2007 Опубликовано 7 июля, 2007 (изменено) · Жалоба в xcl из области ROM исключите страницы, которые пользуете при сохранении данных, чтоб линкер программу туда не пихал, скорее всего затираете нужный кусок кода, а так с внктренней влеш в самах вроде все нормально, я ни разу с глюками не сталкивался.. при записи запретите все прерывания! то что в комментах в xcl написано это ерунда.. страницы можно писать Увы, но факт, есть факт. Когда устройство лежало у меня на столе, у меня тоже все было впорядке. Ни единого глюка. Но когда спустили десять таких устройств в шахту. Там то они и появились. Хотя дело выбора :) . А так я тоже брал эту программу с форума этого. Зная конечный размер программы, я в xcl файле (как вы и советуете) ограничилч объем памяти (хотя было видно и без ограничения, что линкер туда программу не пихал, но это не важно). Потом долго разбирался: на столе нормально, в шахте - глюк. Пока с ноутом не залез в шахту, не подключился и не увидел лично. Изменено 7 июля, 2007 пользователем Timofey Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Annuta 0 9 июля, 2007 Опубликовано 9 июля, 2007 (изменено) · Жалоба Моя переменная #define EFC_PAGE_SIZE 128 Я просто не совсем может правильно чего понимаю, народ ? Но у меня ж никак не должна затираться прошивка данными... При попытке поменять в xcl файле адреса на такие /скопировала в аналогичной проге/ //************************************************************************* // Read-only segments mapped to Flash 256K. //************************************************************************* -DROMSTART=00000000 -DROMEND=0003FFFF //************************************************************************* // Read/write segments mapped to 64K RAM. //************************************************************************* -DRAMSTART=00000000 -DRAMEND=0000FFFF получаю ошибку... Fatal Error[e72]: Segment SVC_STACK must be defined in a segment definition option (-Z, -b or -P) Чего он ругается !???? Изменено 9 июля, 2007 пользователем Annuta Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexBoy 0 9 июля, 2007 Опубликовано 9 июля, 2007 · Жалоба Моя переменная #define EFC_PAGE_SIZE 128 Странно, у меня другой размер страницы именно для X256. #define AT91C_IFLASH_PAGE_SIZE ((unsigned int) 256) учтите что вы пишете по 4 байта, так что делите еще на 4. А функция записи страницы такая: // Write in one Flash page located in AT91C_IFLASH BOOL AT91F_Flash_Write(int page, DWORD *buff) { unsigned int i; DWORD *flash; // init flash pointer flash = (DWORD *)AT91C_IFLASH; // copy the new value i = (AT91C_IFLASH_PAGE_SIZE>>2); do { *flash++ = *buff++; } while(--i); // Write the write page command AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_START_PROG | (AT91C_MC_PAGEN & (page << 8)); // Wait the end of command AT91F_Flash_Ready(); // Check the result if ((AT91C_BASE_MC->MC_FSR & (AT91C_MC_PROGE | AT91C_MC_LOCKE)) != 0) return FALSE; return TRUE; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dron_Gus 2 9 июля, 2007 Опубликовано 9 июля, 2007 · Жалоба //************************************************************************* // Read-only segments mapped to Flash 256K. //************************************************************************* -DROMSTART=00000000 -DROMEND=0003FFFF //************************************************************************* // Read/write segments mapped to 64K RAM. //************************************************************************* -DRAMSTART=00000000 -DRAMEND=0000FFFF получаю ошибку... Fatal Error[e72]: Segment SVC_STACK must be defined in a segment definition option (-Z, -b or -P) Чего он ругается !???? Ругается т.к. Вы ему РАМ урезали до 64 Кб. А стек обычно лежит в конце РАМы, а теперь там неопределенная память... Надеюсь понятно выразил. :) Вот кусов моего бутлоадера под at91sam7x256 может поможет /* ******************************************************************************** ************************* * AT91_PageWrite ******************************************************************************** ************************* * Writers len page to flash * Addr - start sector num * pBuff - data to write * len - page count to write * Return: * >0 - bytes flashed * -1 - outside flash adr. ******************************************************************************** ************************* */ __ramfunc int AT91_PageWrite(unsigned int Addr, const char *pBuff, unsigned int len) { unsigned int *pSource; unsigned int *pDest; unsigned int i; unsigned int Page; pSource = (unsigned int*) pBuff; pDest = (unsigned int*) (AT91C_IFLASH_PAGE_SIZE * Addr + AT91C_IFLASH); Page = Addr; while (Page < Addr + len) { i = 0; while (i < AT91C_IFLASH_PAGE_SIZE) { *pDest = *pSource; pDest++; pSource++; i += 4; } AT91C_BASE_MC->MC_FCR |= AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_START_PROG | ((Page << 8) & AT91C_MC_PAGEN); while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY)); Page++; } return (len * AT91C_IFLASH_PAGE_SIZE); } /* ******************************************************************************** ************************* * flash init ******************************************************************************** ************************* */ void AT91_FlashInit() { AT91C_BASE_MC->MC_FMR = (((MCK*2/1000000)<< 16) & AT91C_MC_FMCN) | AT91C_MC_FWS_1FWS; AT91C_BASE_MC->MC_FMR = ((100 <<16)&(AT91C_MC_FMCN)) | AT91C_MC_FWS_1FWS; while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY)); } Тут главное правильно проинициализировать регистры MC, особенно задержки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timofey_219 0 9 июля, 2007 Опубликовано 9 июля, 2007 (изменено) · Жалоба Моя переменная #define EFC_PAGE_SIZE 128 Размер страницы что у SAM7X128 что у SAM7X256 равен 256 байт (согласно даташиту) При попытке поменять в xcl файле адреса на такие /скопировала в аналогичной проге/ верните прежние значения, просто смотрите куда вы пишете, то есть какой начальный адрес вы передаете в функцию void EFCWrite(u32 adr, u8 *pbuf, u32 Len, u32 NeedReset) Если вы передадите туда допустим адрес 0х00001000 а размер программы у вас более 4 кб, то собственно все что свыше этих 4 кб будет затерто вашими данными ... Поэтому просто ограничиваете размер флэшки в xlc файле (как тут советовали) и пишете в ту область. Допустим пишете тут -DROMSTART=00000000 -DROMEND=0002FFFF (размер программы при этом не может быть более 196607 байт) и уже в функцию записи передаете адрес 00030000. И еще: вместо page = (0x00310000)/EFC_PAGE_SIZE; напишите page = (adr & 0x3FFFF)/EFC_PAGE_SIZE; Изменено 9 июля, 2007 пользователем Timofey Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Annuta 0 9 июля, 2007 Опубликовано 9 июля, 2007 · Жалоба Спасибо!! Вроде пишет - не могу провериить -- так как не работает чтение .... вот функция __ramfunc u32 EFC_ReadPage(u32 adr, u32 *pbuf) { unsigned int *pflash = (unsigned int *)(adr & 0x00000040); unsigned int i; EFC_Init(); for (i = 0; i < EFC_PAGE_SIZE_UINT; i++) *(pbuf + i) = *(pflash + i ); return 1; } // вот массив пусто! помогите уж до конца разобраться... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timofey_219 0 9 июля, 2007 Опубликовано 9 июля, 2007 · Жалоба __ramfunc u32 EFC_ReadPage(u32 adr, u32 *pbuf) { unsigned int *pflash = (unsigned int *) adr; unsigned int i; EFC_Init(); for (i = 0; i < EFC_PAGE_SIZE_UINT; i++) *(pbuf + i) = *(pflash + i ); return 1; } в переменную adr передавайте тот же начальный адрес который указывали для записи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Annuta 0 11 июля, 2007 Опубликовано 11 июля, 2007 (изменено) · Жалоба Происходят странные вещи!.. моя прога на этой строке сбрасывается... перегружается... AT91C_BASE_MC->MC_FCR = (0x5A << 24) | AT91C_MC_FCMD_ERASE_ALL; Это я пытаюсь сделть очистку.... как правильно - очистку сделать!... стереть стр? и ещё где можно скачать - самы простой - работающий проект для работы с внутренней флэш... демку какую-нить... ? Изменено 11 июля, 2007 пользователем Annuta Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timofey_219 0 12 июля, 2007 Опубликовано 12 июля, 2007 · Жалоба Происходят странные вещи!.. моя прога на этой строке сбрасывается... перегружается... AT91C_BASE_MC->MC_FCR = (0x5A << 24) | AT91C_MC_FCMD_ERASE_ALL; Это я пытаюсь сделть очистку.... как правильно - очистку сделать!... стереть стр? Это вы указываете стереть ВСЮ флэш память!! "Запускает процесс стирания всей реализованной на кристалле области флэш-памяти. Если защищена хотя бы одна страница с помощью бита защиты, то эта команда выполнена не будет." Если вы используете программу взятую с форума, то там есть строка в программе AT91C_BASE_MC->MC_FCR = (0x5A << 24) | (page << 8 ) | AT91C_MC_FCMD_START_PROG; вот она собственно и записывает "Команда программирования страницы (WP): Запускает процесс программирования одной страницы, номер которой указан в поле PAGEN." и ещё где можно скачать - самы простой - работающий проект для работы с внутренней флэш... демку какую-нить... ? Программа, которую выложили вначале, вполне работоспособная. Я для SAM7S64 пишу нормально. И считываю данные тоже. Просто сделайте все заново, учитывая коментарии. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Annuta 0 12 июля, 2007 Опубликовано 12 июля, 2007 · Жалоба вот написала по вашему совету прогу сначала. Эх... ну не работает!. :crying: .. Не пинайте ногами если - что упускаю... програмимирую первый раз в жизни микроконтроллер!... вот мой код #include <os_cpu.h> #define TestAddr 0x0030000 #define EFC_PAGE_SIZE 256 #define EFC_PAGE_COUNT 256 #define EFC_PagesInTheLockRegion 32 #define EFC_PAGE_SIZE_UINT (EFC_PAGE_SIZE/4) // #define u32 unsigned long #define u8 unsigned char #define DWORD unsigned long __ramfunc void EFC_Init(void) { while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY)); AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN)&(100 <<16)) | AT91C_MC_FWS_1FWS; while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY)); } __ramfunc u32 EFC_WritePage(u32 adr, u32 *pbuf) { unsigned int *pflash; unsigned int page; unsigned int region; unsigned int i; pflash = (unsigned int *)adr; page = (adr & 0x3FFFF)/EFC_PAGE_SIZE; region = (page/EFC_PagesInTheLockRegion); EFC_Init(); 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)); return 1; } __ramfunc void EFCWrite(u32 adr, u8 *pbuf, u32 Len, u32 NeedReset) { u32 l; if (NeedReset) { l=0; } l=0; while (l<Len) { EFC_WritePage(adr, (u32*)&(pbuf[l])); l+=EFC_PAGE_SIZE; adr+=EFC_PAGE_SIZE; } if (NeedReset) { __asm("sub r0, r0,r0;"); __asm("bx r0;"); } } __ramfunc u32 EFC_ReadPage(u32 adr, u32 *pbuf) { unsigned int *pflash = (unsigned int *)adr; unsigned int i; EFC_Init(); for (i = 0; i < EFC_PAGE_SIZE_UINT; i++) *(pbuf + i) = *(pflash + i ); return 1; } void TestEFC(void) { unsigned int buf1[8192/4]; int i; unsigned int *pbuf3=(unsigned int *)TestAddr; //AT91C_BASE_MC->MC_FCR = (0x5A << 24) | AT91C_MC_FCMD_ERASE_ALL; //while (!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY)); for(i=0;i<8192/4;i++) buf1[i]=i+9; OS_CPU_SR cpu_sr = 0; OS_ENTER_CRITICAL(); //Запретили прерывания EFCWrite( TestAddr ,(u8*)buf1,8192,0); OS_EXIT_CRITICAL(); //Разрешили прерывания for( i=0;i<8192/4;i++) if (buf1[i]!=pbuf3[i]) buf1[i]=0; } вот прога делает такой финт ушами... как только я вызываю функцию записи в основном цикле LED_On(2); TestEFC(); LED_On(3); Она зажигает второй лед, потом плата перегружается... !... все огоньки гаснут /как будто жму кнопочку на плате ресет/ ...и она снова работает... только сначала!... Третий лед не зажигается... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dron_Gus 2 12 июля, 2007 Опубликовано 12 июля, 2007 · Жалоба Какой у Вас MCK? Далее EFC_WritePage: зачем Вы вызываете EFC_Init() и тут же по-новой настраиваете MC другими значениями. При этом учтите: FMCN: Flash Microsecond Cycle Number Before writing Non Volatile Memory bits (Lock bits, General Purpose NVM bit and Security bits), this field must be set to the number of Master Clock cycles in one microsecond. When writing the rest of the Flash, this field defines the number of Master Clock cycles in 1.5 microseconds. This number must be rounded up. Для флеша должно быть в 1.5 раза больше. Проще выразить это через MCK чем использовать прямое значение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 12 июля, 2007 Опубликовано 12 июля, 2007 · Жалоба Она зажигает второй лед, потом плата перегружается... !... все огоньки гаснут /как будто жму кнопочку на плате ресет/ ...и она снова работает... только сначала!... Третий лед не зажигается...Я извиняюсь, три вопроса - 1) у вас Watchdog Timer остановлен? Если нет, возможно как раз в этот момент истекает его тайм-аут. 2) вы пользуетесь внутрисхемным отладчиком? Если да, то можно пошагово дойти до точки "падения" и узнать какое именно действие вызывает перезагрузку. 3)У вас стоят "заглушки" на исключениях Prefetch Abort, DataAbort, Undefined Instruction? Если нет - поставьте пустые циклы с какой-то индикацией, уже будет больше информации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться