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

 
 
> Проблемы при работе со встроенной flash, AT91SAM7A3, bootloader
Costa
сообщение Feb 4 2009, 17:34
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 24-12-08
Пользователь №: 42 726



Здравствуйте!

Делаю загрузчик (bootloader) для AT91SAM7A3, одной из функций которого должно быть обновление (через USART, но это не суть) собственной прошивки. Все получается, из под JTAG, т.е. когда код загрузчика расположен и исполняется в RAM, все замечательно работает.
Проблема возникает, когда этот же код зашивается во flash. Когда дело доходит собственно до работы с flash (lock/unlock, write page), программа зависает, а поскольку в устройстве есть внешний watchdog, происходит reset.

Сделал маленькую функцию, которая блокирует (lock) регион 0 flash:
Код
__ramfunc void Lock(void)
{
    unsigned int interrupt_mask;
    unsigned int flash_status;
    unsigned short lock_status = *AT91C_MC_FSR >> 16;
    if (lock_status & 0x1)
        return;
  *AT91C_MC_FMR = FMCN_FOR_LOCK | AT91C_MC_FWS_1FWS;
    interrupt_mask = *AT91C_AIC_IMR;
  *AT91C_AIC_IDCR = AT91C_ALL_INT;
  *AT91C_MC_FCR = AT91C_MC_KEY | AT91C_MC_FCMD_LOCK;
  do
  {
    flash_status = *AT91C_MC_FSR & AT91C_MC_EOL;
  }
  while (!flash_status);
  *AT91C_AIC_IECR = interrupt_mask;
}

Штука в том, что собственно lock происходит, т.к. после reset функция выскакивает по первому return; - но вот если регион в состоянии unlock, то все стопорится в цикле do while. Причем пробовал тупо вставлять счетчик в тело цикла, чтобы по его окончании выходить из цикла - все равно виснет...
Уже весь мозг сломал и не знаю, в какую сторону рыть. То ли проблема в том, что как-то некорректно выключаются прерывания на время операций с flash, т.к. хотя сами обработчики прерываний и сделаны __ramfunc, но есть еще вектора прерываний, обертка... То ли вышеприведенный код не попадает на самом деле в RAM, хотя в стартапе __segment_init прописан, и соотв. библиотека к проекту подключена... Помогите разобраться, где накосячил.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
aaarrr
сообщение Feb 4 2009, 18:12
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Для начала убедитесь, что код действительно в RAM - проверьте map-файл. Прерывания я бы запрещал на уровне ядра, а не AIC'а.
Go to the top of the page
 
+Quote Post
Costa
сообщение Feb 5 2009, 06:44
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 24-12-08
Пользователь №: 42 726



Цитата(aaarrr @ Feb 4 2009, 21:12) *
Для начала убедитесь, что код действительно в RAM - проверьте map-файл. Прерывания я бы запрещал на уровне ядра, а не AIC'а.

Вот вырезки из map-файла:

Код
#                            (-carm -Z(CONST)INTRAMSTART_REMAP=00200000        #
#                            -Z(CONST)INTRAMEND_REMAP=00207FFF                 #
#                            -DROMSTART=00000000 -DROMEND=00004000             #
#                            -DRAMSTART=00200000 -DRAMEND=00207FFF             #
#                            -Z(CODE)INTVEC=00-3F                              #
#                            -Z(CODE)ICODE,DIFUNCT=ROMSTART-ROMEND             #
#                            -Z(CODE)SWITAB=ROMSTART-ROMEND                    #
#                            -Z(CODE)CODE=ROMSTART-ROMEND                      #
#                            -Z(CONST)INITTAB,DATA_ID,DATA_C=ROMSTART-ROMEND   #
#                            -Z(CONST)CHECKSUM=ROMSTART-ROMEND                 #
#                            -Z(DATA)DATA_I,DATA_Z,DATA_N=RAMSTART-RAMEND      #
#                            -Z(DATA)CODE_I=RAMSTART-RAMEND                    #
#                            -Z(CONST)CODE_ID=ROMSTART-ROMEND                  #
#                            -QCODE_I=CODE_ID -D_CSTACK_SIZE=(100*10)          #
#                            -D_IRQ_STACK_SIZE=(3*8*4)                         #
#                            -Z(DATA)CSTACK+_CSTACK_SIZE=RAMSTART-RAMEND       #
#                            -Z(DATA)IRQ_STACK+_IRQ_STACK_SIZE=RAMSTART-RAMEND) #

...

                ****************************************
                *                                      *
                *            RUNTIME MODEL             *
                *                                      *
                ****************************************

  ARMv4M       = USED
  ARMv4T       = USED
  StackAlign4  = USED
  __cpu_mode   = __pcs__interwork
  __data_model = absolute
  __endian     = little
  __rt_version = 6



                ****************************************
                *                                      *
                *              MODULE MAP              *
                *                                      *
                ****************************************


  DEFINED ABSOLUTE ENTRIES
  PROGRAM MODULE, NAME : ?ABS_ENTRY_MOD

Absolute parts
           ENTRY                   ADDRESS         REF BY
           =====                   =======         ======
           _IRQ_STACK_SIZE         00000060
           _CSTACK_SIZE            00001000
           RAMEND                  00207FFF
           RAMSTART                00200000
           ROMEND                  00004000
           ROMSTART                00000000
    *************************************************************************

...

    -------------------------------------------------------------------------
CODE_I
  Relative segment, address: 002001C8 - 0020022B (0x64 bytes), align: 2
  Segment part 87.
           ENTRY                   ADDRESS         REF BY
           =====                   =======         ======
           Lock                    002001C8        Protect_Emb_Flash (flash)
    -------------------------------------------------------------------------

...

    -------------------------------------------------------------------------
CODE_ID
  Relative segment, address: 00002790 - 000027F3 (0x64 bytes), align: 2
  Segment part 110.           Intra module refs:   Lock
    -------------------------------------------------------------------------

Могу ли я быть уверенным, что код Lock() исполняется действительно из RAM? Существует ли какой-то способ прямо из тела функции проверить, из какой области памяти исполняется код?
Второй совет, насчет запрета прерываний на уровне ядра, обязательно попробую.
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 1st August 2025 - 00:26
Рейтинг@Mail.ru


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