|
|
  |
LPC11xx не стартует код из своего бутлоадера |
|
|
|
Oct 22 2010, 05:17
|

Частый гость
 
Группа: Свой
Сообщений: 173
Регистрация: 30-11-05
Из: San Francisco
Пользователь №: 11 593

|
Цитата(rezident @ Oct 22 2010, 00:48)  Встречный вопрос. А сколько памяти у вас отведено под стек? Не может ли быть так, что переписывая вектора вы затираете стек? В тестовом проекте Blinky стек начинается с 0x10000800. Но в конфигурации RAM Debug, когда ремап используется-таки, в icf-файле в начале ОЗУ резервируются 0x124 байта, а не 0x200. Такой же диапазон, но уже во Flash резервируется в конфигурации FLASH Debug. У меня стек 0х200 и находится в самом конце используемого ОЗУ. А чтобы вектора ничего не затерли, я в проекте бутлоадера и основной проги разрешаю использовать ОЗУ с отступом на длину векторов.
|
|
|
|
|
Oct 22 2010, 07:00
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 21-09-10
Пользователь №: 59 626

|
Цитата(zuy @ Oct 22 2010, 00:43)  Отладчик Keil ? Он для LPC1114 не совсем корректно работает. Тот пример что я привел в случае если ремап убрать, то вылетает в отладчике в HardFault, но работает отлично в железе.
Рано я обрадовался. в 0х200 байт у меня вся тестовая прога. Получается я ее скопировал всю в ОЗУ. В реальном бутлоадере это не помогло :-( Отладчик у меня LPCXpresso. Плата + ide. Вообще, я думаю, именно в данном случае отладчик мешает. Сложно описать ощущения, когда для отладки, после команды ремапа ставишь подряд десять нопов, и, выполняя программу по ассемблерным шагам, наблюдаешь случайные изменения регистров и вылет в ХардФолт именно, блин, на седьмом нопе. Пока я для себя решил делать так: первые 512 (0x200) байт загрузчика заняты его векторами и просто нулями. Т. е. код загрузчика будет начинаться, например, с 0x204. В основной программе будет запрещено использование ОЗУ меньше адреса 0xC0. Цитата(rezident @ Oct 22 2010, 01:48)  Встречный вопрос. А сколько памяти у вас отведено под стек? Не может ли быть так, что переписывая вектора вы затираете стек? В тестовом проекте Blinky стек начинается с 0x10000800. Но в конфигурации RAM Debug, когда ремап используется-таки, в icf-файле в начале ОЗУ резервируются 0x124 байта, а не 0x200. Такой же диапазон, но уже во Flash резервируется в конфигурации FLASH Debug. По моим сведениям, в LPCXpresso стек начинается с самого старшего адреса ОЗУ и растет в сторону уменьшения адресов. Переменные же располагаются с самого младшего адреса ОЗУ и заполняют память в сторону увеличения адресов. У lpc1114, соответственно, в lpcxpresso, стек начинается с адреса 0x10002000. А у вас, я так понял, Keil? И он резервирует 0x124? (рит) Обдумаю эту информацию на досуге.
Сообщение отредактировал Alekseeey - Oct 22 2010, 07:03
|
|
|
|
|
Oct 22 2010, 13:28
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Alekseeey @ Oct 22 2010, 13:00)  По моим сведениям, в LPCXpresso стек начинается с самого старшего адреса ОЗУ и растет в сторону уменьшения адресов. Переменные же располагаются с самого младшего адреса ОЗУ и заполняют память в сторону увеличения адресов. Направление изменения стека не зависит от вида/типа платы, а только от архитектуры самого МК. Цитата(Alekseeey @ Oct 22 2010, 13:00)  А у вас, я так понял, Keil? IAR EWARM 5.50. Пример проекта Blinky из него же. Цитата(Alekseeey @ Oct 22 2010, 13:00)  И он резервирует 0x124? (рит) Обдумаю эту информацию на досуге. Это установки конкретного проекта, приводимого в примерах. Ни IDE, ни компилятор сами ничего не резервируют. Все настройки можно поменять так, как захочется. В худшем случае компилятор даст предупреждение или ошибку. Но своевольничать он не имеет права. Использую самодельную плату с LPC1114FBD48,301 и LCD-модулем (TIC234). Отладчик - MT-Link. Так что никаких ограничений, накладываемых LPCXpresso, у меня нет.
|
|
|
|
|
Oct 23 2010, 05:02
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 21-09-10
Пользователь №: 59 626

