реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> работа с внутренней флэш, AT91SAM7X256
Annuta
сообщение Jul 6 2007, 11:16
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 42
Регистрация: 26-04-07
Из: Смоленск
Пользователь №: 27 333



Привет! У меня плата на AT91SAM7x256 - первый раз в жизни пытаюсь работать с внутреней флэш ... 07.gif
вот пишу что-то в память
Код
__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.gif ... и в xcl написано
"Read-Only" ...это значит что я могу только читать -- что надо прописать чтоб можно было и писать ?
Спасибо!

Сообщение отредактировал Annuta - Jul 6 2007, 11:21


--------------------
Из комбинации лени и логики - получается программист! /народная мудрость/
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jul 6 2007, 13:40
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Цитата(Annuta @ Jul 6 2007, 17:16) *


По собственному опыту не советую использовать внутреннюю флэш. При записи очень часто возникал глюк: страница стирается, а записывать не записывается. При проверке выяснилось что бит готовности не всегда вставал в положение "флэш занята". Лучше всего использовать внешнюю spi-ную например.

А по теме: что передаете в эту функцию EFCWrite(u32 adr, u8 *pbuf, u32 Len, u32 NeedReset)? Чему равна переменная EFC_PAGE_SIZE?

Сообщение отредактировал Timofey - Jul 6 2007, 13:45
Go to the top of the page
 
+Quote Post
IV_K
сообщение Jul 6 2007, 16:04
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 121
Регистрация: 17-06-05
Пользователь №: 6 087



в xcl из области ROM исключите страницы, которые пользуете при сохранении данных, чтоб линкер программу туда не пихал, скорее всего затираете нужный кусок кода, а так с внктренней влеш в самах вроде все нормально, я ни разу с глюками не сталкивался..
при записи запретите все прерывания! то что в комментах в xcl написано это ерунда.. страницы можно писать
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jul 7 2007, 06:19
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Цитата(IV_K @ Jul 6 2007, 22:04) *
в xcl из области ROM исключите страницы, которые пользуете при сохранении данных, чтоб линкер программу туда не пихал, скорее всего затираете нужный кусок кода, а так с внктренней влеш в самах вроде все нормально, я ни разу с глюками не сталкивался..
при записи запретите все прерывания! то что в комментах в xcl написано это ерунда.. страницы можно писать


Увы, но факт, есть факт. Когда устройство лежало у меня на столе, у меня тоже все было впорядке. Ни единого глюка. Но когда спустили десять таких устройств в шахту. Там то они и появились. Хотя дело выбора smile.gif . А так я тоже брал эту программу с форума этого. Зная конечный размер программы, я в xcl файле (как вы и советуете) ограничилч объем памяти (хотя было видно и без ограничения, что линкер туда программу не пихал, но это не важно). Потом долго разбирался: на столе нормально, в шахте - глюк. Пока с ноутом не залез в шахту, не подключился и не увидел лично.

Сообщение отредактировал Timofey - Jul 7 2007, 06:19
Go to the top of the page
 
+Quote Post
Annuta
сообщение Jul 9 2007, 05:27
Сообщение #5


Участник
*

Группа: Новичок
Сообщений: 42
Регистрация: 26-04-07
Из: Смоленск
Пользователь №: 27 333



Моя переменная
#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)

Чего он ругается !????

Сообщение отредактировал Annuta - Jul 9 2007, 05:28


--------------------
Из комбинации лени и логики - получается программист! /народная мудрость/
Go to the top of the page
 
+Quote Post
AlexBoy
сообщение Jul 9 2007, 09:30
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 205
Регистрация: 19-12-05
Из: Kiev
Пользователь №: 12 394



Цитата(Annuta @ Jul 9 2007, 08:27) *
Моя переменная
#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;
  }
Go to the top of the page
 
+Quote Post
Dron_Gus
сообщение Jul 9 2007, 09:34
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 9-01-05
Из: Санкт-Петербург
Пользователь №: 1 861



Цитата(Annuta @ Jul 9 2007, 09:27) *
Код
//*************************************************************************
// 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 Кб. А стек обычно лежит в конце РАМы, а теперь там неопределенная память... Надеюсь понятно выразил. smile.gif



Вот кусов моего бутлоадера под 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, особенно задержки.


--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jul 9 2007, 09:59
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Цитата(Annuta @ Jul 9 2007, 11:27) *
Моя переменная
#define EFC_PAGE_SIZE 128

