CAHTA_1939 0 29 октября, 2007 Опубликовано 29 октября, 2007 · Жалоба я тут в msp430x1xx_user_guide прочитал что флеш память можно программировать если программа находится в ОЗУ... а кук туда ее записать? сорри если туплю... я в этом новичек и учусь... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 29 октября, 2007 Опубликовано 29 октября, 2007 · Жалоба я тут в msp430x1xx_user_guide прочитал что флеш память можно программировать если программа находится в ОЗУ... Совсем не обязательно. Программа программирования Flash может работать прямо из самой Flash. Только естественно, не из того же сектора, который в данный момент программируется. В MSP430 реализован автомат (контроллер Flash-памяти), который на время стирания/записи Flash сам тактирует ядро и подменяет текущую команду, выбираемую из Flash, командой "пустого" перехода - JMP PC. Если вы читали User's Guide, то вопрос странный. Если не читали, то стоит почитать. http://www.gaw.ru/html.cgi/txt/doc/micros/msp430/arh/5.htm а кук туда ее записать? сорри если туплю... я в этом новичек и учусь... Дык банальным копированием :) - скопировали код в ОЗУ и передали ему управление. Только этот кусок кода должен быть перемещаемым, т.е. работать с относительными локальными метками переходов. Ну и не быть слишком большим конечно же, помещаться в имеющийся на кристалле объем ОЗУ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
АДИКМ 0 30 октября, 2007 Опубликовано 30 октября, 2007 · Жалоба Если Вам надо быстрое блочное программирование, тогда программа должна выполняться только из рам. Если достаточно байтового/пословного программирования, тогда можно выполнять из флеш. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NoName 0 1 ноября, 2007 Опубликовано 1 ноября, 2007 (изменено) · Жалоба Это мне понятно, дело здесь в другом, допустим у нас несколько сегментов: -Z(CODE)CODE=1100-1200 -Z(CODE)MYCODE=1200-1500 По умолчанию компилятор IAR помещает стандартные и служебные функции в сегмент CODE, то есть это означает, что если программист забыл указать сегмент, то компилятор автоматом поместит в сегмент --Z(CODE)CODE, то есть мне не хотелось сильно зависеть от данного сегмента, ибо большинство функции находятся в сегменте MYCODE, придется тогда над каждой функцией писать #pragma location="MYCODE". В старой версии IAR мне понравилось тем, что распределение по сегментам определяется один раз, достаточно наверху с помошью прагмы указать сегмент и тогда все функции данного модуля окажутся в этом сегменте, а новой версии этого почему-то не нашел, приходится объявлять сегмент каждой функции, что не есть хорошо.. для Си void func_name ( void ) @ "MYCODE" { _NOP(); } недочитал %), ответ не по вопросу ... Изменено 1 ноября, 2007 пользователем NoName Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KARLSON 1 5 октября, 2011 Опубликовано 5 октября, 2011 · Жалоба Здравствуйте. Собрался писать загрузчик. Т.к. в MSP430F2410 выводы своего загрузчика находятся на P1.1 и P2.2, которые заняты. Почитав форум узнал: - что лучше делать 2 проекта (один загрузчик, другой рабочий проект), получается 2 hex файла? Первый – загрузчик - прошивается через JTAG? А после, через интерфейс загрузчика? - что-то делается с таблицами векторов. Так называемый remapping. Но так и не понял как это делается. Смею предположить, что переписывается всего лишь xcl файл. С программированием флеш памяти (INFO) знаком. Написал функцию прошивальщика с общением по UART.(Прикрепил) Правда ещё не проверял в действии. Вопросы: с чего продолжить? Как оформить таблицу векторов? Как оформить функцию прошивальщик. Program_FLASH.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 5 октября, 2011 Опубликовано 5 октября, 2011 · Жалоба - что лучше делать 2 проекта (один загрузчик, другой рабочий проект), получается 2 hex файла?Да. Первый – загрузчик - прошивается через JTAG? А после, через интерфейс загрузчика?Не обязательно. Можно обе прошивки hex-файла объединить. Ведь пересекаться по расположению в памяти они не должны. - что-то делается с таблицами векторов. Так называемый remapping. Но так и не понял как это делается. Смею предположить, что переписывается всего лишь xcl файл.Не совсем так. В xcl-файле проекта пользовательского исходника нужно объявить сегмент, который компилятор не должен использовать для размещения кода. В исходнике же бутлоадера - наоборот, компилятор должен использовать только этот выделенный сегмент. На месте векторов прерываний должны быть адреса переходов. А сами обработчики прерываний располагаются где-то в другом месте (в неперезаписываемом сегменте Flash или в ОЗУ). Хотя по-моему в бутлоадере использовать прерывания это моветон, да и незачем, если только у вас нет жесткого требования обновления firmware прямо во время работы программы без прерывания ее функционирования. Хотя в этом случае образец новой firmware предварительно еще где-то сохранить нужно, проверив его на валидность. Работать в бутлоадере с UART можно и без прерываний, по опросу флагов готовности. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KARLSON 1 10 октября, 2011 Опубликовано 10 октября, 2011 · Жалоба При двух проектах, ведь будет две функции main(); А при включении контроллера запускаться должна рабочая программа? И по команде по UART вызываться функция бутлоадера, вернее переход на адрес во флешь? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 140 10 октября, 2011 Опубликовано 10 октября, 2011 · Жалоба А при включении контроллера запускаться должна рабочая программа?А если ее нет или она записалась не до конца? Как раз наоборот - при включении питания запускается загрузчик, проверяет целостность рабочей программы, и если она признана живой - запускает ее. Если нет - ожидает поступления по UART (или другому интерфейсу перепрошивки) команды перепрошивки. И по команде по UART вызываться функция бутлоадера, вернее переход на адрес во флешь?Это да. Если приложение запущено, то оно запускает загрузчик по команде. Но не переходом на его main(), а переходом на начало его стартап-кода, который штатно подготовит ОЗУ для запуска main() загрузчика. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KARLSON 1 10 октября, 2011 Опубликовано 10 октября, 2011 · Жалоба И так. Создаю пример. Вопрос: правильно ли прописаны xcl файлы? Как вызвать в загрузчике приложение и наоборот)) Msp430F2410 описание памяти: // Interrupt vectors: 32 // Peripheral units: 0-01FF // Information memory (FLASH): 1000-10FF // Read/write memory (RAM): 1100-20FF // Read-only memory (FLASH): 2100-FFFF Bootloader #include <io430.h> #include "Titl.h" #include "function.cpp" #include "UART0.cpp" void main( void ) { WDTCTL = WDTPW + WDTHOLD; Init_DCO_16MHz(); Init_USCI_A0(); Init_FLASH(); P3OUT = 0; P3DIR = BIT3; if (Check_Flash()) {// проверка прошла удачно // переход в приложение } else {// неудачная проверка // ждём команду по UART перепрошивки _EINT(); while(1) { for(unsigned int i=0; i<65000; i++); for(unsigned int i=0; i<65000; i++); P3OUT ^= BIT3; } } } xcl файл Bootloader // ------------------------------------- // Code // -Z(CODE)CSTART,ISR_CODE,CODE_ID=EC00-FFBF -P(CODE)CODE=EC00-FFBF // ------------------------------------- // Interrupt vectors // -Z(CODE)INTVEC=FFC0-FFFF -Z(CODE)RESET=FFFE-FFFF Приложение #include <io430.h> #include "Titl.h" #include "function.cpp" #include "UART0.cpp" void main( void ) { WDTCTL = WDTPW + WDTHOLD; Init_DCO_16MHz(); Init_USCI_A0(); P3OUT = 0; P3DIR = BIT3; _EINT(); while(1) {// приложение for(unsigned int i=0; i<65000; i++); for(unsigned int i=0; i<65000; i++); P3OUT ^= BIT3; } } #pragma vector = USCIAB0RX_VECTOR __interrupt void USCIA0_RX(void) {//1 if(UCA0STAT&UCADDR) {//2 Clovo_Data_RX0=0; //--------------------------------------------------- switch(UCA0RXBUF) { case 0: // команда для прошивке // переход на прошивку UCA0CTL1 &=~ UCDORM; //Переключиться на прием неадресных символов break; default: break; } }//2 }// 1 xcl файл Приложения // ------------------------------------- // Code // -Z(CODE)CSTART,ISR_CODE,CODE_ID=2200-EBFF -P(CODE)CODE=2200-EBFF // ------------------------------------- // Interrupt vectors // -Z(CODE)INTVEC=21C0-21FF -Z(CODE)RESET=21FE-21FF Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 10 октября, 2011 Опубликовано 10 октября, 2011 · Жалоба И так. Создаю пример.Bootloader на плюсах? Весьма оригинально! Вопрос: правильно ли прописаны xcl файлы? Как вызвать в загрузчике приложение и наоборот)) main для приложения должена компилироваться как функция по заранее определенному адресу. Тогда не составляет сложности вызвать эту функцию по указателю. О том, как разместить функцию по определенному адресу, написано в разделах Placing code and data и Pragma directives документа EW430_CompilerReference.pdf. Обязательно следует учитывать, что еще до вызова функции main в скомпилированной программе сначала выполняется установка/инициализация указателя стека, затем вызывается функция low_level_init, а потом выполняется функция очистки и начальной инициализации глобальных и статических переменных (?cstart_init_zero). Так что если вы будете вызывать пользовательскую программу по адресу main, то вышеописанные функции вам придется реализовывать "вручную". Ну либо ищите как можно узнать или зарезервировать адрес метки __program_start (?cstart_begin в случае С), которая располагается по адресу перехода от вектора прерывания RESET и с которой начинается выполнение программы. Обычно эта метка совпадает с началом сегмента CODE. Все это справедливо лишь для "чистого" Си. C++ для программирования MSP430 я ни разу не использовал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 140 11 октября, 2011 Опубликовано 11 октября, 2011 · Жалоба Bootloader на плюсах? Весьма оригинально!Ой, да бросьте. Гораздо удобнее чем на обычных Сях. Накладных расходов нет, если пользоваться головой. main для приложения должена компилироваться как функция по заранее определенному адресу. Тогда не составляет сложности вызвать эту функцию по указателю.Зачем? Достаточно перейти по тому адресу, который находится в векторе Reset приложения. И все необходимые действия (cstartup) будут выполнены, и адрес этого вектора известен. KARLSON: Включать .cpp в другие файлы - путь в корне неправильный. Вам необходимо почитать про заголовочные (header) файлы и раздельную компиляцию. -Z(CODE)INTVEC=FFC0-FFFF -Z(CODE)RESET=FFFE-FFFF Бить область векторов на две (выделать вектор сброса в отдельную область) не обязательно. Мне кажется вторая строка лишняя - вектор сброса компилятор тоже кладет в INTVEC. Во втором файле то же самое. Но идею вы ухватили верно. И подумайте, как быть с прерываниями - у приложения будут свои обработчики и их надо вызывать, а "настоящие" вектора находятся в области загрузчика. Я на GCC делал так: __attribute__ ((section(".app_vectors"))) struct { flash_t::address_t App_image_size; void *Vectors[INT_VECTORS_COUNT - 1]; void (*ResetVector)(); } Application; #define TRAMP(name, vector) \ extern "C" __attribute__((__naked__)) void Tramp_##name() \ { \ asm volatile("BR %0\n\t" ::"m"(InterruptVectors[vector])); \ } TRAMP(DAC12, 0); TRAMP(DMA, 1); TRAMP(USCIAB1TX_VECTOR, 2); TRAMP(USCIAB1RX_VECTOR, 3); ..... typedef void (*vector_t)(); __attribute__ ((section(".vectors"))) extern vector_t const VectorTable[INT_VECTORS_COUNT] = { Tramp_DAC12, Tramp_DMA, Tramp_USCIAB1TX_VECTOR, Tramp_USCIAB1RX_VECTOR, Вы можете сделать что-то подобное в отдельном асм-файле. Если загрузчику тоже нужны обработчики прерываний, то надо копировать вектора нужной части программы в ОЗУ и адрес для этого перехода брать из ОЗУ: if (!crc) // Application Section crc ok { DRIVER(MANUAL_BOOT, OUTPUT); // set MANUAL_PROG as output uint_fast8_t i = INT_VECTORS_COUNT - 1; // do not copy reset vector while(i--) { InterruptVectors[i] = Application.Vectors[i]; } Application.ResetVector(); } Не забудьте запретить прерывания перед переходом из приложения в загрузчик. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 11 октября, 2011 Опубликовано 11 октября, 2011 · Жалоба Зачем? Достаточно перейти по тому адресу, который находится в векторе Reset приложения. И все необходимые действия (cstartup) будут выполнены, и адрес этого вектора известен.В векторе сброса располагается адрес старта бутлоадера, а не пользовательского приложения. Или я что-то не понимаю? :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 140 11 октября, 2011 Опубликовано 11 октября, 2011 · Жалоба В векторе сброса располагается адрес старта бутлоадера, а не пользовательского приложения. Или я что-то не понимаю? :laughing:В векторе Reset приложения. Приложение ведь имеет свой полный комплект векторов, в том числе и вектор Reset c адресом перехода как раз в нужную точку старта. У меня так :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 11 октября, 2011 Опубликовано 11 октября, 2011 · Жалоба В векторе Reset приложения. Приложение ведь имеет свой полный комплект векторов, в том числе и вектор Reset c адресом перехода как раз в нужную точку старта.Дык ведь тогда вектора RESET бутлоадера и приложения будут наложены друг на друга. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 140 11 октября, 2011 Опубликовано 11 октября, 2011 · Жалоба Дык ведь тогда вектора RESET бутлоадера и приложения будут наложены друг на друга.Ну почему же? Посмотрите сообщение №24 - две программы, две таблицы векторов по разным адресам. А... кажется понял. У нас несколько разная трактовка понятия "вектор". Я под вектором подразумеваю содержимое, т.е. сам адрес "куда переходить", а не саму ячейку, т.е. "адрес, из которого процессор берет адрес перехода". Поэтому и таблица "моих" векторов у приложения может быть своя, совершенно независимая. Да, адреса из таблицы приложения берутся не аппаратно, а посредством функций-помошников ("трамплинов"), указатели на которые сидят на "железных", "ваших" ;) векторах. Во всяком случае такой подход позволяет ценой одного дополнительного косвенного перехода и двух байт ОЗУ на каждый вектор иметь совершенно независимые обработчики у приложения и загрузчика. Причем в целях экономии ОЗУ таким образом можно охватить не всю таблицу, а лишь физически реализованные в процессоре прерывания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться