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

 
 
> Ещё раз о бутлоадере, Некоторые тонкости.
SasaVitebsk
сообщение Oct 4 2007, 09:17
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Задумка такая.

По старту попадаем в бут. Там считаем CRC и если Ok - выходим на саму приложение. Если не Ok то переходим на сам лодырь.

В приложении по команде переходим непосредственно на лоадырь.


То есть мне надо две точки входа. По сбросу и по команде. Хотелось бы использовать незадействованные вектора бутлоадера. Например +2. Как это сделать. Если использовать pragma location, то наверняка будет linker ругаться.

Конечно можно упростить задачу и использовать какой нибудь признак в EEPROM. Или портить CRC к примеру, но что-то мне не нравится такой подход.

А кто как делает?
Go to the top of the page
 
+Quote Post
4 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 59)
Сергей Борщ
сообщение Oct 4 2007, 09:37
Сообщение #2


Гуру
******

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



Цитата(SasaVitebsk @ Oct 4 2007, 12:17) *
Хотелось бы использовать незадействованные вектора бутлоадера. Например +2. Как это сделать. Если использовать pragma location, то наверняка будет linker ругаться.
Конечно можно упростить задачу и использовать какой нибудь признак в EEPROM. Или портить CRC к примеру, но что-то мне не нравится такой подход.
Есть некая нога, которую приложение всегда настраивает на вывод. Например выход USART или нога, на которой висит светодиод. После сброса все порты гарантировано настроены на ввод. Значит, используюя даже одну точку входа по направлению этой ноги можем судить - мы попали по сбросу или по переходу из приложения. По второму вопросу: в коде пишем
Код
extern void BootLoader();
В командной строке линкера добавляем -DBootLoader=0x1800 или в .xcl дописываем -DBootLoader=0x1800. Все. в приложении делаем dir_out(MANUAL_PROG); __disable_interrupt(); BootLoader();
На всякий случай в __low_level_init() лодыря сразу же запретить прерывания и переключить вектора на лодырь (если используются).


--------------------
На любой вопрос даю любой ответ
"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
SasaVitebsk
сообщение Oct 4 2007, 19:14
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Спасибо Сергей. Всё доступно объяснил. smile.gif Подходят оба варианта.
Go to the top of the page
 
+Quote Post
arttab
сообщение Oct 7 2007, 14:34
Сообщение #4


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

Группа: Свой
Сообщений: 1 432
Регистрация: 7-12-04
Из: Новосибирск
Пользователь №: 1 371



а почему бы не объявить переменную в озу в загрузчике и основной программе по одному и тому же адресу.
В загрузчике ей присваевается значение (не 0 или FF) по результатам проверки срс, а в основной проге считывается значение. и по значению делаем выводы.


--------------------
OrCAD, Altium,IAR, AVR....
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 8 2007, 08:16
Сообщение #5


Гуру
******

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



Цитата(arttab @ Oct 7 2007, 17:34) *
В загрузчике ей присваевается значение (не 0 или FF) по результатам проверки срс, а в основной проге считывается значение. и по значению делаем выводы.
Потому что содержимое ОЗУ по включению питания не определено. Там может случайно оказаться и "магическое" число. А направление портов четко оговорено, к тому же такой метод не требует дополнительных затрат ОЗУ - жаба душит выдлять ячейку, которая используется только один раз при включении smile.gif


--------------------
На любой вопрос даю любой ответ
"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
IJAR
сообщение Oct 9 2007, 07:28
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 232
Регистрация: 26-02-07
Из: г. Зеленоград
Пользователь №: 25 669



Цитата(SasaVitebsk @ Oct 4 2007, 13:17) *
Задумка такая.

По старту попадаем в бут. Там считаем CRC и если Ok - выходим на саму приложение. Если не Ok то переходим на сам лодырь.

В приложении по команде переходим непосредственно на лоадырь.
То есть мне надо две точки входа. По сбросу и по команде. Хотелось бы использовать незадействованные вектора бутлоадера. Например +2. Как это сделать. Если использовать pragma location, то наверняка будет linker ругаться.

Конечно можно упростить задачу и использовать какой нибудь признак в EEPROM. Или портить CRC к примеру, но что-то мне не нравится такой подход.

А кто как делает?


Добавлю и я свои наработки:
1. Использовать ногу процессора - метод надежный, но IMHO это будет "жирновато", ног не всегда
хватает+на плате надо вешать на эту ногу резюк, кроме того в разных проектах это могут быть
разные ноги.
2. Вариант с EEPROM более предпочтителен, поскольку 1-й старт после прошивки программатором
BootLoader-a всегда будет на него. Тогда при отладке приложения работа будет такой:
а) - загрузка приложения
б) подача BootLoader-у команды передать управление на приложение, т.е. на адрес 0x0000
После отладки - прописать в EEPROM признак: сразу после Reset передавать управление на
приложение.
Правда здесь есть один подводный камень - зависание приложения или необходимость его
коррекции. Здесь можно использовать такой метод:
Если в течении, например 1-ой минуты проходит не менее 10-ти горячих рестартов, то в
EEPROM устанавливается признак блокировки перехода на приложение.


--------------------
Вяжешь - вой, а поедешь - песни пой.
Между "хочу" и "можно" всегда есть дистанция
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 9 2007, 10:45
Сообщение #7


Гуру
******

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



Цитата(IJAR @ Oct 9 2007, 10:28) *
1. Использовать ногу процессора - метод надежный, но IMHO это будет "жирновато", ног не всегда хватает+на плате надо вешать на эту ногу резюк, кроме того в разных проектах это могут быть разные ноги.
Используется нога, которая в приложении выполняет какую-либо функцию. Например выход UART или выход на светодиод. Подтяжка желательна, но это может быть штатная подтяжка (например подтяжка CS внешнего устройства или тот же светодиод). В разных проектах пишется #define MANUAL_PROG C,3,L или #define MANUAL_PROG B,0,H


--------------------
На любой вопрос даю любой ответ
"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
IJAR
сообщение Oct 9 2007, 11:40
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 232
Регистрация: 26-02-07
Из: г. Зеленоград
Пользователь №: 25 669



Цитата(Сергей Борщ @ Oct 4 2007, 13:37) *
Есть некая нога, которую приложение всегда настраивает на вывод. Например выход USART или нога, на которой висит светодиод. После сброса все порты гарантировано настроены на ввод. Значит, используюя даже одну точку входа по направлению этой ноги можем судить - мы попали по сбросу или по переходу из приложения.


А какой смысл возврата в BootLoader из приложения?
Как я понимаю, по Reset всегда на BL а далее разбор:
пользоваться ли его услугами или сразу перейти к выполнению приложения.
Может я что-то "не догоняю".


--------------------
Вяжешь - вой, а поедешь - песни пой.
Между "хочу" и "можно" всегда есть дистанция
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 9 2007, 12:01
Сообщение #9


Гуру
******

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



Цитата(IJAR @ Oct 9 2007, 14:40) *
А какой смысл возврата в BootLoader из приложения?
Чтобы обновлять ПО по команде извне по интерфейсу связи. Это удобно как для устройств, находящихся в труднодоступных местах, так и для устройств на столе - для перепрошивки их не нужно вскрывать чтобы замкнуть джампер. Протокол связи поддерживается приложением, оно получает команду "обновление", передает управление в загрузчик, загрузчик формирует ответ "к загрузке готов" в соответствии с протоколом связи. Если же мы стартанули загрузчик принудительно или приложения нет/не сошлась контрольная сумма, то загрузчик сам ожидает команду "обновление" (и это единственная команда из всего протокола, которая в нем реализована).


--------------------
На любой вопрос даю любой ответ
"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
IJAR
сообщение Oct 9 2007, 12:33
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 232
Регистрация: 26-02-07
Из: г. Зеленоград
Пользователь №: 25 669



Цитата(Сергей Борщ @ Oct 9 2007, 16:01) *
Чтобы обновлять ПО по команде извне по интерфейсу связи. Это удобно как для устройств, находящихся в труднодоступных местах, так и для устройств на столе - для перепрошивки их не нужно вскрывать чтобы замкнуть джампер. Протокол связи поддерживается приложением, оно получает команду "обновление", передает управление в загрузчик, загрузчик формирует ответ "к загрузке готов" в соответствии с протоколом связи. Если же мы стартанули загрузчик принудительно или приложения нет/не сошлась контрольная сумма, то загрузчик сам ожидает команду "обновление" (и это единственная команда из всего протокола, которая в нем реализована).

Логично! beer.gif
Но есть один недостаток: приложение должно поддерживать протокол (иметь возможно лишний программный код) . А если приложение пишет другой программист, не разработчик BL или вообще
в другой конторе (например у потребителя устройства). Ему же надо все описать, что он должен сделать.


--------------------
Вяжешь - вой, а поедешь - песни пой.
Между "хочу" и "можно" всегда есть дистанция
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 9 2007, 14:33
Сообщение #11


Гуру
******

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



Цитата(IJAR @ Oct 9 2007, 15:33) *
Но есть один недостаток: приложение должно поддерживать протокол (иметь возможно лишний программный код).
Да, есть такое. Но если какой-то интерфейс с внешним миром есть, обычно поверх него есть и какой-то протокол. Добавить в него одну команду обычно несложно. Если интерфейса нет (точнее он не выведен наружу) - ну остается джампер на плате.
Цитата(IJAR @ Oct 9 2007, 15:33) *
А если приложение пишет другой программист, не разработчик BL или вообще в другой конторе (например у потребителя устройства). Ему же надо все описать, что он должен сделать.
Да. Описываю так: 1) запретить прерывания 2)настроить ногу X на вывод. 3) перейти по адресу 0x1800.
В общем главное - что мы друг друга поняли.


--------------------
На любой вопрос даю любой ответ
"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
SasaVitebsk
сообщение Oct 9 2007, 23:55
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Сергей, всётаки по коду не уложился в 2к. Со своим WakeUp-ом. Там ещё некоторые приколы есть. У меня должно осуществляться обновление прямо в сети. Соответственно при обновлении требуется сверять серийный номер устройства. Его я не хочу записывать в лоадер, дабы лоадер унифицированный был. Поэтому при перепрошивке вытаскиваю номер перепрошиваю и сохраняю номер. smile.gif

Короче впрямую в 2к не влез. В связи с тем, что сам протокол Wake, если работать ч/з прерывания, практически не связан с лоадером - переписал его на ASM. Думаю так влезу.

Но вот возник вопрос.

там есть конструкция в лоадере если помнишь.

typedef union
{
struct
{
uint8_t m_rxBuffer[BUFFER_SIZE]; // Receive buffer
uint8_t m_pageBuffer[PAGE_SIZE]; // Page is assembled here before
// getting programmed to flash mem
} part1;

#define rxBuffer sharedbufs.part1.m_rxBuffer

Честно говоря смысл её не всосал. Чтобы к одному и тому же участку памяти под разными именами обращаться, что ли.

Но у меня с ней проблемы на ASM. Не могу понять как на ASM указать адрес начала буфера приёмного (rxBuffer)???


Сори. smile.gif Разобрался.

Просто как-то в голове не укладывается как в ассемблере имена структур фигурируют. Понятно что потом линкер их к адресам приводит, но всё равно несколько диковато. smile.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 10 2007, 10:58
Сообщение #13


Гуру
******

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



Цитата(SasaVitebsk @ Oct 10 2007, 02:55) *
Сергей, всётаки по коду не уложился в 2к. Со своим WakeUp-ом.
Ты пытаешься засунуть в загрузчик еще какие-то команды кроме UpdateFirmware? У меня Wake-подобный протокол, я сделал так:
Код
static unsigned char busReceiveByte(void)
{
    uint8_t c = UART_getchar();
    if(c == CTL)
        c = UART_getchar() ^ 0x20;
    return c;
}
__C_task void main(void)
{
.......
    if(!dir(MANUAL_PROG))
    {
        uint8_t command[7];
        command[0] = 0xC0;          // Begin Of Frame
        uint16_t Tmp = SerialNo();
        command[1] = Tmp;
        command[2] = Tmp >> 8;
        command[3] = 0xFF;
        uint8_t *ptr = &command[1];
        Tmp = 0xFFFF;
        Tmp = CRC_XMODEM (*ptr++, Tmp);
        Tmp = CRC_XMODEM (*ptr++, Tmp);
        Tmp = CRC_XMODEM (*ptr++, Tmp);
        command[4] = ~Tmp;
        command[5] = ~(Tmp >> 8);
        command[6] = 0xC1;          // End Of Frame
        uint8_t idx = 0;
        do {
            uint8_t c = busReceiveByte();

            if(c != command[idx])
                idx = 0;
            else
                idx++;
        } while(idx < sizeof(command));        // wait for EOM
    }
    busReplyByte(ERROR_OK);
Т.е. я формирую образ всей команды и сравниваю проходящий поток с образцом. Сгенерить образец гораздо проще, чем реализовывать весь конечный автомат приема. Увы, это проходит только для одной команды.
Цитата(SasaVitebsk @ Oct 10 2007, 02:55) *
Соответственно при обновлении требуется сверять серийный номер устройства. Его я не хочу записывать в лоадер, дабы лоадер унифицированный был. Поэтому при перепрошивке вытаскиваю номер перепрошиваю и сохраняю номер. smile.gif
У меня в области загрузчика есть функция
Код
#pragma segment="GET_SERIAL"
#pragma location="GET_SERIAL"
__root uint16_t SerialNo(void) { return ~0;}
При прошивке я указываю AvRealу -c?serno2=1826,serno.txt и он автоматически при программировании подставляет в эту функцию уникальные номера. Номер хранится в загрузчике и не может быть случайно стерт с приложением. Функцию SerialNo() можно вызвать и из приложения, поэтому и приложение становится независимым от серийника. Функция занимает 6 байт, что меньше чем код для чтения 16-битной константы из флеш с помощью LPM
Цитата(SasaVitebsk @ Oct 10 2007, 02:55) *
Честно говоря смысл её не всосал. Чтобы к одному и тому же участку памяти под разными именами обращаться, что ли.
Именно так. Для улучшения читабельности. Т.е. "сейчас мы работаем с этим блоком как с буфером приема"
Цитата(SasaVitebsk @ Oct 10 2007, 02:55) *
Сори. smile.gif Разобрался.
Просто как-то в голове не укладывается как в ассемблере имена структур фигурируют. Понятно что потом линкер их к адресам приводит, но всё равно несколько диковато. smile.gif
Ну, если не на плюсах писать, то имена как и у обычных переменных. А вот к полям из ассемблера, увы, только вручную указывая смещение от начала структуры.


--------------------
На любой вопрос даю любой ответ
"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
SasaVitebsk
сообщение Oct 10 2007, 13:35
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Сергей Борщ @ Oct 10 2007, 13:58) *
Ты пытаешься засунуть в загрузчик еще какие-то команды кроме UpdateFirmware? У меня Wake-подобный протокол, я сделал так:


Пытаюсь Сергей. sad.gif

Вчера в 3 часа ночи получил результат 2232. sad.gif Если бы надо было байт 50 выжать ещё бы попытался, а так буду пробовать в обход. Я видишь ли с прерываниями завязался. Возможно придётся отказаться. Только вектора занимают 112 байт. Можно конечно их под себя подмять.

Короче буду думу думать. Жалко выделять 4к если нехватает совсем чуть чуть.


Спасибо за рекомендации. Разбираюсь. Пользуюсь. Помагает.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 10 2007, 15:46
Сообщение #15


Гуру
******

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



Цитата(SasaVitebsk @ Oct 10 2007, 16:35) *
Пытаюсь Сергей.
. Интересно, какие? Мне пока в голову приходила всего одна команда, полезная в загрузчике - запрос версии. Приложение отвечает свою версию, загрузчик отвечает 0. Тогда центральный узел понимает, что приложение ёк и его надо перешить обязательно. А по ответу приложения о версии центральный узел может определять - нужно ли апгрейдить. Планирую реализовать. Думаю, что второй массив с образцом команды и поиск по нему как в примере выше не сильно раздует код. А на какие запросы у тебя отвечает загрузчик?
Цитата(SasaVitebsk @ Oct 10 2007, 16:35) *
Только вектора занимают 112 байт. Можно конечно их под себя подмять.
"Не только мона, но и нуна!" А как в .xcl сегменты распределяются? Я отдаю под код все после последнего используемого вектора:
Код
// Interrupt vectors
-Z(CODE)INTVEC=1800-1825
// Code memory
-Z(CODE)NEAR_F,HUGE_F,SWITCH,INITTAB,DIFUNCT,CODE=1802-1FFF
-Z(CODE)GET_SERIAL,GET_AREA#1802-1FFF
Хм. Скопировал сюда и призадумался - зачем указываю 0x1802, ведь 0x1800 всегда занят... Можно писать 1800-1FFF.
Цитата(SasaVitebsk @ Oct 10 2007, 16:35) *
Жалко выделять 4к если нехватает совсем чуть чуть.
"Вам то хорошо..." (с) "Операция "С Новым Годом"". Вот если бы было 2 и не больше, как в m8, это бы еще сильнее стимулировало smile.gif


--------------------
На любой вопрос даю любой ответ
"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
Dog Pawlowa
сообщение Oct 10 2007, 16:42
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Сергей Борщ @ Oct 10 2007, 18:46) *
... А на какие запросы у тебя отвечает загрузчик?" ...

