St_vladm 0 4 июня, 2014 Опубликовано 4 июня, 2014 · Жалоба А проблема вот какая, когда ОТП-лайк прога в флэшн - её стандартный адрес BEGIN=0x38fff6, но кактолько она скача саму фирмвалю и написала то в BEGIN переписался тоже алрес старта, и разумеется наша ОТП-лайк прога уде ни когда не стартанет. В общем я не нашел и не придумал как это обойти (единственное было с мыслях парсить весь стрим и найдя этот пдоес тупо его игнорить и перехватывать для записи в другое место) У меня весь стрим принимается по 2 байта и также и пишется сразу же по 1 слову. (Про эту находку я писал ранее) Что-то я не понял последовательность в Вашем описании. У меня в cmd-файле для таких кусков записано неcколько описаний секций вроде этого: .text : LOAD = FLASHH, PAGE = 0 RUN = RAML0, PAGE = 0 LOAD_START(WriterCodeLoad), LOAD_SIZE(WriterCodeSize), RUN_START(WriterCodeStart) После старта мой загрузчик переписывает эти куски из FLASH в ОЗУ (memcpy, как в примере с FlashAPI) и передает туда управление. Эти куски, записанные в FLASH, из самого FLASH работать не могут, ибо содержат заведомо не те адреса, где лежат, а заточены под ОЗУ. CCS3 не использую, меня от него коробит, кашмарный софт, не удобный ни разу. Но возможно таки прийдется тоже под него проект сделать. Мне приходится работать именно с CCS3, ибо код основной (рабочей) части весь на ассемблере - реал-тайм приложение, управляющее через PWM силовыми ключами. На С слишком много накладных расходов, не хватает тактов, да и бороться с излишней "оптимизацией" кода не очень приятно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TSS 0 4 июня, 2014 Опубликовано 4 июня, 2014 · Жалоба CCS3 не использую, меня от него коробит, кашмарный софт, не удобный ни разу. Но возможно таки прийдется тоже под него проект сделать. Третий имеет конечно свои недостатки, но именно в одном он круче и четвёртого, и пятого: он может считать прошивку из разлоченного проца, без отдельных ухищрений вне среды разработки. Проект для этого создавать не надо. Я тоже его для этой цели одно время держал на винчестере. :) Мне приходится работать именно с CCS3, ибо код основной (рабочей) части весь на ассемблере - реал-тайм приложение, управляющее через PWM силовыми ключами. На С слишком много накладных расходов, не хватает тактов, да и бороться с излишней "оптимизацией" кода не очень приятно. Простите, а как связано написание основных функций на ассемблере и версия CCS? Пишу свои функции на асме в 5.5 совершенно спокойно. Оптимизация вообще работать не мешает, с этим в CGTools С2000 всегда всё в порядке было. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
St_vladm 0 5 июня, 2014 Опубликовано 5 июня, 2014 · Жалоба Простите, а как связано написание основных функций на ассемблере и версия CCS? Сейчас уже точно не помню, где именно, но когда попробовал в CCS5 поработать с asm-проектом, показалось очень неудобно. Дело привычки, наверное. Хотя :bb-offtopic: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prst 0 7 июня, 2014 Опубликовано 7 июня, 2014 · Жалоба Не совсем понял, что Вы хотели этим сказать. Что адрес старта процессора всё время меняется? У меня 2 уровня, Первый сам OTP, который грузит в ОЗУ вторую, промежуточную прогу, Второй - грузит фирмварю, вторая кстати и записывает её в флеш через флэшАпи. Так вот там адрес точки входа то может меняться, не исключено, ибо она а ОЗУ а а будущем неизвестно как всё повернется. Так это не так, Вы сами задаёте этот адрес. Если Вы посмотрите мой проект для загрузчика и загружаемой программы (файлы .cmd), то найдёте, что там описывается кусок флэша с названием BEGIN на который ложится секция codestart. В секции codestart располагается асмовская инструкция перехода на _c_int00 (), т.е. на функцию main (см. DSP281x_CodeStartBranch.asm) code_start: .if WD_DISABLE == 1 LB wd_disable ;Branch to watchdog disable code .else LB _c_int00 ;Branch to start of boot.asm in RTS library .endif Таким образом, не смотря на то что адрес main (_с_int00) может меняться, адрес перехода на _c_int00 всегда остаётся постоянным, и вы его сами задаёте, можете BEGIN положить по любому адресу, который Вам нравится. да, я знаю, я так пробовал, распалогал по адресу 0x8000 и от туда успешно грузился способом как вы написали ниже. Но как я уже писал адрес точки схода может поменяться. А как Вы до этого осуществляли переход? Всё просто, одна инструкция: __inline void GotoLoadedProgram(){ asm(" LB 0x3DA000"); } __inline void GotoBootLoader(){ asm(" LB 0x3F7FF6"); } Тут только константой задается, если передать вместо 0x3F7FF6 например _var_addr где будет храниться значение адреса, то по факту будет переход по адресу той самой переменной var_addr, а это точно не то, что мне нужно Что-то я не понял последовательность в Вашем описании. У меня в cmd-файле для таких кусков записано неcколько описаний секций вроде этого: .text : LOAD = FLASHH, PAGE = 0 RUN = RAML0, PAGE = 0 LOAD_START(WriterCodeLoad), LOAD_SIZE(WriterCodeSize), RUN_START(WriterCodeStart) После старта мой загрузчик переписывает эти куски из FLASH в ОЗУ (memcpy, как в примере с FlashAPI) и передает туда управление. Эти куски, записанные в FLASH, из самого FLASH работать не могут, ибо содержат заведомо не те адреса, где лежат, а заточены под ОЗУ. Если честно я не понял как оно у вас так работает. То что вы описали это классический подход к приложению в флеше. Ведь по идее точка входа даже в вашем случае будет гдето, но чтоб до неё добраться нужно пройти сквозь _c_int00, на адрес который то и будет указывать значение в 0x38fff6. Так вот о чем я и говорил, что если вместо секции OTP, расположить нашу прогу(А), которая на самом деле OTP, только собранная для старта флеш, то будет её точка старта всё в том же 0x38fff6, и как только она скачает новую прошивку для флеша и перезапишет, то в том же 0x38fff6 уже будет указание не на (А) п на нашу новую прогу. Вот что я имел ввиду. И вот это как побороть я не понял, все пробы что делал не венчались успехом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doom13 0 7 июня, 2014 Опубликовано 7 июня, 2014 · Жалоба У меня 2 уровня, Первый сам OTP, который грузит в ОЗУ вторую, промежуточную прогу, Второй - грузит фирмварю, вторая кстати и записывает её в флеш через флэшАпи. Так вот там адрес точки входа то может меняться, не исключено, ибо она а ОЗУ а а будущем неизвестно как всё повернется. да, я знаю, я так пробовал, распалогал по адресу 0x8000 и от туда успешно грузился способом как вы написали ниже. Но как я уже писал адрес точки схода может поменяться. Адрес точки входа _с_int00 меняется, но адрес перехода на точку входа _c_int00 не меняется, он через секцию codestart привязан к одному и тому же адресу, т.е. зная этот адрес Вы всегда можете попасть на _c_int00. Для перехода, который выполняет занрузчик при старте программы, удобнее использовать не адрес _c_int00 (адрес самого main), а адрес перехода на _c_int00, т.е. постоянный адрес секции codestart. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
St_vladm 0 8 июня, 2014 Опубликовано 8 июня, 2014 · Жалоба Если честно я не понял как оно у вас так работает. То что вы описали это классический подход к приложению в флеше. Ведь по идее точка входа даже в вашем случае будет гдето, но чтоб до неё добраться нужно пройти сквозь _c_int00, на адрес который то и будет указывать значение в 0x38fff6. Так вот о чем я и говорил, что если вместо секции OTP, расположить нашу прогу(А), которая на самом деле OTP, только собранная для старта флеш, то будет её точка старта всё в том же 0x38fff6, и как только она скачает новую прошивку для флеша и перезапишет, то в том же 0x38fff6 уже будет указание не на (А) п на нашу новую прогу. Вот что я имел ввиду. И вот это как побороть я не понял, все пробы что делал не венчались успехом. Так. Давайте еще раз, с самого начала. У Вас в OTP записана программа-загрузчик (отдельный проект, со своим CMD-файлом). Процессор настроен выбором пинов на "boot from OTP", то есть точка BEGIN вашей проги-загрузчика, описанная в CMD-файле, всегда равна 0x380800. Программа записана раз и навсегда (так как OTP). Она откуда-то (неважно) читает какой-то параметр, и делает выбор - загрузить в ОЗУ кусок с FLASH API и передать туда управление для последующей загрузки и записи нового firmware (назовем его "основная программа" для однозначности) в FLASH, либо сразу передать управление в FLASH на уже ранее записанную программу. Адрес точки входа (BEGIN) для FLASH всегда равен 0x33FFF6, он же указывается в CMD-файле при сборке проекта основной программы. А уже по этому адресу лежит переход (LB) на _c_int00 основной программы. То есть ваша программа-загрузчик при отсутствии необходимости обновления основной программы всегда передает управление по одному и тому же адресу 0x33FFF6. Что по этому адресу лежит, зависит от ранее прописанного из бинарника кода. А лежит там обычно "LB _c_int00", естественно, с абсолютным адресом, вычисленным при компиляции кода основной программы. Программе-загрузчику этот адрес знать не нужно - достаточно передать управление на 0x33FFF6. Кусок программы-загрузчика для работы в ОЗУ расположен в проекте в отдельной секции, как и FLASH API, переносится из места хранения (OTP или FLASH, неважно) в ОЗУ через memcpy, адреса хранения в OTP/FLASH (LOAD) и перемещения/выполнения в ОЗУ (RUN) описываются в CMD-файле, как я написал ранее. Их можно задать жестко. Ваша программа-загрузчик, выполняемая в ОЗУ, в случае необходимости обновления читает бинарник основной программы и пишет его содержимое по тем адресам, которые в нем указаны. То есть все адреса известны заранее. Где наши методы (или понимание работы) расходятся? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prst 0 14 июня, 2014 Опубликовано 14 июня, 2014 · Жалоба Так. Давайте еще раз, с самого начала. У Вас в OTP записана программа-загрузчик (отдельный проект, со своим CMD-файлом). Процессор настроен выбором пинов на "boot from OTP", то есть точка BEGIN вашей проги-загрузчика, описанная в CMD-файле, всегда равна 0x380800. Программа записана раз и навсегда (так как OTP). Она откуда-то (неважно) читает какой-то параметр, и делает выбор - загрузить в ОЗУ кусок с FLASH API и передать туда управление для последующей загрузки и записи нового firmware (назовем его "основная программа" для однозначности) в FLASH, либо сразу передать управление в FLASH на уже ранее записанную программу. Адрес точки входа (BEGIN) для FLASH всегда равен 0x33FFF6, он же указывается в CMD-файле при сборке проекта основной программы. А уже по этому адресу лежит переход (LB) на _c_int00 основной программы. То есть ваша программа-загрузчик при отсутствии необходимости обновления основной программы всегда передает управление по одному и тому же адресу 0x33FFF6. Что по этому адресу лежит, зависит от ранее прописанного из бинарника кода. А лежит там обычно "LB _c_int00", естественно, с абсолютным адресом, вычисленным при компиляции кода основной программы. Программе-загрузчику этот адрес знать не нужно - достаточно передать управление на 0x33FFF6. Кусок программы-загрузчика для работы в ОЗУ расположен в проекте в отдельной секции, как и FLASH API, переносится из места хранения (OTP или FLASH, неважно) в ОЗУ через memcpy, адреса хранения в OTP/FLASH (LOAD) и перемещения/выполнения в ОЗУ (RUN) описываются в CMD-файле, как я написал ранее. Их можно задать жестко. Ваша программа-загрузчик, выполняемая в ОЗУ, в случае необходимости обновления читает бинарник основной программы и пишет его содержимое по тем адресам, которые в нем указаны. То есть все адреса известны заранее. Где наши методы (или понимание работы) расходятся? все именно так, только вместо 0x380800, должно быть 0x380400 А так, как раз Вами описан классический способ, и как раз подобного поста мне не хватало в начале всего этого пути... Только отличие в том, что мне нужно не только грузиться по тому что в 0x38FFF6, но и возможно по совершенно другому адресу самый простой пример, на чипе, в разные секции записаны разные версии, и нужно на них уметь перепрыгивать. своего рода - мультибут, и главная особенность что точки старта у них могут меняться после перепрошивки каждый раз То есть, цель сделать чуть более разумный и гибкий лоадер. что вобщем-то, мне кажется, удалось. А лежит там обычно "LB _c_int00", естественно, с абсолютным адресом, вычисленным при компиляции кода основной программы. Программе-загрузчику этот адрес знать не нужно - достаточно передать управление на 0x33FFF6. Вот тут то и проблема, была, которую я уже пофиксил, что в LD передается только константа... щас я могу гибко перепрыгивать в любое место которое узнаю при записи новой версии передав только переменную с значением точки бута. Ну и второй момент, приложение может быть собрано в бинарик без всякого там _c_int00, а точнее без библиотеки rts2800_ml.lib, конечно это малая вероятность, но тем не менее не исключено тоже Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doom13 0 16 июня, 2014 Опубликовано 16 июня, 2014 · Жалоба Только отличие в том, что мне нужно не только грузиться по тому что в 0x38FFF6, но и возможно по совершенно другому адресу самый простой пример, на чипе, в разные секции записаны разные версии, и нужно на них уметь перепрыгивать. своего рода - мультибут, и главная особенность что точки старта у них могут меняться после перепрошивки каждый раз То есть, цель сделать чуть более разумный и гибкий лоадер. что вобщем-то, мне кажется, удалось. Что-то Вам всё рассказывают-рассказывают, а Вы всё равно о своём. Для каждой прошивки свой BEGIN, гле лежит переход на свой _c_int00 и адрес BEGIN == const. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prst 0 17 июня, 2014 Опубликовано 17 июня, 2014 · Жалоба Что-то Вам всё рассказывают-рассказывают, а Вы всё равно о своём. Для каждой прошивки свой BEGIN, гле лежит переход на свой _c_int00 и адрес BEGIN == const. Так это я уже давно понял, где-то по теме выше, уже это пару раз рассказывали. Я же говорю о другом совсем(ну или немножко)... в принципе то что я делаю, это не так уж и важно, оно просто не совсем традиционное. Но если говорить кратко - то тема помогла решить те вопросы что были ранее )) По этому всем кто помог прояснить и объяснить непонятные моменты - огромное спасибо! :laughing: Я стартанул в разных видах свои прошивки, и получил довольно хороший результат, как мне показалось. А особенно, !спасибо! doom13 :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ey8bg 0 21 января, 2016 Опубликовано 21 января, 2016 · Жалоба Здравствуйте, уважаемые специалисты. У меня сходная задача, с обсуждаемой в этой теме, но я куда меньше смог продвинуться. Пока даже не получается делать прыжки в необходимую область памяти, чтобы выполнить код сохраненный там. Вот, что у меня есть: #pragma CODE_SECTION(Cycle, "MY_SEG"); volatile void Cycle(void) { тут у меня инициализация PLL, настройка порта и просто светодиодная мигалка } Сама по себе функция рабочая, светодиод мигает. Ниже мой cmd файл: MEMORY { PAGE 0: /* Program Memory */ /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE1 for data allocation */ RAML0 : origin = 0x008000, length = 0x001000 /* on-chip RAM block L0 */ OTP : origin = 0x3D7800, length = 0x000400 /* on-chip OTP */ FLASHH : origin = 0x3D8000, length = 0x004000 /* on-chip FLASH */ FLASHG : origin = 0x3DC000, length = 0x004000 /* on-chip FLASH */ FLASHB : origin = 0x3F0000, length = 0x004000 /* on-chip FLASH */ FLASHF : origin = 0x3E0000, length = 0x004000 /* on-chip FLASH */ FLASHE : origin = 0x3E4000, length = 0x003F80 /* on-chip FLASH */ FLASHD : origin = 0x3E8000, length = 0x004000 /* on-chip FLASH */ FLASHC : origin = 0x3EC000, length = 0x004000 /* on-chip FLASH */ FLASHA : origin = 0x3F4000, length = 0x003F80 /* on-chip FLASH */ CSM_RSVD : origin = 0x3F7F80, length = 0x000076 /* Part of FLASHA. Program with all 0x0000 when CSM is in use. */ BEGIN : origin = 0x3F7FF6, length = 0x000002 /* Part of FLASHA. Used for "boot to Flash" bootloader mode. */ CSM_PWL : origin = 0x3F7FF8, length = 0x000008 /* Part of FLASHA. CSM password locations in FLASHA */ ROM : origin = 0x3FF000, length = 0x000FC0 /* Boot ROM */ RESET : origin = 0x3FFFC0, length = 0x000002 /* part of boot ROM */ VECTORS : origin = 0x3FFFC2, length = 0x00003E /* part of boot ROM */ PAGE 1 : /* Data Memory */ /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE0 for program allocation */ /* Registers remain on PAGE1 */ RAMM0 : origin = 0x000000, length = 0x000400 /* on-chip RAM block M0 */ RAMM1 : origin = 0x000480, length = 0x000380 /* on-chip RAM block M1 */ BOOT_RSVD : origin = 0x000400, length = 0x000080 /* Part of M1, BOOT rom will use this for stack */ RAML1 : origin = 0x009000, length = 0x001000 /* on-chip RAM block L1 */ RAMH0 : origin = 0x3FA000, length = 0x002000 /* on-chip RAM block H0 */ } SECTIONS { /* Allocate program areas: */ .cinit : > FLASHA PAGE = 0 /*память для глобальных переменных*/ .pinit : > FLASHA, PAGE = 0 /*значения начальной инициализации переменных*/ .text : > FLASHA PAGE = 0 /*содержит исполняемый код и константы*/ codestart : > BEGIN PAGE = 0 /*в codestart сщдержится адрес старта программы BEGIN*/ MY_SEG : > FLASHH PAGE = 0 ramfuncs : LOAD = FLASHB, RUN = RAML0, LOAD_START(_RamfuncsLoadStart), LOAD_END(_RamfuncsLoadEnd), RUN_START(_RamfuncsRunStart), PAGE = 0 csmpasswds : > CSM_PWL PAGE = 0 csm_rsvd : > CSM_RSVD PAGE = 0 /* Allocate uninitalized data sections: */ .stack : > RAMM1 PAGE = 1 /*системный стек (для сохранения контекста процессора при вызове процедур)*/ .esysmem : > RAMM1 PAGE = 1 .ebss : > RAML1 PAGE = 1 MY_SEG : > FLASHH PAGE = 0 /* Initalized sections go in Flash */ /* For SDFlash to program these, they must be allocated to page 0 */ .econst : > FLASHA PAGE = 0 /*инициализация констант (для языка С)*/ .switch : > FLASHA PAGE = 0 Flash28_API: { -lFlash2809_API_V100.lib(.econst) -lFlash2809_API_V100.lib(.text) } LOAD = FLASHA, RUN = RAML0, LOAD_START(_Flash28_API_LoadStart), LOAD_END(_Flash28_API_LoadEnd), RUN_START(_Flash28_API_RunStart), PAGE = 0 /* Constants caching */ ramconsts : LOAD = FLASHB, PAGE = 0 RUN = RAML1, PAGE = 1 LOAD_START(_RamconstsLoadStart), LOAD_END(_RamconstsLoadEnd), RUN_START(_RamconstsRunStart) /* Allocate large memory blocks section: */ data_mem : > RAMH0 PAGE = 1 data_mem2 : > RAMM0 PAGE = 1 .reset : > RESET, PAGE = 0, TYPE = DSECT vectors : > VECTORS PAGE = 0, TYPE = DSECT } Данная функция записывается в SECTORH. Но вот никак не могу запустить этот код из моей функции main. Пробовал так: int main(void) { asm(" LB 0x3D8000"); } и так: int main(void) { jumpToAppEntry(); } где jumpToAppEntry(), взятая с форума ti, где обсуждали подобную тему. _jumpToAppEntry: SETC INTM; ZAPA; MOV @SP,#0; PUSH ACC; PUSH AL; MOV AL, #0x0a08; PUSH AL; MOVL XAR7, #0x3D8000; PUSH XAR7; POP RPC; POP ST1; POP ST0; POP IER; POP DBGIER; LRETR; В результате после выполнения asm(" LB 0x3D8000"); или jumpToAppEntry(); всегда в отладчике появляется сообщение : No source available for "0x3d8000" Люди, помогите разобраться. Что я делаю не так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doom13 0 21 января, 2016 Опубликовано 21 января, 2016 · Жалоба Тут было начало разговора, можете глянуть, возможно найдёте что-нибудь полезное. В результате после выполнения asm(" LB 0x3D8000"); или jumpToAppEntry(); всегда в отладчике появляется сообщение : No source available for "0x3d8000" Так и должно быть, программа уходит в область памяти, которая ей не принадлежит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ey8bg 0 21 января, 2016 Опубликовано 21 января, 2016 · Жалоба Тут было начало разговора, можете глянуть, возможно найдёте что-нибудь полезное. Ту тему читал в первую очередь. Ничего, что могло бы мне помочь я не нашел. Кстати процессор TMS320F2809. Может будут еще мысли какие нибудь у кого? Буду очень признателен, а то уже отчаялся. Так и должно быть, программа уходит в область памяти, которая ей не принадлежит. Возможно я чего то не до понимаю, но ведь именно по этому адресу расположена моя функция, которую я хочу запустить. Собственно я видел это отладчиком. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doom13 0 21 января, 2016 Опубликовано 21 января, 2016 · Жалоба Не совсем понятно, что Вы хотите сделать. Этим переходом LB 0x3D8000 хотите попасть в функцию Cycle()? А Вы уверены, что 0х3D8000 это её адрес в памяти? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ey8bg 0 21 января, 2016 Опубликовано 21 января, 2016 · Жалоба Не совсем понятно, что Вы хотите сделать. Этим переходом LB 0x3D8000 хотите попасть в функцию Cycle()? А Вы уверены, что 0х3D8000 это её адрес в памяти? Лучше опишу конечную цель - это CAN загрузчик. Этим примером я хотел отработать некоторые механизмы этого процесса. Данной темой раньше не занимался и возможно, а скорее точно думаю не совсем в правильном направлении. Сам процесс вижу так: В секторе А, В и т.д. может располагаться основная программа, которая также работает и с CAN. Если приходит команда о перепрошивке, то необходимо запустить загрузчик, который заранее записан в сектор Н и этот загрузчик уже сотрет необходимые страницы памяти и запишет в них основную программу, которую по-блочно будет получать по CAN. С чего начать и на что особенно необходимо обратить внимание? С записью и стиранием флешки я разобрался. А Вы уверены, что 0х3D8000 это её адрес в памяти? В CCS смотрел отладчиком сектор Н и там начиная с адреса 0x3d8000 были данные моей функции Cycle();. Чтобы удостовериться, что это данные именно этой функции, я вызвал эту функцию напрямую из main и убрал строку #pragma. Данные с сектора Н исчезли, зато тот же самый порядок байт оказался в секторе А. Отсюда я сделал вывод, что в первом случае в секторе Н по адресу 0x3d8000 находилась моя функция Cycle(); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doom13 0 21 января, 2016 Опубликовано 21 января, 2016 · Жалоба В той теме, если не ошибаюсь, этот процесс расписан. Должно быть две прошивки: одна - загрузчик, вторая приложение. У каждой свой cmd-файл, описывающий память в которой располагается соответствующая программа (загрузчик/приложение). Области памяти загрузчика и приложения не пересекаются. Возможный вариант работы - при включении питания стартует загрузчик, проверяет записано ли приложение, если записано, то переходит на адрес основной программы. Если подробнее, при включении питания процессор стартует с адреса BEGIN (для f2812 было 0x3F7FF6), там лежит переход на _c_int00, запускается загрузчик. Далее если условия совпали осуществляется переход на BEGIN_APP (адрес старта приложения), тут лежит переход на _c_int00 программы приложения. PS: В той теме был пример загрузчика и приложения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться