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

 
 
> Внутренний flash для хранения пользовательских данных, как правильно?
athlon64
сообщение Jul 6 2010, 03:18
Сообщение #1


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

Группа: Свой
Сообщений: 156
Регистрация: 10-03-10
Из: Уфа
Пользователь №: 55 882



В процессоре at91sam7x512 нужно отдать последние 128Кб для хранения настроек устройства (конфигурационного файла).
Запись и чтение у меня сделано и работает, но начиная с определённого размера конфигурации, запись повреждает основную программу.
В icf-файле уменьшил адрес конца ROM __ICFEDIT_region_ROM_end__ со стандартных 0x17FFFF до 0x15FFFF, чтобы линкер не помещал программу выше 384Кб флеша. Но, видимо, этого недостаточно.
Как правильно настроить линкер?
Прикрепленные файлы
Прикрепленный файл  flash.zip ( 899 байт ) Кол-во скачиваний: 21
 


--------------------
Руслан
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
athlon64
сообщение Jul 6 2010, 08:04
Сообщение #2


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

Группа: Свой
Сообщений: 156
Регистрация: 10-03-10
Из: Уфа
Пользователь №: 55 882



Цитата(cornflyer @ Jul 6 2010, 13:37) *
во время работы с флешью надо запрещать все прерывания:
__disable_interrupt();
// flash read/write
__enable_interrupt();
причем надо еще добавить в startup.s:

irqHandler:
// spurious interrupts elimination
MRS r14, SPSR ; Abort if IRQ disabled
ANDS r14, r14, #I_BIT ; (IRQ_BIT = 1)
LDMNEFD sp!, {pc}^

на __disable_interrupt(); и __enable_interrupt(); IAR ругается
Я пробовал запрещать прерывания от TWI с помощью:
AT91C_BASE_TWI->TWI_IDR = 0xFFFFFFFF; и IRQ_DisbleIT(AT91C_ID_TWI);
не помогло.
Если не инициализировать TWI - запись и чтение происходят без ошибок. Причём с включенным TWI запись конфигурационного файла до 256 байт тоже проходит без ошибок, больше 256 - виснет и после резета виснет снова, т.е. как будто повреждена основная программа.

Вот код чтения:
Код
char EPR_Rd(unsigned int adr)
{
  return((char) *(pfirstPageData+adr));
}


Запись - функция реализующая запись в произвольное место произвольное кол-во байт:
Код
volatile unsigned int firstPageAddress;
volatile unsigned int *pfirstPageData;                 // Указатель на начало пользовательского блока во FLASH
unsigned int pFlashBuffer[AT91C_IFLASH_PAGE_SIZE / 4]; // Буфер записи страницы flash

void WriteBlokToFlash(unsigned int address_wr, char *data_array_p, unsigned char IndexStartWr, unsigned int CntByte_wr)
{
  unsigned int BytesSaved, i;
  unsigned char PageNoStart, AddrInPage, i_end;
  unsigned char array_idx=0;

  BytesSaved=0;                                             // Пока не записали ни одного байта конфигурации      
  
  while (BytesSaved!=CntByte_wr)                            // Сидим в цикле до тех пор пока всё запланированное не будет записано
  {
    PageNoStart = address_wr/64;                              // Номер страницы для записи
    AddrInPage  = address_wr%64;                              // Адрес внутри страницы  
    
    for (i=0;i<64;i++)
      pFlashBuffer[i] = *(pfirstPageData+(PageNoStart*64)+i); // Загоняем в буфер текущую страницу флеша
    
    if ((AddrInPage+CntByte_wr)>64)                         // Если блок не умещается в текущую страницу пишем до конца страницы (64*4байт)
      i_end=64;
    else                                                    // Если умещается - пишем до конца блока
      i_end = AddrInPage + CntByte_wr - BytesSaved;
    
    array_idx = IndexStartWr + BytesSaved;                  // Ставим указатель в массиве данных
    for (i=AddrInPage; i<i_end; i++)
    {
      pFlashBuffer[i]=*(data_array_p+(array_idx++));        // Вносим изменения в буфер записи
      BytesSaved++;
    }
    FLASHD_Write(firstPageAddress+(PageNoStart*AT91C_IFLASH_PAGE_SIZE), pFlashBuffer, AT91C_IFLASH_PAGE_SIZE);
    address_wr = address_wr + BytesSaved;                   // Увеличиваем адрес на кол-во записанных байт
  }      
}

Щас появилась мысль:
Конфигурация пишется пачками по 62 байта, обычно затык на 5 пакете, т.е. который попадает между 2х страниц, соответственно эта функция произведёт запись 2х страниц почти подряд. Возможно не хватает времени на запись первой страницы, как нужно писать уже вторую? Попробую сделать задержку. Но тогда не понятно почему с отключенным TWI запись и такой конфигурации проходит нормально


--------------------
Руслан
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- athlon64   Внутренний flash для хранения пользовательских данных   Jul 6 2010, 03:18
- - athlon64   Посмотрел map-файл, линкер действительно не помеща...   Jul 6 2010, 04:48
- - cornflyer   проверь содержимое Flash Mode Register: AT91C_BASE...   Jul 6 2010, 05:42
- - athlon64   Цитата(cornflyer @ Jul 6 2010, 11:42) про...   Jul 6 2010, 05:59
- - cornflyer   пропиши строчку: AT91C_BASE_MC->MC_FMR = ((AT91...   Jul 6 2010, 06:14
- - athlon64   Цитата(cornflyer @ Jul 6 2010, 12:14) про...   Jul 6 2010, 06:37
- - cornflyer   выкладывай код функций чтения/записи.... во время ...   Jul 6 2010, 07:37
|- - dimka76   Функция КодFLASHD_Write(firstPageAddress+...   Jul 7 2010, 07:05
- - cornflyer   добавь в main.c #include <intrinsics.h> тог...   Jul 6 2010, 08:14
- - athlon64   Цитата(cornflyer @ Jul 6 2010, 14:14) доб...   Jul 6 2010, 14:11
|- - defunct   Цитата(athlon64 @ Jul 6 2010, 17:11) Во в...   Jul 7 2010, 16:03
- - cornflyer   я к сожалению только сейчас получил возможность по...   Jul 7 2010, 06:37
- - athlon64   Цитата(dimka76 @ Jul 7 2010, 13:05) Функц...   Jul 7 2010, 07:18
- - athlon64   В общем разобрался в ситуации, дело было не в боби...   Jul 15 2010, 04:49


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

 


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


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