При наличии в сети разных устройств кроме текущей версии нужно знать еще и тип устройства, чтобы прошивку от БМВ не прошить в Боинг smile.gif
То есть желательно иметь команду запроса типа устройства по данному адресу.
Но мы тоже экономили команды, и тип устройства содержится в нулевой странице по фиксированному адресу - то есть сравнивает типы устройств бутлоадер, и он уникальный для каждого типа устройств (если контроллер одинаковый - отличие в строке символов, определяющей тип).


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 10 2007, 16:57
Сообщение #17


Гуру
******

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



Цитата(Dog Pawlowa @ Oct 10 2007, 19:42) *
При наличии в сети разных устройств кроме текущей версии нужно знать еще и тип устройства, чтобы прошивку от БМВ не прошить в Боинг smile.gif
А, ну да. У меня тип отвечается вместе с версией, поэтому я о нем и не подумал. Хорошо, все необходимые данные загрузчик может отдавать в одном ответе. Обзовем это "запросом конфигурации". Какие еще команды должен поддерживать загрузчик?

И понятное дело - для разных типов и даже для одного типа, но несовместимых версий железа разные ключи шифрования, так что БМВ не взлетит biggrin.gif


--------------------
На любой вопрос даю любой ответ
"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
SasaVitebsk
сообщение Oct 11 2007, 09:07
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Код

2 106 bytes of CODE memory
1 430 bytes of DATA memory (+ 8 absolute )


smile.gif

Непонятно ещё какая то хрень записывает 4 байта по 00 адресу.


Короче оставлю пока 4к на бутлоадер и приступаю к отладке. Когда отлажу, тогда уберу оставшийся жирок.
Go to the top of the page
 
+Quote Post
Waso
сообщение Oct 12 2007, 08:36
Сообщение #19


Местный
***

Группа: Свой
Сообщений: 268
Регистрация: 4-11-05
Пользователь №: 10 470



Извиняюсь что лезу в чужую тему, но есть дилетантский вопрос по ней.
Мне нужно обеспечить перепрошиваемость устройства (sam7x256) через ethernet. http и ftp сервера уже реализованы. Я планирую через ftp заливать (декриптовать находу) бинарник в свободную часть флеши и, после успешной проверки CRC, переписывать reset-вектор чтобы он указывал на начало этого бинарника.

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

Прав ли я и смогу ли я избежать танцев с бубном вокруг бутлодера?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 12 2007, 11:04
Сообщение #20


Гуру
******

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



Цитата(Waso @ Oct 12 2007, 11:36) *
Я планирую через ftp заливать (декриптовать находу) бинарник в свободную часть флеши и, после успешной проверки CRC, переписывать reset-вектор чтобы он указывал на начало этого бинарника.
Это очень плохая идея - переписывать вектора. Потому что обязательно в этот момент произойдет сбой питания и устройство окажется неработоспособным. Вектор сброса должен указывать на неизменяемую часть кода (бутлодер), который определяет куда передать управление дальше. Для остальных векторов я использую ремап.
Цитата(Waso @ Oct 12 2007, 11:36) *
А бутлодер нужен, насколько я понимаю, чтобы переписывать прошивку поверх старой, и данные при этом брать из внешнего источника.
Вовсе нет - бутлодер - это общее название (части)программы, предназначенной для обновления прошивки.


--------------------
На любой вопрос даю любой ответ
"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
Waso
сообщение Oct 15 2007, 07:02
Сообщение #21


Местный
***

Группа: Свой
Сообщений: 268
Регистрация: 4-11-05
Пользователь №: 10 470



Спасибо за совет!
Нашел апноты. Изучаю.

Safe and Secure Firmware Upgrade for AT91SAM Microcontrollers
Safe and Secure Bootloader Implementation
Safe and Secure Bootloader Implementation (source.zip)

Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 16 2007, 10:28
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Ещё один вопрос, напрямую с бутлоадером не связанный а вот с IAR да.

Я решил разместить серийный номер изделия непосредственно в буте по фиксированному адресу.
Это мне облегчает некоторые вещи. Программирование осущ. в сети и поэтому серийный номер как бы непосредственно связан с самим камнем.

Так вот такой вопрос.
В приложении я объявляю переменную таким образом

extern const uint32_t __flash SerialNN @ BOOTSERIAL; // Серийный номер

Так IAR генерит в hex файле по указаному адресу 00000000. Что в свою очередь плохо сказывается на файл формируемый CREATE и при заливке портит мне загрузчик. Непонятно как его вообще убрать.

Понятно что можно ручками эту строчку из HEX. Но этож будешь забывать. Понятно что потом я BLB поставлю, но хотелось бы найти нормальное решение.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 16 2007, 12:51
Сообщение #23


Гуру
******

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



Цитата(SasaVitebsk @ Oct 16 2007, 13:28) *
Так IAR генерит в hex файле по указаному адресу 00000000. Что в свою очередь плохо сказывается на файл формируемый CREATE и при заливке портит мне загрузчик. Непонятно как его вообще убрать.
__no_init const uint32_t __flash SerialNN @ BOOTSERIAL; Но как ты будешь читать серийник, если выставишь локи BLB1? Может лучше разместить в области загрузчика функцию uint16_t SerialNo() { return 0xFFFF; } в которой при прошивке менять 0xFFFF на серийник (AvReal такое умеет)? Она займет на 4 байта больше чем просто константа, но снимет все проблемы.


--------------------
На любой вопрос даю любой ответ
"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
SasaVitebsk
сообщение Oct 16 2007, 16:47
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Спасибо, но я не планирую запрещать локи на чтение.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 16 2007, 18:01
Сообщение #25


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(SasaVitebsk @ Oct 10 2007, 17:35) *
Вчера в 3 часа ночи получил результат 2232. sad.gif Если бы надо было байт 50 выжать ещё бы попытался, а так буду пробовать в обход. Я видишь ли с прерываниями завязался. Возможно придётся отказаться. Только вектора занимают 112 байт. Можно конечно их под себя подмять.
Короче буду думу думать. Жалко выделять 4к если нехватает совсем чуть чуть.
SasaVitebsk, а Вы принципиально не будете пробовать Gcc ?
Стало интересно, посмотрел на исходники, ну этот код, особенно aes.c просто предназначен для
компилирования gcc smile.gif
на Iar там принципиально хуже...

P.S. Еще очень порадовало обращение к EEPROM переменным через функции писанные на асм...
Интересно, почему на Iar не воспользовались __eeprom ???
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Oct 16 2007, 20:32
Сообщение #26


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(Сергей Борщ @ Oct 16 2007, 15:51) *
__no_init const uint32_t __flash SerialNN @ BOOTSERIAL;

Разве __no_init и __flash совместимы?
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 16 2007, 20:58
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



2 singlskv. Не планирую переходить на GCC. Работы завались и времени на изучение новых пакетов банально не хватает. Тем более, что я пробовал с ним работать вначале. Мне не понравилось, что по сути это не один продукт а десятки слабоинтегрированных фичей. Я, безусловно, не претендую даже на коментарии к этому продукту. Просто высказываю своё первое впечатление. Я уже обратил внимание, что есть специалисты, которым такое построение нравится. Они берут компилятор с одного источника линкер с другого, редактор с третьего а отладчик с четвёртого. Наверное это правильно. Возможно я до этого дойду, но пока - не готов. __eeprom пользуюсь. Ассемблерный файл spm выкинул и пользуюсь IARовскими приблудами. Благо Сергей Борщ предложил свой вариант. Спасибо ему.

