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

 
 
> bootloader, возникает исключительная ситуация
dimka76
сообщение Jul 21 2009, 08:37
Сообщение #1


developer
****

Группа: Свой
Сообщений: 902
Регистрация: 12-04-06
Из: Казань
Пользователь №: 16 032



Пишу bootloader.
Контроллер AT91SAM7S64.
Компилятор IAR.
Вот код самой процедуры самопрограммирования

Код
void flash_init (void)
{
    *AT91C_MC_FMR = ((AT91C_MC_FMCN)&(72 <<16)) | AT91C_MC_FWS_1FWS;
}


void flash_write(unsigned int page, unsigned int* flash_buf)
{
    unsigned int* flash;
    unsigned int i;

        *AT91C_MC_FCR = (0x5A<<24) | (page<<8 & AT91C_MC_PAGEN) | AT91C_MC_FCMD_UNLOCK;    //Unlock Region
        while((*AT91C_MC_FSR & AT91C_MC_FRDY) != AT91C_MC_FRDY );

    flash = (unsigned int *) 0x00100000 + 4*page*FLASH_PAGE_SIZE_WORDS;
    
    for(i=0; i < FLASH_PAGE_SIZE_WORDS; i++) flash[i] = flash_buf[i];
    __disable_interrupt();
    *AT91C_MC_FCR = (0x5A<<24) | (page<<8 & AT91C_MC_PAGEN) | AT91C_MC_FCMD_START_PROG; // | (1 << 8); //0x5A000001; //
    while((*AT91C_MC_FSR & AT91C_MC_FRDY) == 0);
        while((*AT91C_MC_FSR & AT91C_MC_FRDY) != AT91C_MC_FRDY );
        __enable_interrupt();
}


Где-то внутри функции flash_write(...) вылетает в Prefetch Abort.
Точное место определить не могу, т.е. при использовании JTAG и прохождении программы по шагам все работает нормально.


Подскажите пожалуйста в чем может быть причина.


--------------------
Все может быть и быть все может, и лишь того не может быть-чего уж точно быть не может, хотя..и это может быть.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 7)
Сергей Борщ
сообщение Jul 21 2009, 09:11
Сообщение #2


Гуру
******

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



Цитата
Код
        *AT91C_MC_FCR = (0x5A<<24) | (page<<8 & AT91C_MC_PAGEN) | AT91C_MC_FCMD_UNLOCK;    //Unlock Region
        while((*AT91C_MC_FSR & AT91C_MC_FRDY) != AT91C_MC_FRDY );
При записи в MC_FCR и ожидании MC_FRDY код должен исполняться из ОЗУ:
Код
flash.h:
#ifndef FLASH_H__
#define FLASH_H__
#include <at91SAM7s64.h>

#define    MCK_CYCLES ((15ULL * MCK + 5000000) / 10000000)
#if MCK > 30000000
#define WAITSTATES  AT91C_MC_FWS_1FWS
#else
#define WAITSTATES  AT91C_MC_FWS_0FWS
#endif

extern __arm void FlashCommand(uint32_t command, uint32_t mode);
inline void Flash_ErasePage(uint32_t const *addr)
{
    FlashCommand( (0x5AULL *  AT91C_MC_KEY / 0xFF) | (((uint32_t)addr >> 7) << 8) | AT91C_MC_FCMD_START_PROG,
                (0 * AT91C_MC_FRDY) | (0 * AT91C_MC_LOCKE) | ( 0 * AT91C_MC_PROGE) |
                (0 * AT91C_MC_NEBP) | (WAITSTATES) | (MCK_CYCLES * AT91C_MC_FMCN / 0xFF));
}
inline void Flash_ProgramPage(uint32_t const *addr)
{
    FlashCommand( (0x5AULL *  AT91C_MC_KEY / 0xFF) | (((uint32_t)addr >> 7) << 8) | AT91C_MC_FCMD_START_PROG,
                (0 * AT91C_MC_FRDY) | (0 * AT91C_MC_LOCKE) | ( 0 * AT91C_MC_PROGE) |
                (1 * AT91C_MC_NEBP) | (WAITSTATES) | (MCK_CYCLES * AT91C_MC_FMCN / 0xFF));
}
#endif  // FLASH_H__

flash.cpp:
#include <at91SAM7s64.h>
#include "Flash.h"
__ramfunc __arm void FlashCommand_RAM(uint32_t command)
{
    AT91C_BASE_MC->MC_FCR = command;
    while(!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY));
}

__arm void FlashCommand(uint32_t command, uint32_t mode)
{
    __disable_interrupt();
    AT91C_BASE_MC->MC_FMR = mode;
    FlashCommand_RAM(command);
    __enable_interrupt();
}