Размер страницы что у SAM7X128 что у SAM7X256 равен 256 байт (согласно даташиту)
Цитата(Annuta @ Jul 9 2007, 11:27) *
При попытке поменять в 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;

Сообщение отредактировал Timofey - Jul 9 2007, 10:11
Go to the top of the page
 
+Quote Post
Annuta
сообщение Jul 9 2007, 13:42
Сообщение #9


Участник
*

Группа: Новичок
Сообщений: 42
Регистрация: 26-04-07
Из: Смоленск
Пользователь №: 27 333



Спасибо!! Вроде пишет - не могу провериить -- так как не работает чтение .... wacko.gif
вот функция
Код
__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;
}

// вот массив пусто!
помогите уж до конца разобраться...


--------------------
Из комбинации лени и логики - получается программист! /народная мудрость/
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jul 9 2007, 16:07
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Код
__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 передавайте тот же начальный адрес который указывали для записи.
Go to the top of the page
 
+Quote Post
Annuta
сообщение Jul 11 2007, 11:37
Сообщение #11


Участник
*

Группа: Новичок
Сообщений: 42
Регистрация: 26-04-07
Из: Смоленск
Пользователь №: 27 333



Происходят странные вещи!.. моя прога на этой строке сбрасывается... перегружается...
AT91C_BASE_MC->MC_FCR = (0x5A << 24) | AT91C_MC_FCMD_ERASE_ALL;
Это я пытаюсь сделть очистку....
как правильно - очистку сделать!... стереть стр?
и ещё где можно скачать - самы простой - работающий проект для работы с внутренней флэш... демку какую-нить... ?

Сообщение отредактировал Annuta - Jul 11 2007, 11:38


--------------------
Из комбинации лени и логики - получается программист! /народная мудрость/
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jul 12 2007, 08:27
Сообщение #12


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Цитата(Annuta @ Jul 11 2007, 17:37) *
Происходят странные вещи!.. моя прога на этой строке сбрасывается... перегружается...
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."
Цитата(Annuta @ Jul 11 2007, 17:37) *
и ещё где можно скачать - самы простой - работающий проект для работы с внутренней флэш... демку какую-нить... ?

Программа, которую выложили вначале, вполне работоспособная. Я для SAM7S64 пишу нормально. И считываю данные тоже. Просто сделайте все заново, учитывая коментарии.
Go to the top of the page
 
+Quote Post
Annuta
сообщение Jul 12 2007, 10:51
Сообщение #13


Участник
*

Группа: Новичок
Сообщений: 42
Регистрация: 26-04-07
Из: Смоленск
Пользователь №: 27 333



вот написала по вашему совету прогу сначала. Эх... ну не работает!. crying.gif .. Не пинайте ногами если - что упускаю... програмимирую первый раз в жизни микроконтроллер!...
вот мой код
Код
#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);
Она зажигает второй лед, потом плата перегружается... !... все огоньки гаснут /как будто жму кнопочку на плате ресет/ ...и она снова работает... только сначала!... Третий лед не зажигается...


--------------------
Из комбинации лени и логики - получается программист! /народная мудрость/
Go to the top of the page
 
+Quote Post
Dron_Gus
сообщение Jul 12 2007, 11:46
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 9-01-05
Из: Санкт-Петербург
Пользователь №: 1 861



Какой у Вас 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 чем использовать прямое значение.


--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 12 2007, 12:01
Сообщение #15


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Annuta @ Jul 12 2007, 13:51) *
Она зажигает второй лед, потом плата перегружается... !... все огоньки гаснут /как будто жму кнопочку на плате ресет/ ...и она снова работает... только сначала!... Третий лед не зажигается...
Я извиняюсь, три вопроса -
1) у вас Watchdog Timer остановлен? Если нет, возможно как раз в этот момент истекает его тайм-аут.
2) вы пользуетесь внутрисхемным отладчиком? Если да, то можно пошагово дойти до точки "падения" и узнать какое именно действие вызывает перезагрузку.
3)У вас стоят "заглушки" на исключениях Prefetch Abort, DataAbort, Undefined Instruction? Если нет - поставьте пустые циклы с какой-то индикацией, уже будет больше информации.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 14:19
Рейтинг@Mail.ru


Страница сгенерированна за 0.01537 секунд с 7
ELECTRONIX ©2004-2016