Кто-нибудь прогу по расчёту CRC от IAR смог повторить? Что-то у меня в лоб не заработало, а подбирать на CRC - гиблый номер. Легче свою сварганить.


Я пробовал так. Вроде именно так они рекомендуют. Не причёсывал. Чтобы максимально близко к данному варианту было. Потом перепишу.
Код
#define        POLY    0x11021

inline unsigned long
crc16(int bit, unsigned long oldcrc)
{
unsigned long newcrc = (oldcrc << 1) ^ bit;
if (oldcrc & 0x80000000)
newcrc ^= POLY;
return newcrc;
}

__C_task void main(void)
{
  __disable_interrupt();

  #ifdef CRC_CHECK
    // Считаем CRC всей памяти флэш
    unsigned long crc = 0;
    unsigned char i,j;
    unsigned char APPFLASH *p = (unsigned char APPFLASH *)0x000000;
    unsigned char APPFLASH *n = (unsigned char APPFLASH *)MEM_SIZE;
    
    do
    {
      j= *p++;
      for(i=0;i<8;i++)
      {
        crc = crc16(j & 1,crc);
        j>>=1;
      }
    }
    while (--n);
    
    // Если секция программ повреждена
    // то переходим к загрузке в бутлоадер
    if (crc)  ((void (*)())loader)();            // Переходим на сам загрузчик
  #endif
        
  ((void (*)())0x0000)();                        // Если с CRC всё нормально, то перейдём в начало
                                                  // секции программ
}
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 17 2007, 09:56
Сообщение #28


Гуру
******

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



Цитата(singlskv @ Oct 16 2007, 21:01) *
Стало интересно, посмотрел на исходники, ну этот код, особенно aes.c просто предназначен для компилирования gcc smile.gif
Ну так а что на "посмотрел" остановились? Попробуйте откомпилировать gcc, увидите, что без основательной "правки напильником" gcc дает в полтора раза бОльший код. И максимальная разница как раз на aes.c.


Цитата(SasaVitebsk @ Oct 16 2007, 23:58) *
Код
#define        POLY    0x11021
0x80000000 великовато. Должно быть что-то около 0x10000. Попробуй такой вариант:
Код
/*
uint16_t CRC (uint16_t crc, uint8_t data)
{
    static const unsigned short crcPoly = 0x1021;
    crc ^= (uint16_t)data << 8;
    for(uint8_t i = 0; i < 8; i++)
    {
        if ( crc & (1<<15) ) { crc <<= 1; crc ^= crcPoly; }
        else crc <<= 1;
    }
    return crc;
}
*/

uint16_t CRC(uint16_t crc, uint8_t data)
{
    static const unsigned short crcPoly = 0x1021;
    
    uint32_t m = ((uint32_t)crc << 8) | data;
    for (uint8_t i = 0; i < 8; i++)
        if ((m <<= 1) & 0x1000000)
            m ^= ((uint32_t)crcPoly << 8);

    return (uint16_t)(m >> 8);
}
Первый вариант эффективнее на 8/16-битной архитектуре, второй - на 32-битной. Считает сразу весь байт.


--------------------
На любой вопрос даю любой ответ
"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
singlskv
сообщение Oct 17 2007, 20:29
Сообщение #29


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(SasaVitebsk @ Oct 17 2007, 00:58) *
__eeprom пользуюсь. Ассемблерный файл spm выкинул и пользуюсь IARовскими приблудами. Благо Сергей Борщ предложил свой вариант. Спасибо ему.
Ну если Вы так оптимизируете свой код, то в 2K точно будет сложно влезть...
Цитата
Кто-нибудь прогу по расчёту CRC от IAR смог повторить? Что-то у меня в лоб не заработало, а подбирать на CRC - гиблый номер. Легче свою сварганить.
По расчету CRC16 опять же гляньте как это реализованно в Gcc,
там есть встроенная функция тактов на 40 (по длинне правда с циклом не сравнивал, меня
скорость обычно больше волнует).



Цитата(Сергей Борщ @ Oct 17 2007, 13:56) *
Ну так а что на "посмотрел" остановились? Попробуйте откомпилировать gcc, увидите, что без основательной "правки напильником" gcc дает в полтора раза бОльший код. И максимальная разница как раз на aes.c.
Кто бы спорил ?
Там вобще все написано левой ногой, и то что Iar справился соптимизировать этот код лучше,
еще ни о чем не говорит.
Я говорил лишь о том что данный алгоритм больше подходит для Gcc, и Ваш пост:
Цитата(Сергей Борщ @ Oct 4 2007, 16:42) *
Да. Проц - мега8. ключ 256 бит. компилятор - 4.10B. Объем кода - 1974, но есть куда ужимать. Та же мега8, WinAVR, 1888, но другой протокол команды входа в программирование и сильное ужимание.
косвенно это подтверждает.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 17 2007, 20:47
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(singlskv @ Oct 17 2007, 23:29) *
то что Iar справился соптимизировать этот код лучше,
еще ни о чем не говорит.
Я говорил лишь о том что данный алгоритм больше подходит для Gcc...

Т.е. IAR даже "алгоритм больше подхоящий для GCC" скомпилировал лучше smile.gif. Но это "ни о чем не говорит" sad.gif. Жаль smile.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 17 2007, 20:57
Сообщение #31


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(zltigo @ Oct 18 2007, 00:47) *
Т.е. IAR даже "алгоритм больше подхоящий для GCC" скомпилировал лучше smile.gif. Но это "ни о чем не говорит" sad.gif. Жаль smile.gif
Опять вырывем фразу из контекста ?
В этом Вы несомненно мастер !!!
Хотите посоревноваться в оптимизации кода ?
или просто поболтать ?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 17 2007, 21:12
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(singlskv @ Oct 17 2007, 23:57) *
Опять вырывем фразу из контекста ?

Контекста? Контекста собственно и не наблюдается вообще никакого. Только совет использовать GNU по причине того, что aes.c и GNU якобы созданы друг для друга.
Цитата
Хотите посоревноваться в оптимизации кода ?

Можете начинать, если хотите. Понаблюдаю. Объект aes.c есть. Цель - достичь минимального обьема кода - поставлена.
Цитата
или просто поболтать ?

Вот как раз против болтовни и хотелось выступить.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 17 2007, 21:53
Сообщение #33


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(zltigo @ Oct 18 2007, 01:12) *
Контекста? Контекста собственно и не наблюдается вообще никакого. Только совет использовать GNU по причине того, что aes.c и GNU якобы созданы друг для друга.
Можете начинать, если хотите. Понаблюдаю. Объект aes.c есть. Цель - достичь минимального обьема кода - поставлена.
Дык понаблюдаю или поучаствую ???
Цитата
Вот как раз против болтовни и хотелось выступить.
Те кто только наблюдают, и высказывают свое мнение в стиле,
"а IAR все равно круче", ИМХО, как раз и занимаются болтовней...


Готовы поучаствовать ?
Кажись Вы уже этот исходник уже используете ?
Скомпилируйте его для какой-нить меги и выложите сюда.
Я соптимизрую для Gcc и тоже выложу сюда.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 17 2007, 22:04
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(singlskv @ Oct 18 2007, 00:53) *
Скомпилируйте его для какой-нить меги и выложите сюда.

Легко. Тупо без затей взял из атмеловского AN
Код
aes.c
iccavr.exe D:\ARM_WORK\0\0BACKUP\loader.9\0\Source Code\IAR\aes.c --cpu=m128 -ms -o D:\ARM_WORK\0\0BACKUP\loader.9\0\Source Code\IAR\Release\Obj\  
--diag_suppress Pe1053 -y --initializers_in_flash -z9 --no_tbaa --cross_call_passes=1 -DENABLE_BIT_DEFINITIONS -e -I D:\IAR\Embedded Workbench\avr\INC\ -I D:\
IAR\Embedded Workbench\avr\INC\CLIB\ --eeprom_size 4096  

   IAR Atmel AVR C/C++ Compiler V4.30A/W32, Evaluation Version  
   Copyright 1996-2007 IAR Systems. All rights reserved.  
  