--------------------
На любой вопрос даю любой ответ
"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
dimka76
сообщение Jul 21 2009, 09:33
Сообщение #3


developer
****

Группа: Свой
Сообщений: 902
Регистрация: 12-04-06
Из: Казань
Пользователь №: 16 032



Цитата(Сергей Борщ @ Jul 21 2009, 13:11) *
При записи в MC_FCR и ожидании MC_FRDY код должен исполняться из ОЗУ


Спасибо. Помогло.

А обязательно в режиме ARM ?
Нельзя ли в режиме THUMB ?


--------------------
Все может быть и быть все может, и лишь того не может быть-чего уж точно быть не может, хотя..и это может быть.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 21 2009, 10:12
Сообщение #4


Гуру
******

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



Цитата(dimka76 @ Jul 21 2009, 12:33) *
А обязательно в режиме ARM ?
Нельзя ли в режиме THUMB ?
Можно, но в ARM этот код получается короче.


--------------------
На любой вопрос даю любой ответ
"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
dimka76
сообщение Jul 21 2009, 10:18
Сообщение #5


developer
****

Группа: Свой
Сообщений: 902
Регистрация: 12-04-06
Из: Казань
Пользователь №: 16 032



Цитата(Сергей Борщ @ Jul 21 2009, 14:12) *
Можно, но в ARM этот код получается короче.


какой ЭТОТ ?

У меня в THUMB режиме почти в два раза меньше код во FLASH, в RAM такой же.
я не стал использовать ваш код просто учел ваши рекомендации в своем.

И еще вопросик.

откуда эта формула?
Код
#define    MCK_CYCLES ((15ULL * MCK + 5000000) / 10000000)


--------------------
Все может быть и быть все может, и лишь того не может быть-чего уж точно быть не может, хотя..и это может быть.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 21 2009, 11:22
Сообщение #6


Гуру
******

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



Цитата(dimka76 @ Jul 21 2009, 13:18) *
какой ЭТОТ ?
Код
    __disable_interrupt();

    __enable_interrupt();
Из THUMB нет доступа к регистру CPSR, поэтому для разрешения/запрещения прерываний придется переключаться в ARM. А между ними - опять в THUMB. Делая код чуть длинее за счет ARM-команд экономим место и время на выкидывании переключения в THUMB между ними. Мне так казалось. Давно это писалось.
Цитата(dimka76 @ Jul 21 2009, 13:18) *
откуда эта формула?
Код
#define    MCK_CYCLES ((15ULL * MCK + 5000000) / 10000000)
Из головы. Количество тактов в полутора микросекундах с округлением.
И наверное красивее было бы заменить
Код
#if MCK > 30000000
#define WAITSTATES  AT91C_MC_FWS_1FWS
#else
#define WAITSTATES  AT91C_MC_FWS_0FWS
#endif
на
Код
#define WAITSTATES  ((MCK) > 30000000 ? AT91C_MC_FWS_1FWS : AT91C_MC_FWS_0FWS)


--------------------
На любой вопрос даю любой ответ
"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
dimka76
сообщение Jul 21 2009, 11:54
Сообщение #7


developer
****

Группа: Свой
Сообщений: 902
Регистрация: 12-04-06
Из: Казань
Пользователь №: 16 032



Цитата(Сергей Борщ @ Jul 21 2009, 15:22) *
Код
    __disable_interrupt();

    __enable_interrupt();
Из THUMB нет доступа к регистру CPSR, поэтому для разрешения/запрещения прерываний придется переключаться в ARM. А между ними - опять в THUMB.


Я то подумал, что речь идет обо всей программе.
А это же лишь небольшой процент от всей программы.
А я имел весь бутлоадер в тумбе делать. А в указанном вами фрагменте пусть себе переключается. Потеря в объеме программы несущественная.
А вот если весь бутлоадер делать в АРМ режиме, то и размер почти в два раза возрастает. А это на мой взгляд расточительство для бутлоадера. Проигрыш в производительности значения не имеет.

Цитата
Количество тактов в полутора микросекундах с округлением.


почему в полуторах, ведь в datasheet написано

Цитата
FMCN:Flash Microsecond Cycle Number
This field defines the number of Master Clock cycles in 1 microsecond.


В одной микросекунде получается.


--------------------
Все может быть и быть все может, и лишь того не может быть-чего уж точно быть не может, хотя..и это может быть.
Go to the top of the page
 
+Quote Post
Dron_Gus
сообщение Jul 21 2009, 11:58
Сообщение #8


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

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



• 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.


--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 04:05
Рейтинг@Mail.ru


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