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

 
 
> Bootloader для MSP430, как написать бутлоадер для МСП430
asket
сообщение Oct 15 2007, 10:09
Сообщение #1


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

Группа: Участник
Сообщений: 91
Регистрация: 24-08-06
Из: Москва
Пользователь №: 19 809



Я в этом деле новичок, недавно начал заниматься этой деятельностью, мне поручили написать Bootloader. Задача: имеется шина, будь это COM-порт или собственная шина, не важно какая, нужно по данной шине закачать с компьютера прошивку и залить его во флеш в целях ее обновления, вопрос: как это сделать это по умному? Кто и что посоветует? Может примерчик какой-нить.. К сожалению в отличии от других процев у MSP430 встроенных бутлоадеров я так понимаю нету. Компилятор IAR 3.42.

Заранее благодарен.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
KARLSON
сообщение Oct 10 2011, 11:34
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 604
Регистрация: 5-05-06
Из: Нижегородская обл.
Пользователь №: 16 819



И так. Создаю пример.
Вопрос: правильно ли прописаны 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





--------------------
Кризис - это не отсутствие денег, а отсутствие идей! Учитесь и никаких кризисов не будет.
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 10 2011, 19:44
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(KARLSON @ Oct 10 2011, 16:34) *
И так. Создаю пример.
Bootloader на плюсах? wacko.gif Весьма оригинально!
Цитата(KARLSON @ Oct 10 2011, 16:34) *
Вопрос: правильно ли прописаны 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 я ни разу не использовал.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 11 2011, 06:12
Сообщение #4


Гуру
******

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



QUOTE (rezident @ Oct 10 2011, 22:44) *
Bootloader на плюсах? wacko.gif Весьма оригинально!
Ой, да бросьте. Гораздо удобнее чем на обычных Сях. Накладных расходов нет, если пользоваться головой.
QUOTE (rezident @ Oct 10 2011, 22:44) *
main для приложения должена компилироваться как функция по заранее определенному адресу. Тогда не составляет сложности вызвать эту функцию по указателю.
Зачем? Достаточно перейти по тому адресу, который находится в векторе Reset приложения. И все необходимые действия (cstartup) будут выполнены, и адрес этого вектора известен.

KARLSON: Включать .cpp в другие файлы - путь в корне неправильный. Вам необходимо почитать про заголовочные (header) файлы и раздельную компиляцию.

CODE
-Z(CODE)INTVEC=FFC0-FFFF
-Z(CODE)RESET=FFFE-FFFF
Бить область векторов на две (выделать вектор сброса в отдельную область) не обязательно. Мне кажется вторая строка лишняя - вектор сброса компилятор тоже кладет в INTVEC. Во втором файле то же самое. Но идею вы ухватили верно. И подумайте, как быть с прерываниями - у приложения будут свои обработчики и их надо вызывать, а "настоящие" вектора находятся в области загрузчика. Я на GCC делал так:
CODE
__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,
Вы можете сделать что-то подобное в отдельном асм-файле.
Если загрузчику тоже нужны обработчики прерываний, то надо копировать вектора нужной части программы в ОЗУ и адрес для этого перехода брать из ОЗУ:
CODE
    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();
    }


Не забудьте запретить прерывания перед переходом из приложения в загрузчик.


--------------------
На любой вопрос даю любой ответ
"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
rezident
сообщение Oct 11 2011, 15:08
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Сергей Борщ @ Oct 11 2011, 11:12) *
Зачем? Достаточно перейти по тому адресу, который находится в векторе Reset приложения. И все необходимые действия (cstartup) будут выполнены, и адрес этого вектора известен.
В векторе сброса располагается адрес старта бутлоадера, а не пользовательского приложения. Или я что-то не понимаю? laughing.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 11 2011, 17:32
Сообщение #6


Гуру
******

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



QUOTE (rezident @ Oct 11 2011, 18:08) *
В векторе сброса располагается адрес старта бутлоадера, а не пользовательского приложения. Или я что-то не понимаю? laughing.gif
В векторе Reset приложения. Приложение ведь имеет свой полный комплект векторов, в том числе и вектор Reset c адресом перехода как раз в нужную точку старта.
У меня так laughing.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
rezident
сообщение Oct 11 2011, 17:59
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Сергей Борщ @ Oct 11 2011, 22:32) *
В векторе Reset приложения. Приложение ведь имеет свой полный комплект векторов, в том числе и вектор Reset c адресом перехода как раз в нужную точку старта.
Дык ведь тогда вектора RESET бутлоадера и приложения будут наложены друг на друга.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 11 2011, 22:32
Сообщение #8