1 096 bytes of CODE memory (+ 7 bytes shared)
   522 bytes of DATA memory




Цитата(singlskv @ Oct 18 2007, 00:53) *
Я соптимизрую для Gcc и тоже выложу сюда.

Нет уж, для начала оставте в неприкосновенности. Потом, можете хоть ручками на ASM переписывать smile.gif
Прикрепленные файлы
Прикрепленный файл  aes.rar ( 3.51 килобайт ) Кол-во скачиваний: 57
 


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 17 2007, 22:24
Сообщение #35


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(zltigo @ Oct 18 2007, 02:04) *
Легко. Тупо без затей взял из атмеловского AN
Нет уж, для начала оставте в неприкосновенности. Потом, можете хоть ручками на ASM переписывать smile.gif
Ок,
не обещаю что очень быстро выложу результаты(работать тоже иногда нужно smile.gif )
а портировать просто на Gcc без изменения кода там тоже прилично...
для адекватного сравнения предлягаю добавить минимальную прогу которая будет вызывать
aesInit() и aesDecrypt() для какого-нить буфера.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 17 2007, 22:35
Сообщение #36


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(singlskv @ Oct 18 2007, 01:24) *
а портировать просто на Gcc без изменения кода там тоже прилично...

В aes.c ничего специфичного для какого-либо компилятора. Изменения в исходнике практически не нужны.
Откомпилируйте только его - 5 минут работы.
Примеры:
Код
wcc -omsn -d0 -s aes.c
Open Watcom C16 Optimizing Compiler Version 1.7
Portions Copyright (c) 1984-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
aes.c: 387 lines, included 124, 0 warnings, 0 errors
Code size: 1308

Код
iccarm.exe D:\ARM_WORK\LOADER\AES\aes.c -lC D:\ARM_WORK\LOADER\Works\List\ --remarks --diag_suppress Pe1422,Pe1375 -o D:\ARM_WORK\LOADER\
Works\Obj\ --endian little --cpu ARM7TDMI-S -e --require_prototypes --fpu None --dlib_config D:\ARM_WORK\LOADER\RESOURCE\dlib_cfg.h -I D:\ARM_WORK\
LOADER\AES\ -I D:\ARM_WORK\LOADER\FLASH\ -I D:\ARM_WORK\LOADER\..\common\INCLUDE\ -I D:\ARM_WORK\LOADER\ -I D:\IAR\Embedded Workbench 5\
ARM\INC\ --cpu_mode thumb -Ohz

   IAR ARM ANSI C/C++ Compiler V5.10.2.372/W32 EVALUATION
   Copyright 1999-2007 IAR Systems. All rights reserved.  
  
1 076 bytes of CODE  memory
    36 bytes of CONST memory
   532 bytes of DATA  memory


Сообщение отредактировал zltigo - Oct 18 2007, 07:38


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 17 2007, 22:55
Сообщение #37


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(zltigo @ Oct 18 2007, 02:35) *
В aes.c ничего специфичного для какого-либо компилятора. Изменения в исходнике практически не нужны.
Откомпилируйте только его - 5 минут работы.
Пример:
Код
Open Watcom C16 Optimizing Compiler Version 1.7
Portions Copyright (c) 1984-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
aes.c: 387 lines, included 124, 0 warnings, 0 errors
Code size: 1429

Не, тока завтра смогу, там нужно __flash на PROGMEM менять аккуратненько....
сегодня я уже не в силах этим заниматься ...
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 18 2007, 19:35
Сообщение #38


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(singlskv @ Oct 17 2007, 23:29) *
Ну если Вы так оптимизируете свой код, то в 2K точно будет сложно влезть...
По расчету CRC16 опять же гляньте как это реализовано в Gcc,
там есть встроенная функция тактов на 40 (по длинне правда с циклом не сравнивал, меня
скорость обычно больше волнует).


bb-offtopic.gif
Уважаемый. Бут оптимизируется по коду. В программе встречается 1 вызов п/п чтения EEPROM и 1 вызов записи. Библиотеки на Яре написаны на Асме. Я их смотрел, и честно говоря в 5 операторах ассемблера не нашёл ничего из ряда вон. Да и был бы очень удивлён если бы нашёл. Так ответьте мне причём здесь применение данных п/п к оптимизации. Совершенно очевидно что на этих двух вызовах можно сэкономить ну от силы пару байтов. Речь вначале шла о сотне!

То же касается и CRC16. Я не спрашивал как её написать оптимально. Я не думаю, что написанное мной на ассемблере будет хуже вашего. Во всяком случае значительно. Я просто интересовался как именно IAR генерит CRC. Я переписал на АСМ весь свой WAKE протокол и думаю всётаки влезть в 2к. Переписал потому, что всё это реализовано по прерываниям и логически вообще не связано с самим бутом.

Подытоживая всё выше сказанное, хочется чтобы вы более конкретно обдумывали свои посты.
==========================================

Теперь по существу вопроса. Пишу это, так как только на этой странице уже поднимался вопрос по генерации CRC IARом. И думаю люди будут как и я пытаться его использовать. Для тех кто интересуется сообщаю следующее.

При размещении CRC по разным адресам сам CRC не меняется. Из чего я делаю вывод (возможно некорректный, но это то что первое приходит в голову), что CRC считается только CODE области и размещается где указано. Это не позволяет мне его использовать так как я хочу. Наверное есть опция какая-то, но я не разобрался.

Решил написать программу, которая будет считать CRC и вставлять её в нужное место прямо в HEX файле. Постораюсь написать её максимально универсально, причесать и выложить на форуме AVR для использования желающими.

Ещё один момент - прога CREATE из набора идущего к AES. В ней есть хомут. При размещении данных (CRC) в последних двух ячейках секции пользователя CREATE начинает кричать оверлапинг. При размещении CRC на две ячейки меньше, выполняет операцию, но в прошивке вы получите дополнительно два байта мусора. Исходники там приведены, но я не стал разбираться, так как всё равно не чем её откомпилить. В принципе это не страшно, просто поясняю для того, кто пойдёт по моим стопам. smile.gif

У меня - всё работает. Спасибо всем тем кто принял участие в обсуждении. Особенное спасибо Сергей Борщ за, просто неоценимую, конкретную помощь знающего человека.

Тему не закрываю, возможно ещё что возникнет.
Влезу или не влезу, для любопытных - напишу позже. smile.gif.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 18 2007, 20:40
Сообщение #39


Гуру
******

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



Цитата(SasaVitebsk @ Oct 18 2007, 22:35) *
так как всё равно не чем её откомпилить.
Dev C++В комплекте исходников идут и файлы проекта под этот компилятор.
Цитата(SasaVitebsk @ Oct 18 2007, 22:35) *
Ещё один момент - прога CREATE из набора идущего к AES. В ней есть хомут. При размещении данных (CRC) в последних двух ячейках секции пользователя CREATE начинает кричать оверлапинг. При размещении CRC на две ячейки меньше, выполняет операцию, но в прошивке вы получите дополнительно два байта мусора.
Естественно, потому что CREATE сама считает CRC (по полиному 0x8005) и располагает его в последних двух байтах секции приложения. Поэтому меня несколько ввело в замешательство ваше желание считать CRC при помощи линкера. При этом CREATE кoрректо считает все свободные ячейки заполненными 0xFFFF, в то время как линкер считает, что все свободные места между сегментами заполнены нулями.


--------------------
На любой вопрос даю любой ответ
"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
zltigo
сообщение Oct 18 2007, 22:05
Сообщение #40


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(SasaVitebsk @ Oct 18 2007, 22:35) *
Наверное есть опция какая-то, но я не разобрался.

Естественно CRC вполне управляемо.
Цитата
Решил написать программу, которая будет....

Сергей тоже пошел по такому пути не желая sad.gif разбиратся с линкером. Я пользую линкер.
Цитата
Исходники там приведены, но я не стал разбираться, так как всё равно не чем её откомпилить.

Исходники страшноваты, но GCC компилит. Я из них многое выкинул и дополнил.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 18 2007, 22:48
Сообщение #41


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