|
Цитата(rezident @ Oct 23 2010, 00:51)  Что я не так делаю?  Все так. Пожалуйста, укажи в каких адресах расположена функция main. (я думаю, в отладчике это будет видно). Мне кажется, что IAR учитывает возможность ремапа и кладет исполняемый код в более старшие адреса. И поэтому все работает. В отличие от lpcxpresso, который размещает исполняемый код сразу после таблицы векторов прерываний (адрес 0xC0), и при ремапе эта область памяти начинает ссылаться на ОЗУ, где лежит мусор. Мне интересно узнать, куда кладет исполняемый код IAR, чтобы подправить у себя линкерный скрипт.
|
|
|
|
|
Oct 23 2010, 09:18
|

Частый гость
 
Группа: Свой
Сообщений: 173
Регистрация: 30-11-05
Из: San Francisco
Пользователь №: 11 593

|
Цитата(rezident @ Oct 22 2010, 23:51)  Сегодня проэкспериментировал со своей платой и исходником из сообщения #11. Все работает корректно. Ничего не виснет и не вылетает. Через 9 секунд после ресета светодиод гаснет. Единственное, что я скорректировал, это обращение к порту, т.к. у меня из индикации только подсветка LCD и ее управление к другому пину МК подключено. Настройки icf-файла я взял из проекта Blinky, т.е. настройки стека как на скриншотах выше. Компилятор IAR EWARM 5.50.5. Отладчик MT-Link. Драйвер отладчика J-Link V4.14e. Что я не так делаю?  Конфигурацию FLASH запускали? Поставьте начало ROM с 0х0, зачем кусок флеша размером 0х124 резервировать? А то получается, собранный код располагается после 0х124 во флеш. А длина куска который ремапится вполне может быть и до 0х124. У меня ф-ция main того примера до 0x124 заканчивается.
|
|
|
|
|
Oct 23 2010, 20:00
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(zuy @ Oct 23 2010, 15:18)  Поставьте начало ROM с 0х0, зачем кусок флеша размером 0х124 резервировать? Поставил. Все равно работает. Вот проект. Специально включил генерацию всевозможных листингов и map-файла. Только не знаю, зачем вам это (в смысле начало программы с нуля)? Ведь вся эта программа умещается в сегмент, который копируется и потом маппируется. Я попробовал то же самое (разместить с нуля во Flash) сделать с другой своей программой, которая обслуживает 4 кнопки, LCD и по нажатию на кнопку выводит одну из несколько картинок на него. В ней используются прерывания от timer16_b0 и i2c-модуля. В качестве "рыбы" для этой программы я использовал пример проекта I2C из экзамплов IAR. Программа вместе с битмаповскими картинками занимает чуть меньше 12кБ во Flash. Скомпилировал, загрузил. Работает  Опять я что-то не так делаю? Или в IAR не кошерный компилятор? Update. Я установил Keil 4.12. Но с ним я не знаком и не знаю как создать проект и работать с ним. Если вы выложите свой простейший тестовый проект, который у вас не работает с LPCExpresso, то я попробую проверить его работу на своей плате.
Сообщение отредактировал rezident - Oct 23 2010, 20:58
Прикрепленные файлы
Test.zip ( 29.47 килобайт )
Кол-во скачиваний: 36
|
|
|
|
|
Oct 24 2010, 15:20
|

Частый гость
 
Группа: Свой
Сообщений: 173
Регистрация: 30-11-05
Из: San Francisco
Пользователь №: 11 593