Гуру
******

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



QUOTE (rezident @ Oct 11 2011, 20:59) *
Дык ведь тогда вектора RESET бутлоадера и приложения будут наложены друг на друга.
Ну почему же? Посмотрите сообщение №24 - две программы, две таблицы векторов по разным адресам.
А... кажется понял. У нас несколько разная трактовка понятия "вектор". Я под вектором подразумеваю содержимое, т.е. сам адрес "куда переходить", а не саму ячейку, т.е. "адрес, из которого процессор берет адрес перехода". Поэтому и таблица "моих" векторов у приложения может быть своя, совершенно независимая. Да, адреса из таблицы приложения берутся не аппаратно, а посредством функций-помошников ("трамплинов"), указатели на которые сидят на "железных", "ваших" wink.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

Сообщений в этой теме
- asket   Bootloader для MSP430   Oct 15 2007, 10:09
- - VAI   ЦитатаК сожалению в отличии от других процев у MSP...   Oct 15 2007, 10:36
|- - asket   Цитата(VAI @ Oct 15 2007, 14:36) Плохо по...   Oct 15 2007, 11:12
- - rezident   asket, вы сначала разберитесь как внутрипрограммно...   Oct 15 2007, 12:11
|- - asket   Цитата(rezident @ Oct 15 2007, 16:11) ask...   Oct 15 2007, 12:50
- - VAI   Нашел на http://tech.groups.yahoo.com/group/msp430...   Oct 15 2007, 13:21
|- - asket   Цитата(VAI @ Oct 15 2007, 17:21) Нашел на...   Oct 15 2007, 13:56
|- - rezident   Цитата(asket @ Oct 15 2007, 19:56) И еще ...   Oct 15 2007, 18:40
|- - asket   Цитата(rezident @ Oct 15 2007, 22:40) Дык...   Oct 19 2007, 08:10
|- - asket   Неужели останусь без ответа и привета?   Oct 19 2007, 14:56
|- - gotty   Цитата(asket @ Oct 19 2007, 11:10) Окей, ...   Oct 22 2007, 06:19
|- - asket   Еще такой вопрос по поводу сегментации флеш-памяти...   Oct 23 2007, 13:27
|- - gotty   Цитата(asket @ Oct 23 2007, 16:27) Еще та...   Oct 23 2007, 14:16
|- - asket   Цитата(gotty @ Oct 23 2007, 18:16) Можно ...   Oct 23 2007, 15:48
|- - NoName   Цитата(asket @ Oct 23 2007, 17:48) Это мн...   Nov 1 2007, 13:39
- - SSerge   Узнать размер именно функции нельзя. Но можно указ...   Oct 19 2007, 19:16
- - CAHTA_1939   я тут в msp430x1xx_user_guide прочитал что флеш па...   Oct 29 2007, 20:36
|- - rezident   Цитата(CAHTA_1939 @ Oct 30 2007, 01:36) я...   Oct 29 2007, 20:53
- - АДИКМ   Если Вам надо быстрое блочное программирование, то...   Oct 30 2007, 13:13
- - KARLSON   Здравствуйте. Собрался писать загрузчик. Т.к. в MS...   Oct 5 2011, 07:31
|- - rezident   Цитата(KARLSON @ Oct 5 2011, 12:31) - чт...   Oct 5 2011, 17:26
- - KARLSON   При двух проектах, ведь будет две функции main(); ...   Oct 10 2011, 05:20
|- - Сергей Борщ   QUOTE (KARLSON @ Oct 10 2011, 08:20) А пр...   Oct 10 2011, 06:57
- - rezident   Нет, Сергей, как сделать "перемещаемые" ...   Oct 11 2011, 23:16
|- - Сергей Борщ   QUOTE (rezident @ Oct 12 2011, 02:16) Нет...   Oct 12 2011, 06:14
- - KARLSON   А что делает запись ((void(*)() )0x2200)();? Если ...   Oct 12 2011, 12:42
|- - Сергей Борщ   QUOTE (KARLSON @ Oct 12 2011, 15:42) А чт...   Oct 12 2011, 13:07
- - KARLSON   Захотел я сделать прошивку с переходами между прил...   Oct 13 2011, 06:35
|- - Сергей Борщ   QUOTE (KARLSON @ Oct 13 2011, 09:35) Кста...   Oct 13 2011, 15:56
- - Kurt   Мои пять копеек. Вариант, если в устройстве есть в...   Oct 21 2011, 04:49


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

 


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


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