Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Обновление прошивки STR91X через внешний интерфейс (UART)
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Zandy
Я столкнулся с проблемой написания программы (бутлодера) для обновления софта на контроллере STR91X. Прошерстив форумы ST и Keil и перебробовав массу вариатов, угробив массу времени, в сухом остатке только нерабочие проекты. Я не детализирую свои вопросы (их очень много), т. к. хотелось бы знать, кто-нибудь делал такие рабочие проекты именно для STR91X?
Очень надеюсь на помощь.
gregory812
Делал загрузчик для STM32 по USART, все работало. Посмотрел документацию, у STR9X все тоже самое. Для STR9X все команды управления подробно расписаны здесь (включая блок-схемы) http://www.st.com/stonline/products/literature/anp/12951.pdf. Расскажите подробней, что вы делаете и где не работает.
Zandy
Все вопросы свелись к одному единственному вопросу.
ПОСЛЕ УСПЕШНОЙ ЗАПИСИ В БАНК_0, НЕ ХОЧЕТ СТАРТОВАТЬ ОСНОВНАЯ ПРОГРАММА!!!

Вот функция старта приложения (Александр, ваша функция!)

Код
typedef void(*pFunction)(void);


void Start_application(void)
{
  pFunction Jump_To_Application;
  /* -------------------------------------------------------------------------- */
  /*                Configure bank 0 as 512KB and bank 1 as 32KB                */
  /*       Remap bank 0 at address 0x0 and bank 1 at address 0x80000            */
  /* -------------------------------------------------------------------------- */
  __disable_irq();
  __disable_fiq();

//  FMI->BBSR   = 0x1;
//  FMI->NBBSR  = 0x6;
//  FMI->CR     = 0;
  FMI->BBADR  = 0x80000 >> 2;
  FMI->NBBADR = 0x0;
//  FMI->CR     = BIT(4) + BIT(3);

  /* Jump to the user application and execute it */
  Jump_To_Application = (pFunction) 0x00;
  Jump_To_Application();

}


Я и до этого делал точно также. Не понимаю, в чем тут тонкость? Банки ремапятся, идем по нулевому адресу банка0, где и находится мое приложение. Оно там точно находится. Я с помощью SEGGERовской утилиты менял бит из конфигурационного регистра (тот, который заведует, с какого банка грузиться) на 0. Все в порядке - приложение работает как часы. А вот из бутлоадера (после его отработки) - хрен! Бутлоадер конечно грузится из банка 1. Здесь все чисто.

Александр, тут еще вопросик наверное к вам. Функция, приведенная выше, должна выполняться из RAM. Я это делаю просто. В кейле, в опциях файла, где лежит эта функция, выбираю IRAM1 [0x4000000-0x4017FFF]. Вот тут у меня сомнения. Правильно ли я делаю? В вашем пректе я такого не нашел. Где вы указываете, что функция должна выполняться из RAM?
AlexandrY
То что должно находится в RAM указывается в файле proj.sct (устанавливается в закладке линкера)
Это файл конфигурации для линкера.
Конкретно за функцию в RAM в нем отвечает строка : proc_in_ram.o (+RO)
Видя такую информацию линкер в программу вставляет кусок кода который во первых разжимает образ который должен быть в RAM-е, а во вторых пересылает его в эту RAM. Этот кусок вызывается из startup файла при переходе по инструкции: LDR R0, =__main
Zandy
Цитата(AlexandrY @ Aug 14 2010, 20:51) *
То что должно находится в RAM указывается в файле proj.sct (устанавливается в закладке линкера)
Это файл конфигурации для линкера.
Конкретно за функцию в RAM в нем отвечает строка : proc_in_ram.o (+RO)
Видя такую информацию линкер в программу вставляет кусок кода который во первых разжимает образ который должен быть в RAM-е, а во вторых пересылает его в эту RAM. Этот кусок вызывается из startup файла при переходе по инструкции: LDR R0, =__main


