Самопрограммирование (STM32)


Представим, что имеется большая интерфейсная линия, на которой размещено несколько десятков устройств. Управляет ими один мастер.
И вдруг, понадобилось обновить прошивку.
Ситуация не радостная. Мало того, что они удалены друг от друга, так еще и программатор с ноутбуком подключать к каждому персонально…
Вот и придумали для похожих задач самопрограммирование.
Идея такова:
Программа состоит из двух частей. Загрузчика и программы основной.
Загрузчик проверяет команду от Мастера для входа в режим программирования.
Если ничего нет — передает управление основной программе.
Основная программа кроме своих задач, должна следить за появлением все той же команды начала программирования.
И если такая появится, произвести Сброс. После чего управление вновь окажется у загрузчика.
Он примет байты данных, проверит контрольную сумму чтобы не накосячить, и запишет все по порядку во FLASH.

Загрузчик обязательно должен начинаться с 0x80000000 адреса, иначе старта не будет.

Основная программа может начинаться с любого адреса, в пределах 0x80000000-0x8001FFFF.
А чтобы она случайно не пересеклась с загрузчиком, для нее нужно выбрать место.
Проще это сделать, задав соответствующие значения в Keil-е или Coocox.
Адреса прекрасно отображаются в отладчике.
Но нельзя просто перейти на первый попавший.
Заглянем с файл .map.
Там будет строка примерно такого содержания — «Reset_Handler 0x08001421 Thumb Code»
Значит переходить нужно на 0x08001421.
Адрес Reset_handler — остается неизменным.
И не забыть переопределить вектора прерываний.
(NOP-ы здесь только для демонстрации, они не нужны вовсе как и функция Work)

SCB->VTOR = (((uint32_t)0x08000800)); // Переопределить вектора
.................................
typedef void (*pFunction)(void); // Объявляем функцию перехода
...........................................
((pFunction) 0x08001421)(); // Переход на 0x08001421
.......................................
void work(void){ // Функция с пустыми NOP-ами
__ASM("NOP");__ASM("NOP");__ASM("NOP");__ASM("NOP");__ASM("NOP");__ASM("NOP");__ASM("NOP");__ASM("NOP");__ASM("NOP");__ASM("NOP");__ASM("NOP");__ASM("NOP");__ASM("NOP");__ASM("NOP");
HEX файл передается построчно:
:101800009008002001190008091900080B190008A8
где ":«начало строки.
»10" — длина данных (16).
"1800" адрес куда записывать первый байт данных из строки (последующие байты записываются на +1).
"00" запись.
"9008002001190008091900080B190008" — 16 байт данных.
"A8" Оканчивается каждая строка байтом контрольной суммы.
Считается легко. Если просуммировать все байты (контрольной суммы тоже), результат по модулю будет равен 00.
В моем проекте проверка КС происходит сразу после приема, в буфере uint8_t baits[21],
потом данные перебрасываются в uint8_t BUFFER_data[315][21].

Примеры.
read:
while(Rec_Flag==0){}; // Ждем данных
Receive_UDR(); // Прием
Rec_Flag=0;
if (Receive_DATA[0]==':')
temp = check_sum(Konvert_ascii_leng()); // Проверка КС
if(temp==0)
{
Bait_to_FLASH_data(couBaits_toFLASH); Переброс в BUFFER_data[315][21];
couBaits_toFLASH++; // Общий счетчик принятых строк
temp = Konvert_ascii_leng(); // Определяем длину данных
temp2 = konver_ascii_address(); // Адрес
Receive_dat_clear();
Rec_Flag=0;
Transmit_UDR("Ok", 20); // Отчитатся о удачно принятой строке
goto read; // Снова, пока не поступит команда окончания
}
else (если начало не ":" проверяем на условие, переходим в записи)
uint8_t check_sum (uint8_t leng){
uint8_t temp3 = 0;
uint8_t cou = 0;
uint8_t temp4 = 0;
uint16_t sym = 0;
uint8_t count = 0;
temp4 = leng ;
leng = leng *2;
leng = leng + 10;
for(cou=0;cou<leng; cou=cou+2)
{
temp3 = Konvert_all(cou);
baits[count] = temp3;
sym=sym+temp3;
count++;
}
leng = temp4;
leng = leng +6;
for(temp4=temp4; temp4<15; temp4++)
{
baits[leng++]=0xFF;
}
return sym;
}
uint8_t Konvert_ascii_leng(){
uint8_t template2;
uint8_t templat;
for(temp=0; temp<2; temp++)
{
switch(Receive_DATA[temp+1])
{
case 'F': templat= 0x0F; break;
case 'E': templat= 0x0E; break;
case 'D': templat= 0x0D; break;
case 'C': templat= 0x0C; break;
case 'B': templat= 0x0B; break;
case 'A': templat= 0x0A; break;
case '9': templat= 0x09; break;
case '8': templat= 0x08; break;
case '7': templat= 0x07; break;
case '6': templat= 0x06; break;
case '5': templat= 0x05; break;
case '4': templat= 0x04; break;
case '3': templat= 0x03; break;
case '2': templat= 0x02; break;
case '1': templat= 0x01; break;
case '0': templat= 0x00; break;
default : templat= 0x0F; break;
} template2 = template2 <<4;
template2 |= templat;
}
return template2;
}
Стирание FLASH
void FLASH_errase_Page(uint32_t address_start)
{
flash_unlock();
FLASH->CR = FLASH_CR_PER;
FLASH->AR = address_start;
FLASH->CR|= FLASH_CR_STRT;
while ((FLASH->SR & FLASH_SR_BSY) != 0 );
FLASH->CR = FLASH_CR_LOCK;
}
void flash_unlock(void) {
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;
}
И сама запись
void Write_FLASH(){
uint32_t address =0;
uint32_t address2 =0;
int long numstring = 0;
uint8_t temp3 = 0;
uint8_t temp4 = 0;
uint32_t data = 0;
int long line =0;
uint8_t temp5 = 0;
uint32_t temp6;
FLASH_errase();
for(temp3=0; temp3<couBaits_toFLASH; temp3++)
{
flash_unlock();
FLASH->CR |= FLASH_CR_PG; //Разрешаем программирование флеша
address=0;
temp6=0;
address = BUFFER_data[line][1];
temp6 = address;
address = BUFFER_data[line][2];
temp6 = temp6 << 8;
address |= temp6 ;
temp6 = 0x8001800;
temp6&=~0x00FFFFF;
address |= temp6;
for(temp4=0;temp4<16; temp4=temp4+4)
{
data = 0;
data |= (BUFFER_data[line][temp4+7]) ; data = data <<8;
data |= (BUFFER_data[line][temp4+6] ); data = data <<8;
data |= (BUFFER_data[line][temp4+5] ); data = data <<8;
data |= (BUFFER_data[line][temp4 + 4] );
while ((FLASH->SR & FLASH_SR_BSY) != 0 );
*(__IO uint16_t*)address = (uint16_t)data; //младшие 2 байта
while ((FLASH->SR & FLASH_SR_BSY) != 0 );
address+=2;
data>>=16;
*(__IO uint16_t*)address = (uint16_t)data; //старшие 2 байта
while ((FLASH->SR & FLASH_SR_BSY) != 0 );
address+=2;
}
data = 0;
FLASH->CR &= ~(FLASH_CR_PG); //Запрет программирования
line++;
}
}
Затем написал простенькую программу, которая просто отсылает HEX по строкам и следит за ответами.

Единственное неудобство в том, что проектов должно быть двое…
- +6
- 06 июля 2013, 11:23
- khomin
- 1
Файлы в топике:
boot.zip
Маленькая рекомендация. Что бы на такое объявление среагировал кто-то кроме ниираспила следует код оформлять чуть более качественно. гуглтранслейт забанен только в ниираспил, остальные компании могут его себе позволить. А наблюдать в одном коде konver_ascii_addres и address тем более странно. Помните — объявление/резюме — это ваше лицо. К ним надо подходить серьезно. Оформите «коекак» и получите «коекак».
P.S.: А я вот постоянно по-русски пишу «буффер» :)
P.S.: А я вот постоянно по-русски пишу «буффер» :)
for(temp=0; temp<2; temp++)
тоже прикольно — как известно i,j,k перекочевали в Си из бейсика, в который они попали видимо из фортрана, в который они попали видимо из классических математических формул с Σ.
Видел как-то давно такой юмор:
int foo(ping) {
…
return pong;
}
тоже прикольно — как известно i,j,k перекочевали в Си из бейсика, в который они попали видимо из фортрана, в который они попали видимо из классических математических формул с Σ.
Видел как-то давно такой юмор:
int foo(ping) {
…
return pong;
}
- well-man2000
- 07 июля 2013, 12:17
- ↑
- ↓
35 т.р. в Москве? Не малоли?
В Чебоксарах (Чувашляндия) средняя З.П. 15 т.р. — которая ни на чё не хватает.
В Чебоксарах (Чувашляндия) средняя З.П. 15 т.р. — которая ни на чё не хватает.
Очевидно человек уже работает в обороннии, там з/п у сотрудников ниже рыночных в разы. Человек просто не знает, что можно зарабатывать больше, правда следовало бы немного подучится. будучи ещё в том нии.
А что такого — 35 тыр. для москвы это нищенская з/п. Челу как я понял 23 года, и видимо вышки нет, электронику/MCU за год/полтора изучил по EE и инету — вполне скромно себя ведет, начиная с 35 тыр. Только вот как раз в профильной оборонке/нии старой формации ему как раз и не помешало бы подучиться годика 2-3. У барыг/ИП, где такие же самоучки или бывшие студенты — его уже ничему не научат.
- well-man2000
- 06 июля 2013, 17:28
- ↑
- ↓
Знали бы вы его текущую зарплату, сказали бы: «биги оттуда срочно!»
В этих нии нельзя задерживаться на долго — сгниёшь и никуда больше не уйдешь. Так что ни о каких 2-х годах, а тем более трех не может быть и речи. У тех же барыг он будет получать отдачу гораздо быстрее, что будет способствовать обучению. В ниишке ему надо только освоить всякие госты и организацию работы (отчеты, служебки,...), самому же разработку там не освоить — нечего и задерживаться.
В этих нии нельзя задерживаться на долго — сгниёшь и никуда больше не уйдешь. Так что ни о каких 2-х годах, а тем более трех не может быть и речи. У тех же барыг он будет получать отдачу гораздо быстрее, что будет способствовать обучению. В ниишке ему надо только освоить всякие госты и организацию работы (отчеты, служебки,...), самому же разработку там не освоить — нечего и задерживаться.
Я же не знаю про какое нии там идет речь, в нии можно и сисадмином и техником паялой работать, но можно и аспирантом быть на нищенской з/п, но с интересной темой и с неплохой техн.базой, которой у барыг просто нет или она им не нужна.
- well-man2000
- 06 июля 2013, 19:18
- ↑
- ↓
Сам постоянно себя убеждаю в том, что надо бежать из НИИ, но куда? К дяде? Может тогда лучше свое дело организовать?
надо бежать из НИИ, но куда?Куда, куда — естественно в Тексас Инструментс! Там такая же тупая работа инженеришкой с 8-00 до 17-00, но оклады больше.
Я вот более приземленными проблемами занят — как научиться/стать гениальным(ну хотя бы талантливым) инженером или хотя бы искусным и сверхпродуктивным мега
- well-man2000
- 07 июля 2013, 10:15
- ↑
- ↓
я бы и рад в тексас, но это же не так просто…Вот что говорит Джо Фрейзер — он не разбогател в итоге, как некоторые, но был и остался настоящим простым мужиком(солью земли).
- well-man2000
- 07 июля 2013, 10:53
- ↑
- ↓
так с нее и питается до сих порЛинукс, насколько мне известно, программа бесплатная, с чего ему питаться?
Линус конечно лох в этом смысле — ему очень далеко до Билла или Стива, но ему и ничего больше и не надо видимо: домик, пара мерсов есть и 10-15 тыр баксов ежемесячно с конца 90-х. Точно не знаю механизмов, но западное об-во его как-то гуманитарно содержит — это же не россия.
- well-man2000
- 07 июля 2013, 13:14
- ↑
- ↓
Это, кстати, не так уж много, для людей такого калибра. Я не сильно удивлюсь, если окажется сумма раза в два-два с половиной больше.Ну я тоже так и думал, просто указал сумму по минимуму, учитывая, что он вроде не помешанный на бабках чел, и 10-15 тыр.я думаю с лихвою хватает его семье для нормального существования. Кстати в док.фильме 2001 года «The Code (Linux)» он уже гоняет на BMW, которую в штатах может себе позволить любой, кто имеет >=5 тыр.$ в месяц.
- well-man2000
- 07 июля 2013, 16:31
- ↑
- ↓
То, что софт раздается бесплатно вовсе не значит, что за его разработку не платят. Один из вариантов — допиливание имеющейся софтины для решения конкретных задач. Раз заказчику это нужно, он и платит за разработку. А поскольку это опенсорс, то результатом потом пользуются все. Другой вариант — какая-нибудь контора для решения своих задач пишет софтину, а поскольку продажа софта не ее бизнес, то готовую софтину выкладывает в виде опенсорс. Самой конторе это выгодно, поскольку сильно снижает затраты на дальнейшее сопровождение и развитие софтины. Ну и имидж, естественно. А имидж это новые клиенты и бабло от основного бизнеса.
Да, кстати, забыл еще о таком замечательном варианте, как борьба с конкурентами с помощью открытых технологий. Например андроид. Да и линукс в этом качестве тоже использовался. В обоих случаях удалось выпинать с рынков, где, казалось, они давно и прочно окопались. Естественно, что это не могло произойти без вложения бабла в разработку, причем изрядного.
Линукс, насколько мне известно, программа бесплатная, с чего ему питаться?
Linux — как раз хороший пример, что на open source можно зарабатывать. Посмотрите например на Linux Foundation (там есть информация о членах и ежегодных взносах). И это только один из источников дохода, evsi привел множество других. Помимо этого, корпорации спонсируют ядро не только деньгами, но и кодом, отдавая свои наработки сообществу.
Такие люди как Линус для меня просто загадочный пример уникальных возможностей человеческого мозга в сфере кодинга, но еще больше трудолюбия. Для меня ясно, что он бывший студент, т.е. был типичным говнокодером года 2-3, т.е. говнокодером тактическим(на уровне самого кода). Потом еще года 2-3 он уже побыл говнокодером стратегическим, т.е. уже на уровне самого проекта и его структуры. И наконец стал гуру.
Великий RMS, как говорят, был когда-то заурядным паскалюгой и не смог пройти собеседование в Microsoft. И он явно перемудрил со своей ОС GNU и сам в итоге запутался в ней(горе от ума), хотя возможно что очень много усилий он направил на GCC и другие программы для GNU, но студент Линус в это время неутомимо, обильно и монолитно говнокодил свой Linux и к большому удивлению даже для себя — его проект достиг известности и был успешен почти с самого начала.
В связи с этим очень интересны особенности мозга, характера и главное воспитания Линуса. Просто уникальные возможности в подъеме в одиночку кода, просто фантастического по своей массе(вначале десятки, а потом сотни тысяч строк), и доведения его до какого-то окончательного и вполне надежно работающего состояния, что просто не посильно огромному большинству других кодеров и говнокодеров. Здесь надо еще учесть такой человеческий феномен, что чем более опытным становится кодер — тем меньше он обычно пишет, т.е. ему просто становится лень, он наглеет/толстеет/буреет с точки зрения радотодателя или становится не пишущим гуру.
Великий RMS, как говорят, был когда-то заурядным паскалюгой и не смог пройти собеседование в Microsoft. И он явно перемудрил со своей ОС GNU и сам в итоге запутался в ней(горе от ума), хотя возможно что очень много усилий он направил на GCC и другие программы для GNU, но студент Линус в это время неутомимо, обильно и монолитно говнокодил свой Linux и к большому удивлению даже для себя — его проект достиг известности и был успешен почти с самого начала.
В связи с этим очень интересны особенности мозга, характера и главное воспитания Линуса. Просто уникальные возможности в подъеме в одиночку кода, просто фантастического по своей массе(вначале десятки, а потом сотни тысяч строк), и доведения его до какого-то окончательного и вполне надежно работающего состояния, что просто не посильно огромному большинству других кодеров и говнокодеров. Здесь надо еще учесть такой человеческий феномен, что чем более опытным становится кодер — тем меньше он обычно пишет, т.е. ему просто становится лень, он наглеет/толстеет/буреет с точки зрения радотодателя или становится не пишущим гуру.
- well-man2000
- 10 июля 2013, 10:30
- ↑
- ↓
… чем более опытным становится кодер — тем меньше он обычно пишет <...> становится не пишущим гуру.Такой уровень называется system architect — системный архитектор, нечто вроде генерального конструктора. И дело здесь не в лени, такая должность неизбежно появляется в больших проектах.
Другие аналогии — это режиссёр, или дирижёр, или спортивный тренер. Они не играют сами, но знают, как должны играть другие. Впрочем, Торвальдс — играющий тренер.
Само ядро Windows NT тоже практически в одиночку написано вот этим мега-челом. Возможно потому, что период говнокодера он прошел еще в 70-х, тем более ему было у кого учиться — он работал в DEC.
Есть мнение, что system architect — это просто обычный паразит и даже вредитель. Каких я видел в россии — это или говнокодер, быстро пролезжий по карьерной лестнице; бывший студент начитавшийся умных книжек — псевдо-гуру, но весьма активный и с хорошо подвешенным языком или просто идиот со связями/блатом/родственниками. Т.е. типичный нач.отдела, зам или директор в любой отраслинародного барыжного/бюрократического хоз-ва россии.
Есть мнение, что system architect — это просто обычный паразит и даже вредитель. Каких я видел в россии — это или говнокодер, быстро пролезжий по карьерной лестнице; бывший студент начитавшийся умных книжек — псевдо-гуру, но весьма активный и с хорошо подвешенным языком или просто идиот со связями/блатом/родственниками. Т.е. типичный нач.отдела, зам или директор в любой отрасли
- well-man2000
- 10 июля 2013, 11:51
- ↑
- ↓
Есть мнение, что system architect — это просто обычный паразит и даже вредитель.В любой работе есть люди делающие ее хорошо и есть люди делающие ее плохо.
P.S. меня чуть ли не силком выпихнули на позицию системного архитектора с позиции обычного синьора (даже не тимлида). просто я оказался самым опытным и единственным способным тянуть эту работу. и да, периодически я все еще пишу код сам, когда у меня остается на это время, учитывая, что на мне висят несколько проектов.
Военно-историческая новелла на близкую тему:
«Трассировка и раскладка кабелей на компьютере».
«Трассировка и раскладка кабелей на компьютере».
Интересно, что в 1992 г. в споре с Линусом сторонник микроядра проф. Таненбаум говорит что:
через 5 лет все будут пользоваться свободной GNU на компьютерах SPARCstation-5 мощностью 200 MIPS с памятью 64 мегабайтвместо «тупиковой» Linux, жестко привязанной тогда к i386, т.е. он реально расчитывал на портируемое микроядро ОС GNU от Столмена.
- well-man2000
- 10 июля 2013, 19:39
- ↑
- ↓
Сложно что-то конкретное процетировать или предложить, по этому ограничусь следующим.
Проще это сделать, если создать функцию с пустыми командами.Проче и недопустимее. Посмотрите аппноуты от производителя как создавать загрузчики и прошивки прогграмм ориентированные на работу с загрузчиком. Для этих целей применяется линкер (для стм8 я описывал как делать, и загрузчик в том числе). С его помощью можно настроить адреса (области для загрузчика и для кода), и тогда у вас будет возможность применить ещё и предусмотренный в МК механизм защиты загрузчика.
Не жирно ли хекс передавать их хранить? Оперативка не бесконечная =) *тем более 300 строк — ни о чём*
А ещё не проверяется couBaits_toFLASH (с ответом мастеру), переполнение буфера можно ждать, если прошивка будет иметь более 315 строк.
И я вижу нехороший косяк — если хоть одна строка хекса не дойдёт, а команда на прошивку «Wr_to_F_end» придёт, основную прошивку вы убьёте. И дальше я вижу кусок металлолома вместо прибора. А не дойти оно может запросто, это ж Ethernet и UDP. Контрольную сумму нужно проверять и дополнительно после приёма всех кусков прошивки, от целого файла, вне зависимости от того, какие команды идут от мастера! Если кто-то по дурости или случайно пришлёт эту команду и если прошивки готовой нет в буфере, надо слать нафиг мастера.
И по поводу архивов — лучше, если все генерируемые компилятором файлы будут удалены, может, кроме прошивки =) Ну и валятся в отдельную папочку, а не к исходникам…
s019.radikal.ru/i614/1307/7e/2ffb421ee9c3.png — код и должен так гулять?=)
А ещё не проверяется couBaits_toFLASH (с ответом мастеру), переполнение буфера можно ждать, если прошивка будет иметь более 315 строк.
И я вижу нехороший косяк — если хоть одна строка хекса не дойдёт, а команда на прошивку «Wr_to_F_end» придёт, основную прошивку вы убьёте. И дальше я вижу кусок металлолома вместо прибора. А не дойти оно может запросто, это ж Ethernet и UDP. Контрольную сумму нужно проверять и дополнительно после приёма всех кусков прошивки, от целого файла, вне зависимости от того, какие команды идут от мастера! Если кто-то по дурости или случайно пришлёт эту команду и если прошивки готовой нет в буфере, надо слать нафиг мастера.
И по поводу архивов — лучше, если все генерируемые компилятором файлы будут удалены, может, кроме прошивки =) Ну и валятся в отдельную папочку, а не к исходникам…
s019.radikal.ru/i614/1307/7e/2ffb421ee9c3.png — код и должен так гулять?=)
- teplofizik
- 06 июля 2013, 15:58
- ↓
Друзья-товарищи :)
Касательно-названий адресов, уж простите меня :)
Только вот вот отучился от транслита в названиях.
Учту и в следующий раз буду пользовать GoogleTranslate.
Вышка есть, но совсем не московская. С преподами далекими от своих специализаций.
Любую критику приветствую.
35 т.р. потому, что Москве совсем недавно…
Касательно-названий адресов, уж простите меня :)
Только вот вот отучился от транслита в названиях.
Учту и в следующий раз буду пользовать GoogleTranslate.
Вышка есть, но совсем не московская. С преподами далекими от своих специализаций.
Любую критику приветствую.
35 т.р. потому, что Москве совсем недавно…
Иди к барыгам в ремонтники, они тебя научат не бояться тонких электронных технологий. Можно зашибать хорошие деньги.
- well-man2000
- 07 июля 2013, 11:29
- ↑
- ↓
хочу пока сделать так: стартую в бутлоадер (в нем ничего не делаю ) дале просто переключаюсь в основную программу.
бутлоадер
в линкере ROM star: 0x08000000.
в линкере ROM star: 0x0800F000
В итоге if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000) попадаю в while ( Помогите разобраться
бутлоадер
в линкере ROM star: 0x08000000.
int main(void)
{ .....
#define ApplicationAddress 0x0800f5f1 //адрес Reset_Handler смотрю в .map основной программы
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
uint32_t JumpAddress;
if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
{
JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
Jump_To_Application = (pFunction) JumpAddress;
__set_MSP(*(__IO uint32_t*) ApplicationAddress);
Jump_To_Application();
}
while (1)
{
GPIO_SetBits(GPIOC, GPIO_Pin_8);
Delay(0x7FFFF);
GPIO_ResetBits(GPIOC, GPIO_Pin_8);
Delay(0x7FFFF);
}
}
основная программа:в линкере ROM star: 0x0800F000
int main(void)
{
__disable_interrupt();
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0xf5f1);
.....
while (1)
{
GPIO_SetBits(GPIOC, GPIO_Pin_9);
Delay(0x7FFFF);
GPIO_ResetBits(GPIOC, GPIO_Pin_9);
Delay(0x7FFFF);
}
}
В итоге if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000) попадаю в while ( Помогите разобраться
А чего ты еще ожидал? Сам посмотри, что получается при операции 0x0800f5f1 & 0x2FFE0000.
Ну и опять же, подставлять в бутлоадер адрес из линкера — не лучшая идея. Потом ты обновишь основную прошивку, в ней новый адрес точки входа… А в бутлоадере забит хардкодом старый, и что делать?
Обычно задача решается расположением в фиксированном месте основной прошивки таблицы векторов, из которой бутлоадером вызывается нужный вектор (в простейшем случае только один — точка входа, но при желании их может быть и больше).
Ну и опять же, подставлять в бутлоадер адрес из линкера — не лучшая идея. Потом ты обновишь основную прошивку, в ней новый адрес точки входа… А в бутлоадере забит хардкодом старый, и что делать?
Обычно задача решается расположением в фиксированном месте основной прошивки таблицы векторов, из которой бутлоадером вызывается нужный вектор (в простейшем случае только один — точка входа, но при желании их может быть и больше).
Спасибо.
Я же не так делаю 0x0800f5f1 & 0x2FFE0000, а беру значание по адресу ApplicationAddress & 0x2FFE0000
Проверяем, есть ли что-нибудь по адресу там должно лежать значение SP для приложения, его кладет линкер.
bootloader project.rar
Я же не так делаю 0x0800f5f1 & 0x2FFE0000, а беру значание по адресу ApplicationAddress & 0x2FFE0000
Проверяем, есть ли что-нибудь по адресу там должно лежать значение SP для приложения, его кладет линкер.
bootloader project.rar
Я же не так делаю 0x0800f5f1 & 0x2FFE0000, а беру значание по адресу ApplicationAddress & 0x2FFE0000Тьфу ты, действительно. Запутался в обилии скобок и звездочек.
А таблица векторов и Reset_Handler располагаются в разных адресах, вы же адрес стека пытаетесь найти этим хитрым способом?
*я не очень въехал в эти конструкции*
*я не очень въехал в эти конструкции*
- teplofizik
- 08 июля 2013, 12:58
- ↑
- ↓
Я бы не полагался на адреса из линкера. Лучше поместить таблицу векторов, вызываемых бутлоадером, по фиксированному адресу и проверять ее наличие (можно по magic-полю). Можно в качестве оной использовать таблицу векторов прерываний, опять же разместив ее по фиксированному адресу — проверять ее наличие и прыгать на RESET, а дальше прошивка сама переключит прерывания на эту таблицу.
Понятия не имею. Можно посмотреть, как сделано у других, в стартап-файлах (собсна, именно их скорее всего и потребуется править) и примерах самого кейла, а также покурить документацию. Для задания абсолютного адреса объекта обычно используется директива с названием в духе origin (бывают и сокращения вроде org, в Delphi аналогичная директива называется absolute).
Ну а вся программа в сборе размещается по адресам выше секции бутлоадера с помощью настроек линкера.
А вообще желательно посмотреть готовые примеры для конкретной среды и чипа — в примерах от среды, от производителя чипа, а также в аппнотах.
Ну а вся программа в сборе размещается по адресам выше секции бутлоадера с помощью настроек линкера.
А вообще желательно посмотреть готовые примеры для конкретной среды и чипа — в примерах от среды, от производителя чипа, а также в аппнотах.
В Кейле можно определить регионы памяти в свойствах проекта или в спец.файле, и в свойствах каждого файла выбирать, в коем регионе код будет располагаться (так и в оперативку код запихать можно, просто указав, что пихаем его в IRAM).
- teplofizik
- 09 июля 2013, 02:53
- ↑
- ↓
Комментарии (60)
RSS свернуть / развернуть