|
Цитата(rezident @ Oct 24 2010, 04:05)  Любопытство победило  Со второй попытки создал в Keil работоспособный проект с исходником из сообщения #11. Не мудрствуя лукаво, вывел в окно watch значение регистра SYSMEMREMAP. Изменяя его значение с 0x02 на 0x01, наблюдаю, что содержимое памяти меняется. Вместо кода исполняемой из Flash программы появляются значения 0x00000000 вплоть до границы адреса 0x00000 200. То бишь подтверждается версия о маппировании всего сегмента Flash размером 512 байт. Как этот глюк обходится в IAR, мне пока непонятно.  Тестовый проект (для Keil 4.12) прикладываю. Да, похоже в ИАР это дело автоматически обходится. В общем понятно что произошло. В Rev 0_0 мануала, они ошибочно указали размер таблицы векторов в 0х200 байт и тогда в описании регистра SYSMEMREMAP написали, что он ремапит таблицу векторов. И все вроде сходилось. Но потом видимо заметили косяк, что таблица то длиной 0хС0 байт и исправили это дело, а в описании регистра SYSMEMREMAP забыли указать, что он теперь ремапит не таблицу векторов, но область 0х200. Т.о. на данный момент в последней версии мануала мы имеем некорректное описание регистра SYSMEMREMAP. Нигде по мануалу не написано, что он ремапит 0х200 байт. А зачем мне надо настройки ROM ставить с 0-го адреса. Так я считаю, что это не мое дело раскладывать программу по адресам памяти. Я линкеру указываю только где находятся области куда он может результат ложить, пусть сам и складывает. Мне то зачем над этим думать.
|
|
|
|
|
Oct 24 2010, 16:17
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(zuy @ Oct 24 2010, 21:20)  Т.о. на данный момент в последней версии мануала мы имеем некорректное описание регистра SYSMEMREMAP. Нигде по мануалу не написано, что он ремапит 0х200 байт. Угу. В NXP-ной документации косяков немало  Цитата(zuy @ Oct 24 2010, 21:20)  А зачем мне надо настройки ROM ставить с 0-го адреса. Так я считаю, что это не мое дело раскладывать программу по адресам памяти. Любая программа не умнее программиста, написавшего ее  Если вы знаете чуток побольше компилятора, то почему бы это знание не применить для облегчения ему работы? Ведь вас наверняка интересует результат, а не заморочки, которые испытывает компилятор? Да и результат его работы будет вашим общим, не так ли?
|
|
|
|
|
Oct 24 2010, 16:56
|

Частый гость
 
Группа: Свой
Сообщений: 173
Регистрация: 30-11-05
Из: San Francisco
Пользователь №: 11 593

|
Цитата(rezident @ Oct 24 2010, 19:17)  Любая программа не умнее программиста, написавшего ее  Если вы знаете чуток побольше компилятора, то почему бы это знание не применить для облегчения ему работы? Ведь вас наверняка интересует результат, а не заморочки, которые испытывает компилятор? Да и результат его работы будет вашим общим, не так ли? Не, тут немного другое. Определив ROM с адреса отличного от 0х0 я должен иметь некоторое основание. Иначе, как я это обосную коллегам по работе. У нас по бутлоадеру жесткие ограничения, каждый байт нужно знать чем занят. А то, что ремап захватывает больше байт чем таблица векторов лечится 5-ю строками кода, и не нужно линкеру ничего об этом говорить.
|
|
|
|
|
Sep 24 2012, 08:46
|
Частый гость
 
Группа: Участник
Сообщений: 100
Регистрация: 19-09-12
Пользователь №: 73 602

|
Вот код бутлоадера: CODE #include "LPC11xx.h" #include "rom_drivers.h" #include "gpio.h" #include "string.h" #include "type.h" #include "core_cm0.h" #include "system_LPC11xx.h" #include "application_Flash.h"
__ASM void __copy_MSP_( ) { ldr r0, =0x10000000 ldr r0, [r0] mov sp, r0 }
__ASM void __copy_reset_handler_( ) { ldr r0, =0x10000004 ldr r0, [r0] bx r0 }
/********************************************************** Main function ********************************/ int main(void) { SystemInit();
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
uint32_t const * pSrc = (uint32_t const *)0x00001000; //копируем первые 200 байт флеша, начиная с адреса 0х1000 в ОЗУ uint32_t * pDst = (uint32_t *)0x10000000; #define VECTORS_COUNT 128 for(uint_fast8_t i = 0; i < VECTORS_COUNT; ++i) *pDst++ = *pSrc++;
__copy_MSP_( ); //загружаем в стек
__disable_irq(); //запрещаем прерывания LPC_SYSCON->SYSMEMREMAP = 0x01; // remap to ram
__copy_reset_handler_(); //прыгаем на Resrt_handler
while(1); } Работает только если в "рабочей программе" не используются прерывания. Если прерывания используются, то "Рабоча программа" нивкакую не стартует. Какие есть догадки, в чем ошибка?
Сообщение отредактировал IgorKossak - Sep 24 2012, 13:31
Причина редактирования: [codebox] для длинного кода!!!
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|