К сожалению сейчас попробовать, то что Вы сказали, не могу. Так все-таки я неправильно делал? Это может быть причиной того, что нет прыжка в основное приложение?
AlexandrY
Цитата(Zandy @ Aug 15 2010, 10:18) *
К сожалению сейчас попробовать, то что Вы сказали, не могу. Так все-таки я неправильно делал? Это может быть причиной того, что нет прыжка в основное приложение?


Если не подставить свой .sct файл Keil генерирует автоматически такой файл в директории проекта.
Его и стоило бы проверить на предмет есть ли там секция описывающая код в RAM.
Я такие эксперименты делал слишком давно и сейчас не вспомню, но кажется это не работало.
Но опять же важна версия Keil-а.
На вашем месте я бы все таки прошел по шагам с JTAG-ом до момента перехода на приложение. Все бы стало ясно в течении пяти минут.
Zandy
В .sct строка proc_in_ram.o (+RO) есть. Так что наверное тут все в порядке.

При пошаговом исполнении в дебагере все операторы выполняются. После Jump_To_Application(); попадаем в 91x_vect.s и зависаем здесь:

Код
;*******************************************************************************

PrefetchAbortHandler
        SUB    lr,lr,#4      ; Update the link register.
        SaveContext r0,r3   ; Save the workspace plus the current
                             ; return address lr_abt.

       ldr r0,=Prefetch_Handler
       ldr lr,=Prefetch_Handler_end
       bx r0                ; Branch to Prefetch_Handler.

Prefetch_Handler_end
        RestoreContext r0,r3; Return to the instruction following that...
                             ; ...has generated the prefetch abort exception.

;*******************************************************************************


И что бы это значило?
AlexandrY
Цитата(Zandy @ Aug 16 2010, 11:04) *
В .sct строка proc_in_ram.o (+RO) есть. Так что наверное тут все в порядке.

При пошаговом исполнении в дебагере все операторы выполняются. После Jump_To_Application(); попадаем в 91x_vect.s и зависаем здесь:

Код
;*******************************************************************************

PrefetchAbortHandler
        SUB    lr,lr,#4     ; Update the link register.
        SaveContext r0,r3  ; Save the workspace plus the current
                            ; return address lr_abt.

       ldr r0,=Prefetch_Handler
       ldr lr,=Prefetch_Handler_end
       bx r0            ; Branch to Prefetch_Handler.

Prefetch_Handler_end
        RestoreContext r0,r3; Return to the instruction following that...
                            ; ...has generated the prefetch abort exception.

;*******************************************************************************


И что бы это значило?


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

Zandy
Да, курсор в дизассемблере встает на 0 адрес. А далее вот что. Вот листинг дизасемблера по шагам:

Код
    50:         LDR     PC, Reset_Addr ddr