To zltigo и SasaVitebsk,
признаю, погорячился насчет перевода всего бутлодера под Gcc и cравнения с IAR.
Просто после более подробного изучения кода стало понятно что его нужно переписывать
с нуля, а это займет прилично времени... 07.gif

Цитата(SasaVitebsk @ Oct 18 2007, 23:35) *
Речь вначале шла о сотне!

Ну а чтобы было понятно о чем была речь приведу небольшой пример по оптимизации этого кода:
Было:
Код
void InvMixColumn( byte * column )
{
    byte r0, r1, r2, r3;

    r0 = column[1] ^ column[2] ^ column[3];
    r1 = column[0] ^ column[2] ^ column[3];
    r2 = column[0] ^ column[1] ^ column[3];
    r3 = column[0] ^ column[1] ^ column[2];

    column[0] = (column[0] << 1) ^ (column[0] & 0x80 ? BPOLY : 0);
    column[1] = (column[1] << 1) ^ (column[1] & 0x80 ? BPOLY : 0);
       column[2] = (column[2] << 1) ^ (column[2] & 0x80 ? BPOLY : 0);
       column[3] = (column[3] << 1) ^ (column[3] & 0x80 ? BPOLY : 0);

    r0 ^= column[0] ^ column[1];
    r1 ^= column[1] ^ column[2];
    r2 ^= column[2] ^ column[3];
    r3 ^= column[0] ^ column[3];

       column[0] = (column[0] << 1) ^ (column[0] & 0x80 ? BPOLY : 0);
       column[1] = (column[1] << 1) ^ (column[1] & 0x80 ? BPOLY : 0);
       column[2] = (column[2] << 1) ^ (column[2] & 0x80 ? BPOLY : 0);
       column[3] = (column[3] << 1) ^ (column[3] & 0x80 ? BPOLY : 0);

    r0 ^= column[0] ^ column[2];
    r1 ^= column[1] ^ column[3];
    r2 ^= column[0] ^ column[2];
    r3 ^= column[1] ^ column[3];

       column[0] = (column[0] << 1) ^ (column[0] & 0x80 ? BPOLY : 0);
       column[1] = (column[1] << 1) ^ (column[1] & 0x80 ? BPOLY : 0);
       column[2] = (column[2] << 1) ^ (column[2] & 0x80 ? BPOLY : 0);
       column[3] = (column[3] << 1) ^ (column[3] & 0x80 ? BPOLY : 0);

    column[0] ^= column[1] ^ column[2] ^ column[3];
    r0 ^= column[0];
    r1 ^= column[0];
    r2 ^= column[0];
    r3 ^= column[0];

    column[0] = r0;
    column[1] = r1;
    column[2] = r2;
    column[3] = r3;
}

Стало:
Код
void InvMixColumn( byte * column )
{
    byte r0, r1, r2, r3;
    byte co0 = column[0],co1=column[1],co2=column[2],co3=column[3];
    byte bpoly = BPOLY;

    r0 = co1 ^ co2 ^ co3;
    r1 = co0 ^ co2 ^ co3;
    r2 = co0 ^ co1 ^ co3;
    r3 = co0 ^ co1 ^ co2;

    co0 = (co0 << 1) ^ (co0 & 0x80 ? bpoly : 0);
    co1 = (co1 << 1) ^ (co1 & 0x80 ? bpoly : 0);
       co2 = (co2 << 1) ^ (co2 & 0x80 ? bpoly : 0);
       co3 = (co3 << 1) ^ (co3 & 0x80 ? bpoly : 0);

    r0 ^= co0 ^ co1;
    r1 ^= co1 ^ co2;
    r2 ^= co2 ^ co3;
    r3 ^= co0 ^ co3;

       co0 = (co0 << 1) ^ (co0 & 0x80 ? bpoly : 0);
       co1 = (co1 << 1) ^ (co1 & 0x80 ? bpoly : 0);
       co2 = (co2 << 1) ^ (co2 & 0x80 ? bpoly : 0);
       co3 = (co3 << 1) ^ (co3 & 0x80 ? bpoly : 0);

    r0 ^= co0 ^ co2;
    r1 ^= co1 ^ co3;
    r2 ^= co0 ^ co2;
    r3 ^= co1 ^ co3;

       co0 = (co0 << 1) ^ (co0 & 0x80 ? bpoly : 0);
       co1 = (co1 << 1) ^ (co1 & 0x80 ? bpoly : 0);
       co2 = (co2 << 1) ^ (co2 & 0x80 ? bpoly : 0);
       co3 = (co3 << 1) ^ (co3 & 0x80 ? bpoly : 0);

    co0 ^= co1 ^ co2 ^ co3;
    r0 ^= co0;
    r1 ^= co0;
    r2 ^= co0;
    r3 ^= co0;

    column[0] = r0;
    column[1] = r1;
    column[2] = r2;
    column[3] = r3;
}


Это примерно 120байтов экономии только на одной функции smile.gif

Спросите причем сдесь GCC ?
Ну если спросите, тогда и отвечу...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 19 2007, 07:31
Сообщение #42


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(singlskv @ Oct 19 2007, 01:48) *
Спросите причем сдесь GCC ?

Не спрошу, по тому, что он ни причем. Введение для данного куска @&$^*% и достаточно обширного кода явных промежуточных локальных (для AVR регистровых) переменных достаточно благотворно скажется на любом компиляторе. А вот степень благотворности уже зависит от врожденных способностей компилятора к оптимизации и платформы. Для ARM платформы эффект будет много меньше, зато замена многочисленных byte заточенных под 8-bit платфору на естественные int (или, что много более правильно uint_least8_t ) скажется потрясающе благотворно. Зато то-же действие для x86 платформы будет по барабану.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Oct 19 2007, 07:37
Сообщение #43


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(singlskv @ Oct 19 2007, 02:48) *
Ну а чтобы было понятно о чем была речь приведу небольшой пример по оптимизации этого кода:
Было: ...
Стало: ...
Это примерно 120байтов экономии только на одной функции smile.gif


Ради прикола взял два этих куска и откомпилил. То что было, переименовал в InvMixColumn2.
На IAR AVR с максимальной оптимизацией по скорости получил:
InvMixColumn2(unsigned char *) 320
InvMixColumn(unsigned char *) 332

Т.е., на 12 лишних байт вы соптимизировали smile.gif

Мораль сей басни - оптимизировать низкоуровневые вещи должен компилятор, ему то в 95% случаев надо эту оптимизацию и доверить...
Прикрепленные файлы
Прикрепленный файл  test.txt ( 24.39 килобайт ) Кол-во скачиваний: 157
 
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 19 2007, 08:01
Сообщение #44


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Непомнящий Евгений @ Oct 19 2007, 10:37) *
На IAR AVR с максимальной оптимизацией по скорости получил:

Попробуйте по размеру, думаю эффект будет побольше, даже для IAR.



Цитата(Непомнящий Евгений @ Oct 19 2007, 10:37) *
Мораль сей басни - оптимизировать низкоуровневые вещи должен компилятор, ему то в 95% случаев надо эту оптимизацию и доверить...

Не совcем так - при этом надо ему явно НЕ мешать, что встречается очень часто, особенно при портировании.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Oct 19 2007, 08:33
Сообщение #45


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Если максимальная оптимизация по размеру, то первый вариант весит 312 байт, второй - 192.
Тут действительно вылезают обещанные singlskv 120 байт.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 19 2007, 15:08
Сообщение #46


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(Непомнящий Евгений @ Oct 19 2007, 11:37) *
Т.е., на 12 лишних байт вы соптимизировали smile.gif
Мораль сей басни - оптимизировать низкоуровневые вещи должен компилятор, ему то в 95% случаев надо эту оптимизацию и доверить...

Цитата(Непомнящий Евгений @ Oct 19 2007, 12:33) *
Если максимальная оптимизация по размеру, то первый вариант весит 312 байт, второй - 192.
Тут действительно вылезают обещанные singlskv 120 байт.

А осадок то остался... © (не мой) smile.gif smile.gif

На самом деле в первом варианте "по скорости", IAR просто переклинило по какой-то только ему
ведомой причине.
Так иногда бывает с компиляторами. sad.gif
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 20 2007, 20:07
Сообщение #47


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(singlskv @ Oct 19 2007, 18:08) *
А осадок то остался... © (не мой) smile.gif smile.gif

На самом деле в первом варианте "по скорости", IAR просто переклинило по какой-то только ему
ведомой причине.
Так иногда бывает с компиляторами. sad.gif


По сравнению с вариантом от Сергей Борщ, любезно им предоставленном мне, проигрыш вашего варианта оптимизации на этой подпрограмме составил 26 байт. Хотя честно говоря я не понимаю почему. Я оптимизировал прерывания примерно вашим способом. Видимо знаний компилятора недостаточно.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 21 2007, 17:28
Сообщение #48


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(SasaVitebsk @ Oct 21 2007, 00:07) *
По сравнению с вариантом от Сергей Борщ, любезно им предоставленном мне, проигрыш вашего варианта оптимизации на этой подпрограмме составил 26 байт. Хотя честно говоря я не понимаю почему. Я оптимизировал прерывания примерно вашим способом. Видимо знаний компилятора недостаточно.
Мой вариант, это еще был не "мой" вариант, к реальной оптимизации я просто не приступал wink.gif
так, показал направление ....
Вам нравится IAR ?
Хорошо, будет для IAR:
Код
    143          
    144          __z void InvMixColumn1( byte * column ,byte bpoly_);
    145          

   \                                 In segment CODE, align 2, keep-with-next
    146          __z void InvMixColumn(byte *column)
   \                     InvMixColumn:
    147          {
    148             InvMixColumn1( column ,BPOLY);
   \   00000000   E10B               LDI     R16, 27
   \   00000002                      REQUIRE InvMixColumn1
   \   00000002                     ;               // Fall through to label InvMixColumn1
    149          }

   \                                 In segment CODE, align 2, keep-with-next
    150          __z void InvMixColumn1( byte * column ,byte bpoly)
   \                     InvMixColumn1:
    151          {
    152              byte r0, r1, r2, r3;
    153              byte co0 = column[0],co1=column[1],co2=column[2],co3=column[3];
   \   00000000   8110               LD      R17, Z
   \   00000002   8121               LDD     R18, Z+1
   \   00000004   8132               LDD     R19, Z+2
   \   00000006   8143               LDD     R20, Z+3
    154          byte tmp;
    155          
    156          r0 = co1 ^ co2 ^ co3;
   \   00000008   2F53               MOV     R21, R19
   \   0000000A   2752               EOR     R21, R18
   \   0000000C   2754               EOR     R21, R20
    157          r1 = co0 ^ co2 ^ co3;
   \   0000000E   2F63               MOV     R22, R19
   \   00000010   2761               EOR     R22, R17
   \   00000012   2764               EOR     R22, R20
    158          tmp = r0 ^ r1;
   \   00000014   2F76               MOV     R23, R22
   \   00000016   2775               EOR     R23, R21
    159          r2 = tmp ^ co3;
   \   00000018   2E04               MOV     R0, R20
   \   0000001A   2607               EOR     R0, R23
    160          r3 = tmp ^ co2;
   \   0000001C   2E13               MOV     R1, R19
   \   0000001E   ....               RCALL   ?Subroutine0
    161          
    162          co0 = (tmp=co0) << 1;
    163          if ((tmp & 0x80)==0x80) co0 ^= bpoly;
    164          co1 = (tmp=co1) << 1;
    165          if ((tmp & 0x80)==0x80) co1 ^= bpoly;
    166          co2 = (tmp=co2) << 1;
    167          if ((tmp & 0x80)==0x80) co2 ^= bpoly;
    168          co3 = (tmp=co3) << 1;
    169          if ((tmp & 0x80)==0x80) co3 ^= bpoly;
    170          
    171              r0 ^= co0 ^ co1;
   \                     ??CrossCallReturnLabel_0:
   \   00000020   2F72               MOV     R23, R18
   \   00000022   2771               EOR     R23, R17
   \   00000024   2757               EOR     R21, R23
    172              r1 ^= co1 ^ co2;
   \   00000026   2F73               MOV     R23, R19
   \   00000028   2772               EOR     R23, R18
   \   0000002A   2767               EOR     R22, R23
    173              r2 ^= co2 ^ co3;
   \   0000002C   2F74               MOV     R23, R20
   \   0000002E   2773               EOR     R23, R19
   \   00000030   2607               EOR     R0, R23
    174              r3 ^= co0 ^ co3;
   \   00000032   2F74               MOV     R23, R20
   \   00000034   2771               EOR     R23, R17
   \   00000036   ....               RCALL   ?Subroutine0
    175          
    176          co0 = (tmp=co0) << 1;
    177          if ((tmp & 0x80)==0x80) co0 ^= bpoly;
    178          co1 = (tmp=co1) << 1;
    179          if ((tmp & 0x80)==0x80) co1 ^= bpoly;
    180          co2 = (tmp=co2) << 1;
    181          if ((tmp & 0x80)==0x80) co2 ^= bpoly;
    182          co3 = (tmp=co3) << 1;
    183          if ((tmp & 0x80)==0x80) co3 ^= bpoly;
    184          
    185              r0 ^= co0 ^ co2;
   \                     ??CrossCallReturnLabel_1:
   \   00000038   2F73               MOV     R23, R19
   \   0000003A   2771               EOR     R23, R17
   \   0000003C   2757               EOR     R21, R23
    186              r1 ^= co1 ^ co3;
   \   0000003E   2F74               MOV     R23, R20
   \   00000040   2772               EOR     R23, R18
   \   00000042   2767               EOR     R22, R23
    187              r2 ^= co0 ^ co2;
   \   00000044   2F73               MOV     R23, R19
   \   00000046   2771               EOR     R23, R17
   \   00000048   2607               EOR     R0, R23
    188              r3 ^= co1 ^ co3;
   \   0000004A   2F74               MOV     R23, R20
   \   0000004C   2772               EOR     R23, R18
   \   0000004E   ....               RCALL   ?Subroutine0
    189                  
    190          co0 = (tmp=co0) << 1;
    191          if ((tmp & 0x80)==0x80) co0 ^= bpoly;
    192          co1 = (tmp=co1) << 1;
    193          if ((tmp & 0x80)==0x80) co1 ^= bpoly;
    194          co2 = (tmp=co2) << 1;
    195          if ((tmp & 0x80)==0x80) co2 ^= bpoly;
    196          co3 = (tmp=co3) << 1;
    197          if ((tmp & 0x80)==0x80) co3 ^= bpoly;
    198          
    199              tmp=co0 ^ co1 ^ co2 ^ co3;
   \                     ??CrossCallReturnLabel_2:
   \   00000050   2721               EOR     R18, R17
   \   00000052   2723               EOR     R18, R19
   \   00000054   2724               EOR     R18, R20
    200          
    201              column[0] = tmp ^ r0;
   \   00000056   2752               EOR     R21, R18
   \   00000058   8350               ST      Z, R21
    202              column[1] = tmp ^ r1;
   \   0000005A   2762               EOR     R22, R18
   \   0000005C   8361               STD     Z+1, R22
    203              column[2] = tmp ^ r2;
   \   0000005E   2602               EOR     R0, R18
   \   00000060   8202               STD     Z+2, R0
    204              column[3] = tmp ^ r3;
   \   00000062   2612               EOR     R1, R18
   \   00000064   8213               STD     Z+3, R1
    205          }
   \   00000066   9508               RET

   \                                 In segment CODE, align 2, keep-with-next
   \                     ?Subroutine0:
   \   00000000   2617               EOR     R1, R23
   \   00000002   2F71               MOV     R23, R17
   \   00000004   0F11               LSL     R17
   \   00000006   FB77               BST     R23, 7
   \   00000008   F40E               BRTC    ??Subroutine0_0
   \   0000000A   2710               EOR     R17, R16
   \                     ??Subroutine0_0:
   \   0000000C   2F72               MOV     R23, R18
   \   0000000E   0F22               LSL     R18
   \   00000010   FB77               BST     R23, 7
   \   00000012   F40E               BRTC    ??Subroutine0_1
   \   00000014   2720               EOR     R18, R16
   \                     ??Subroutine0_1:
   \   00000016   2F73               MOV     R23, R19
   \   00000018   0F33               LSL     R19
   \   0000001A   FB77               BST     R23, 7
   \   0000001C   F40E               BRTC    ??Subroutine0_2
   \   0000001E   2730               EOR     R19, R16
   \                     ??Subroutine0_2:
   \   00000020   2F74               MOV     R23, R20
   \   00000022   0F44               LSL     R20
   \   00000024   FB77               BST     R23, 7
   \   00000026   F40E               BRTC    ??Subroutine0_3
   \   00000028   2740               EOR     R20, R16
   \                     ??Subroutine0_3:
   \   0000002A   9508               RET
