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

 
 
> Чтение boot-области из приложения
Огурцов
сообщение Sep 8 2008, 18:17
Сообщение #1


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



Вообще, чтение запрещено лок-битами, но нужно прочитать несколько байт, например, версию и тип бутлоадера.
Как это лучше сделать ? Конечно, бутлоадер возможно доработать. М.б. кто линки встречал на нечто подобное ?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Боинг749
сообщение Sep 9 2008, 06:53
Сообщение #2


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

Группа: Новичок
Сообщений: 83
Регистрация: 25-08-08
Пользователь №: 39 801



Цитата(aaarrr @ Sep 9 2008, 03:17) *
Может лучше я вам перескажу? Речь в нем идет только о чтении по команде LPM, никаких ограничений на вызов кода загрузчика из приложения нет.
Вчитайте-ка в себя мануал.

Ой 05.gif
И правда.
Прошу меня простить. Перепутал с блокировкой RWW секции FLASH после команды записи в RWW. Когда если не разрешить доступ к RWW процессор вместо команд из RWW будет читать $FFFF.

Ещё раз прошу извинить.
Go to the top of the page
 
+Quote Post
Огурцов
сообщение Sep 9 2008, 07:26
Сообщение #3


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



С использованием таблицы векторов прерываний идея понравилась.
Может быть и возможности компилятора (WinAVR/GCC) использовать по инициализации таблицы векторов ?
Типа:
Код
ISR(SIG_####)
{
  asm
  {
    pop
    pop
    jmp Get_version
  }
}

Правда, со стеком придется поизвращаться.
Или есть более прямой путь объяснить компилятору, чтобы он проинициализровал определенный вектор адресом произвольной функции ?

Сообщение отредактировал Огурцов - Sep 9 2008, 07:27
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 9 2008, 07:40
Сообщение #4


Гуру
******

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



Цитата(Огурцов @ Sep 9 2008, 10:26) *
Или есть более прямой путь объяснить компилятору, чтобы он проинициализровал определенный вектор адресом произвольной функции ?
Написать ее на ассемблере. Или написать обычную функцию uint16_t GetSerial() { return 0xffff; } и на ассемблере поставить JMP на нее в нужный вектор. Или поместить эту функцию в отдельную секцию, а секцию разместить по известному адресу, не обязательно на вектора, можно и в конце загрузчика. Я делаю именно так. Ну если хочется на вектора, то вот так:
Код
#define VERSION  12345

ISR(SIG_####, ISR_NAKED)
{
    asm volatile ("\n\t"
    "LDI r24, %A0 \n\t"
    "LDI r25, %B0 \n\t"
    "RET \n\t"
    :
    :"i" ((uint16_t)VERSION)
    :r23,r24
    )
}
Но я бы к векторам не пристраивался - мало ли потом переделаете загрузчик и вектора понадобятся. Обычные функции гибче:
Код
uint16_t GetVersion() __attribute__((section(".get_version")));
uint16_t GetVersion() { return VERSION; }
или так:

int16_t GetVersion() __attribute__((section(".get_version")));
uint16_t GetVersion()
{
    uint16_t Version;
    asm volatile ("\n\t"
    "LDI %A0, %A1 \n\t"
    "LDI %B0, %B1 \n\t"
    "RET \n\t"
    :"=r"(Version)
    :"i" ((uint16_t)VERSION)
    )
    return version;
}


--------------------
На любой вопрос даю любой ответ
"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
Огурцов
сообщение Sep 9 2008, 09:16
Сообщение #5


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



Ага, naked - замечательное слово. 10x!

Получилось примерно так:

Код
#define VERSION  12345

uint16 Get_version()
{
    return VERSION;
}

__attribute__((naked)) ISR(SIG_OVERFLOW0) // ISR_NAKED почему-то не берет
{
    asm volatile
    (
        "rjmp Get_version \n\t"
    );
}


Приложение ничего не знает о загрузчике, поэтому вектора (либо как-то по другому, но с _фиксированными_ адресами) отличное решение. Прерывания в загрузчике не нужны, если когда и потребуются, то это будет уже совсем другая история.
Теперь остается вопрос, как в приложении красиво вычислить адрес ?
Т.к. размеры вектора в таблице и размеры бутовой области у разных камней разные.
Тупо загнать в ifdef`ы или в GCC опять предусмотрена какая-нибудь хитрость(атрибут) ?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 9 2008, 09:50
Сообщение #6


Гуру
******

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



Цитата(Огурцов @ Sep 9 2008, 12:16) *
Теперь остается вопрос, как в приложении красиво вычислить адрес ?
Т.к. размеры вектора в таблице и размеры бутовой области у разных камней разные.
Кристаллы бывают разные, но на этапе компиляции, как правило, известно, для какого кристалла компилится и сколько в этом кристалле отдано под загрузчик. Точнее, точно известны адреса этих функций. Я их указываю в скрипте линкера или командной строке:
Код
*.cpp:
extern "C" uint16_t SerialNo();
*.c:
extern uint16_t SerialNo();

makefile:
LDFLAGS += -Wl,--defsym,SerialNo=0x1FFA
или *.ld:
SECTIONS
{
  ....
}
SerialNo = 0x1FFA;



Цитата(Огурцов @ Sep 9 2008, 12:16) *
Получилось примерно так:
Код
__attribute__((naked)) ISR(SIG_OVERFLOW0) // ISR_NAKED почему-то не берет
{
    asm volatile
    (
        "rjmp Get_version \n\t"
    );
}
ISR_NAKED появилось в последних версиях, возможно в вашей еще нет. Теперь посмотрите в листинг. У вас в области векторов получился rjmp на обработчик, из которого уже rjmp на функцию. Разместите уже всю функцию в обработчик, сэкономите место и время.


--------------------
На любой вопрос даю любой ответ
"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
Огурцов
сообщение Sep 9 2008, 13:26
Сообщение #7


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



Цитата(Сергей Борщ @ Sep 9 2008, 09:50) *
Точнее, точно известны адреса этих функций. Я их указываю в скрипте линкера или командной строке:

Да, это красиво. Но в данном случае вызывает проблемы - в случае, если вносим изменения в бутлоадер, автоматически получается два make`а и два bin`а. Или в следующий раз еще больше. То, что бутлоадер будет меняться я даже не сомневаюсь, поэтому вариант с использованием векторов мне понравился гораздо больше.

Цитата(Сергей Борщ @ Sep 9 2008, 09:50) *
ISR_NAKED появилось в последних версиях, возможно в вашей еще нет.

Да, что-то такое, видимо.

Цитата(Сергей Борщ @ Sep 9 2008, 09:50) *
У вас в области векторов получился rjmp на обработчик, из которого уже rjmp на функцию. Разместите уже всю функцию в обработчик, сэкономите место и время.

Да, потенциально два лишних jamp`а, но м.б. будет вызов более сложных функций, типа crc посчитать, которые оптимизировать и руками прегонять в ассемблер проблемно да, думаю, и не нужно. А в случае с версией да, один jamp можно выкинуть.

С векторами, похоже, будет так:

Код
#define GET_VERSION_VECTOR    1

__attribute__((naked)) ISR(_VECTOR(GET_VERSION_VECTOR))
...


Ничего лучше пока не придумалось
Go to the top of the page
 
+Quote Post



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

 


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


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