0x00000000  E59FF018  LDR       PC,[PC,#0x0018]

   137:         SaveContext r0,r3   ; Save the workspace plus the current
   138:                              ; return address lr_ und.
0x00000050  E1A00000  NOP       PC,[PC,#0x0018]
   140:        ldr r0,=Undefined_Handler PC}00080
0x00000054  E1A00000  NOP       PC,[PC,#0x0018]
   141:        ldr lr,=Undefined_Handler_end 0
0x00000058  E1A00000  NOP       PC,[PC,#0x0018]


   144: Undefined_Handler_end                  ; Reserved vector
0x0000005C  E1A00000  NOP       R0,R0,R0000000

   148:;****************************************************************************
***
   149:;* Function Name  : SWIHandler Save the workspace plus the current
   150:;* Description    : This function is called when SWI instruction executed.
   151:;* Input          : none ined_Addr
   152:;* Output         : none C,[PC,#0x0018]
   153:;****************************************************************************
***
   154:  4  E1A00000  NOP       PC,[PC,#0x0018]
   155: SWIHandler lr,=Undefined_Handler_end 0
0x00000060  E59F0110  LDR       R0,[PC,#0x0110]
   156:         SaveContext r0,r3   ; Save the workspace plus the current
   157:                              ; return address lr_ svc. ssed */
   158:
0x00000064  E59F1110  LDR       R1,[PC,#0x0110]
   159:         ldr r0,=SWI_Handler
0x00000068  E5801034  STR       R1,[R0,#0x0034]
   160:         ldr lr,=SWI_Handler_end
0x0000006C  E3A00315  MOV       R0,#0x54000000
   161:         bx r0                ; Branch to SWI_Handler.
   162:
   163: SWI_Handler_end
0x00000070  E3A01004  MOV       R1,#0x00000004
   164:         RestoreContext r0,r3; Return to the instruction following...
   165:                              ; ...the SWI instruction.
   166:;****************************************************************************
***
   167:;* Function Name  : PrefetchAbortHandler  SWI_Handler
   168:;* Description    : This function is called when Prefetch Abort
   169:;                   exception is entered
   170:;* Input          : none
   171:;* Output        : none
   172:;****************************************************************************
***
   173:  
   174: PrefetchAbortHandler
0x00000074  E5801000  STR       R1,[R0]
   175:         SUB    lr,lr,#4      ; Update the link register.
0x00000078  E3A01002  MOV       R1,#0x00000002
   176:         SaveContext r0,r3   ; Save the workspace plus the current ..
   177:                              ; return address lr_abt.
   178:    
0x0000007C  E5801004  STR       R1,[R0,#0x0004]
   179:        ldr r0,=Prefetch_Handler
0x00000080  E3A01000  MOV       R1,#0x00000000
   180:        ldr lr,=Prefetch_Handler_end
0x00000084  E580100C  STR       R1,[R0,#0x000C]
   181:        bx r0                ; Branch to Prefetch_Handler.
   182:
   183:
0x00000088  E3A02802  MOV       R2,#0x00020000


0x54000000  00000004  ANDEQ     R0,R0,R4
0x54000004  00000002  ANDEQ     R0,R0,R2
0x54000008  00000000  ANDEQ     R0,R0,R0


и т. д.


AlexandrY
Странный листинг.
Ассемблерные строки и фактически показанный код не совпадают.

Какие-то странные команды типа : NOP PC,[PC,#0x0018]

И из листинга остается непонятным как же двигался курсор по шагам.

aaarrr
Цитата(Zandy @ Aug 16 2010, 13:04) *
Да, курсор в дизассемблере встает на 0 адрес. А далее вот что. Вот листинг дизасемблера по шагам:

Лучше посмотрите не дизассемблер, а содержимое памяти с нулевого адреса. И сопоставьте с тем, что туда записывается.
Есть подозрение, что пишете на самом деле не то.
Zandy
Цитата(aaarrr @ Aug 16 2010, 20:12) *
Лучше посмотрите не дизассемблер, а содержимое памяти с нулевого адреса. И сопоставьте с тем, что туда записывается.
Есть подозрение, что пишете на самом деле не то.


Я уже говорил, что запускал записанное приложение, меняя бит "CSx Mapping" в конфигурационном регистре через Seggerовскую утилиту. Приложение запускается и работает. Также считывал память из 0 банка и сравнивал с заливаемым бинарником (правда сравнил содержимое по 0му и последнему адресу). Все было ОК. Эти два факта могут говорить о том, что код правильный?

Может быть приложение надо как-то по хитрому конфигурировать? Не знаю.

Смотреть листинг в дебагере после ремапинга я тоже не понял, зачем. Ведь фактически должен запускаться стартап приложения пользователя, а не бутлодера. Но Александр попросил, я посмотрел. smile.gif
Zandy
Вопрос в общем-то закрыт. Все работает. Как я и думал, дело было в особой конфигурации самого загружаемого приложения.
Всем спасибо!!!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.