ИТОГО:
150 байтов программного кода (уже в 2 раза лучше чем оригинал wink.gif )

И если еще чуть напрячь мозг, то можно на 20-30 байт сократить...
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 22 2007, 10:43
Сообщение #49


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Внимательно просмотрю.
Правда я отказался на сегодняшний момент от ужатия, так как в угоду функциональности всётаки проект распух. sad.gif

Он уже работает.

С другой стороны, как я вижу, и как вы сами доказываете - вполне можно пользоваться любым инструментом. Надо просто его хорошо знать. Методы такого рода оптимизации основаны на знании как именно сам компилятор генерит код. С другой стороны, такая оптимизация достаточно зависима от компилятора.

Спасибо всем за помощь в реализации данного проекта. smile.gif
Go to the top of the page
 
+Quote Post
pvp
сообщение Oct 22 2007, 15:24
Сообщение #50


Участник
*

Группа: Новичок
Сообщений: 18
Регистрация: 16-02-07
Пользователь №: 25 414



Цитата(singlskv @ Oct 21 2007, 21:28) *
__z void InvMixColumn(...)

Поясните, пожалуйста, назначение "__z" (и источник информации) - в описании на компилятор 4.30A("Help>AVR>AVR C/C++ Compiler Reference Guide")не нашёл ничего подобного. Без использования "__z"код "прибавляет в весе" 4 байта.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 22 2007, 15:33
Сообщение #51


Гуру
******

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



Цитата(pvp @ Oct 22 2007, 18:24) *
Поясните, пожалуйста, назначение "__z" (и источник информации)
Было в каком-то из .html в папке документации. Указывает компилятору передавать первый указатель в регистровой паре Z. Встречается также в вариациях __x, __xz (если память не изменяет).


--------------------
На любой вопрос даю любой ответ
"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
singlskv
сообщение Oct 22 2007, 16:43
Сообщение #52


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(SasaVitebsk @ Oct 22 2007, 14:43) *
С другой стороны, как я вижу, и как вы сами доказываете - вполне можно пользоваться любым инструментом. Надо просто его хорошо знать. Методы такого рода оптимизации основаны на знании как именно сам компилятор генерит код. С другой стороны, такая оптимизация достаточно зависима от компилятора.
Эээ... попробую пояснить почему я Вас агитировал за Gcc.
Конечно у IAR оптимизатор написан чуть лучше чем у Gcc(в среднем), и на "плохом" коде
это всегда сказывается.
Дальше все зависит от конкретной задачки и от модели компиляции разными компиляторами.
У IAR AVR есть одно принципиальное отличие от других компиляторов,
он использует регистровую пару Y под стек и на этом очень часто превосходит
другие компиляторы, но, задачки то разные бывают...
Посмотрев исходники я увидел что в данной проге очень часто нужно >2 указателей одновременно.
Соответственно преимущество для таких задач будет иметь компилятор у которого больше
регистровых пар в распоряжении, а это Gcc а не IAR.
Просто посмотрите на листинги первоначального варианта кода и количество
использования в них инструкций типа mov X/Z, R(xx):R(xx+1) и mov R(xx):R(xx+1), X/Z
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 22 2007, 21:24
Сообщение #53


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



smile.gif
Я когда первый раз увидел результаты компилирования IAR, то тоже был немало удивлён наличием двух стеков. И первый вопрос - зачем! Чем не устраивает стандартный стэк? Зачем использовать такую дефицитную вещь как регистровая пара?

Внимательно рассматривая листинги - я понял. Именно при оптимизации по объёму такой подход даёт преимущество. При оптимизации по объёму появляется большое количество подпрограмм. При использовании второго стека можно делать подпрограммы сохранения регистров и восстановления. Есть и ещё ряд преимуществ. В частности возможность прямого обращения к данным в стэке. Например когда параметры находятся в стеке. Если использовать основной стек, то это более сложно получится.

Короче каждый подход имеет свои положительные стороны и свои отрицательные. Что очевидно.

К GCC претензий у меня нет и не может быть. Я не против данного компилятора. Просто работать с ним оказалось сложнее чем с IAR. Может быть когда-нибудь я его освою.
Go to the top of the page
 
+Quote Post
pvp
сообщение Oct 23 2007, 14:02
Сообщение #54


Участник
*

Группа: Новичок
Сообщений: 18
Регистрация: 16-02-07
Пользователь №: 25 414



Цитата(Сергей Борщ @ Oct 22 2007, 19:33) *
Было в каком-то из .html...

Спасибо за ответ. Найду и почитаю.
Go to the top of the page
 
+Quote Post
skripach
сообщение Nov 9 2009, 14:11
Сообщение #55


■ ■ ■ ■
*****

Группа: Свой
Сообщений: 1 100
Регистрация: 9-08-06
Пользователь №: 19 443



Не стал создавать новую тему, поэтому здесь.
Можно ли заставить работать(не получается пока) приложение скомпилированное с такими настройками линкера
Код
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000044;
define symbol __ICFEDIT_region_ROM_end__   = 0x0007FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x40000040;
define symbol __ICFEDIT_region_RAM_end__   = 0x4000FFFF;

если расположить его по адресу скажем 0х1000?
Скопировал вектора, сделал ремап, передал управление на 0-вой адрес. Переходит разумеется не туда...
Если я к тому что лежит с 0х40000020-го адреса прибавляю число 0х1000 то после сброса переходит туда куда надо biggrin.gif но приложение всё равно не работает.


--------------------
Делай что должен и будь что будет.
Go to the top of the page
 
+Quote Post
skripach
сообщение Nov 12 2009, 07:30
Сообщение #56


■ ■ ■ ■
*****

Группа: Свой
Сообщений: 1 100
Регистрация: 9-08-06
Пользователь №: 19 443



Что никто не знает? ...или я что-то не то спросил.


--------------------
Делай что должен и будь что будет.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Nov 12 2009, 09:39
Сообщение #57


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(skripach @ Nov 12 2009, 10:30) *
Что никто не знает? ...или я что-то не то спросил.

Нет желания разгадывать шарады.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
KSN
сообщение Feb 27 2010, 09:55
Сообщение #58


Местный
***

Группа: Свой
Сообщений: 404
Регистрация: 3-12-04
Из: Новосибирск
Пользователь №: 1 304



Есть вопрос по прерываниям в bootloader и application. Итак, контроллер atmega8. Карта памяти:
0x0000 - 0x13FF: Application
0x1400 -0x17FF: Common memory (здесь храняться общие функции, доступные из application & bootloader)
0x1800 - 0x1FFF: Bootloader.
В bootloader используется одно прерывание от таймера2 по сравнению.
Контроллер программируется Avreal и стартует с Bootloader, проверяется CRC, если все ок, то переход на application. Также есть возможность запуска bootloader из application.
Итак, программирую контроллер только прошивкой загрузчика: все хорошо, прерывание работает.
Теперь, программирую контроллер с общей прошивкой (приложение+загрузчик): загрузчик запускается, отрабатывает и передает управление приложению. Затем из приложения вызываю загрузчик и вижу, что прерывание не работает. В загрузчике и приложении использую разные low_level_init, причем в загрузчике устанавливаю IVSEL, а в приложении сбрасываю. Может у кого было подобное?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 27 2010, 11:39
Сообщение #59


Гуру
******

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



Цитата(KSN @ Feb 27 2010, 11:55) *
Может у кого было подобное?
Нет, не было. Прекрасно работают прерывания и там и там. Можете прислать проект на serzh собака rrt.lv, посмотрю.


--------------------
На любой вопрос даю любой ответ
"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
zltigo
сообщение Feb 28 2010, 20:09
Сообщение #60


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(KSN @ Feb 28 2010, 20:56) *
Отправил повторно.....

Moderator:
Для обильной личной переписки существует служба личных сообщений. Заодно напоминаю, что кросспосты на форуме запрещены.
Личная переписка удалена.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

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

 


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


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