|
LPC1114., Исполнение программы из ОЗУ |
|
|
|
Mar 19 2012, 18:48
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Вечер добрый. Вопрос следующий: Скачал с сайта Yagarto ( пример для lpc1114). Сделал в файле main.c нём такое изменение: Код #include <stdint.h> #include "LPC11xx.h" #include "core_cm0.h"
void DelayTick(uint32_t delay) { while (delay) { while ((SysTick->CTRL&(1<<SysTick_CTRL_COUNTFLAG_Pos))==0); SysTick->CTRL = 0 | (1 << SysTick_CTRL_ENABLE_Pos) // Enable timer | (0 << SysTick_CTRL_TICKINT_Pos) // Disable SysTick interrupts | (0 << SysTick_CTRL_CLKSOURCE_Pos); // System clock/2 delay--; } }
int main (void) { LPC_GPIO0->DIR=1<<7;
// setup SysTick timer SysTick->LOAD = 48000000 / 100-1; SysTick->VAL = 0; // reset counter SysTick->CTRL = 0 | (1 << SysTick_CTRL_ENABLE_Pos) // Enable timer | (0 << SysTick_CTRL_TICKINT_Pos) // Disable SysTick interrupts | (0 << SysTick_CTRL_CLKSOURCE_Pos) // System clock/2 ; while (1) { LPC_GPIO0->DATA&=~(1<<7); DelayTick(100); LPC_GPIO0->DATA|=(1<<7); DelayTick(5);
} } То есть всё выкинул и вставил моргание светодиодом с частотой ~1Гц. Запустил на отладку - увидел то что ожидал. Дальше заменил в makefile строку Код RUN_FROM_FLASH = 1 Код RUN_FROM_FLASH = 0 Ожидал увидеть, что программа начнёт исполнятся из ОЗУ - нет, не увидел: контроллер перешёл в какое-то неизвестное мне состояние и отлаживаться отказался(выдал сообщение: No source available for ""). Дальше, запрограммировал test_ram.elf - морганий не увидел. Программатор/отладчик - LPCXpresso. Как правильно запускать программу в ОЗУ? Можно ли отлаживать программу расположенную в ОЗУ? Видимо, я хочу получить от этого примера то, для чего он совсем не предназначен. Для чего он тогда? Спасибо.
|
|
|
|
|
Mar 20 2012, 07:51
|

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

|
QUOTE (_Артём_ @ Mar 19 2012, 20:48)  Дальше заменил в makefile строку CODE RUN_FROM_FLASH = 1 CODE RUN_FROM_FLASH = 0 1) В скрипте линкера отсутствует строка CODE ENTRY(Reset_Handler) В вашем архиве то же самое делает команда monitor reg pc = (0x10000004), но ENTRY - более прямой путь. 2) В crt.c идет обращение к Vector Offset Register, которого в Cortex-M0 не существует (там ремап через регистр SYSMEMREMAP как в "обычных" ARM). 3) При старте дебаггера надо прописать в указатель стека значение из таблицы векторов. Либо в командах дебаггера, либо в начале Reset_Handler. В вашем архиве это делает команда monitor reg r13 = (0x10000000). Разберитесь, куда ее надо вписать в LPCXpresso. QUOTE (_Артём_ @ Mar 19 2012, 20:48)  Ожидал увидеть, что программа начнёт исполнятся из ОЗУ - нет, не увидел: контроллер перешёл в какое-то неизвестное мне состояние и отлаживаться отказался(выдал сообщение: No source available for ""). Посмотрите содержимое PC. Вероятно он улетел в адреса, для которых у вас действительно нет исходного кода. Можно воспользоваться окном дизассемблера чтобы посмотреть содержимое памяти. QUOTE (_Артём_ @ Mar 19 2012, 20:48)  Как правильно запускать программу в ОЗУ? Можно ли отлаживать программу расположенную в ОЗУ? Да, можно. Вам нужно заставить отладчик перед стартом выполнить то, что при старте из флеша делает ядро - инициализировать указатель стека из таблицы векторов и занести в PC адрес начала программы (опять же либо из таблицы векторов либо директивой ENTRY() скрипта линкера). QUOTE (_Артём_ @ Mar 19 2012, 20:48)  Видимо, я хочу получить от этого примера то, для чего он совсем не предназначен. Для чего он тогда? Это надо в его описании читать. Я предпочитаю читать документацию и писать подобный пример сам. Да, требует времени, но приходит детальное понимание процесса.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 20 2012, 11:38
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Спасибо, что-то начало запускаться (пока не понял что). Цитата(Сергей Борщ @ Mar 20 2012, 09:51)  1) В скрипте линкера отсутствует строка Код ENTRY(Reset_Handler) В вашем архиве то же самое делает команда monitor reg pc = (0x10000004), но ENTRY - более прямой путь. Пока добавил в lpc1114_ram.ld Код ENTRY(ResetHandler) Запустилось. Не знаю откуда - разбираюсь. Цитата(Сергей Борщ @ Mar 20 2012, 09:51)  то же самое делает команда monitor reg pc = (0x10000004) Это видимо относится к jlink-e которого у меня нет. Цитата(Сергей Борщ @ Mar 20 2012, 09:51)  2) В crt.c идет обращение к Vector Offset Register, которого в Cortex-M0 не существует А это тогда кто: Код *((uint32_t*)0xE000ED08) = (uint32_t)&_stext
? Цитата(Сергей Борщ @ Mar 20 2012, 09:51)  Посмотрите содержимое PC. Вероятно он улетел в адреса, для которых у вас действительно нет исходного кода. Можно воспользоваться окном дизассемблера чтобы посмотреть содержимое памяти. Это надо в его описании читать. Я предпочитаю читать документацию и писать подобный пример сам. Да, требует времени, но приходит детальное понимание процесса. Посмотрю. Спасибо. Цитата(Сергей Борщ @ Mar 20 2012, 09:51)  Это надо в его описании читать. Я предпочитаю читать документацию и писать подобный пример сам. Да, требует времени, но приходит детальное понимание процесса. Самый надёжный метод. Не поспоришь.
|
|
|
|
|
Mar 20 2012, 16:54
|

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

|
QUOTE (_Артём_ @ Mar 20 2012, 13:38)  Это видимо относится к jlink-e которого у меня нет. Это относится к любому gdb серверу. monitor - обращение к серверу, смысл "reg pc = (0x10000004)" думаю понятен. QUOTE (_Артём_ @ Mar 20 2012, 13:38)  А это тогда кто: А в документации он где? SYSMEMREMAP в документации есть и работает как описано (проверено). VECT_OFFSET есть в документации Cortex-M3, в документации M0 такого регистра нет.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 21 2012, 22:15
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Попробывал использовать в проекте функции расположенные и в RAM и во flash: Код __attribute__ ((__section__(".data.WaitTimer0_16BInterrupt"))) void WaitTimer0_16BInterrupt() { unsigned long counter_value=Timer0_16BCounter;
while (counter_value==Timer0_16BCounter); } Судя по содержимому pc выполняется из ОЗУ. Но выдаётся warning: Цитата Warning: setting incorrect section attributes for .data.WaitTimer0_16BInterrupt Или есть какие-то другие способы, более прямые?
|
|
|
|
|
Mar 22 2012, 06:39
|

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

|
QUOTE (_Артём_ @ Mar 22 2012, 00:15)  Или есть какие-то другие способы, более прямые? Секции .data не имеют атрибута x (executable). Надо завести свою секцию и разместить ее в выходную секцию .data: CODE .data : { . = ALIGN(4); _sdata = .; /* start of .data label */ *(.ramfunc*) *(.data*) . = ALIGN(4); _edata = .; /* end of .data label */ } > RAM AT > TEXT _sidata = LOADADDR(.data); /* start of initialized data label */
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 22 2012, 19:08
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Сергей Борщ @ Mar 22 2012, 08:39)  Секции .data не имеют атрибута x (executable). Надо завести свою секцию и разместить ее в выходную секцию .data: Попробовал: warning пропал. Способ - более прямой. Спасибо. Цитата(Сергей Борщ @ Mar 20 2012, 18:54)  А в документации он где? SYSMEMREMAP в документации есть и работает как описано (проверено). VECT_OFFSET есть в документации Cortex-M3, в документации M0 такого регистра нет. Да, похоже так - регистра VECT_OFFSET в M0 нет. Значит в примере от Yagarto и LPCXpresso ошибка.
|
|
|
|
|
Mar 23 2012, 03:37
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Сергей Борщ @ Mar 22 2012, 12:39)  Сергей, может, всё же вот так: Код *(.data) *(.data.*) ? Иначе в секцию .data попадут секции с именами .datablablabla, а это может быть неправильно.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Mar 23 2012, 15:35
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(AHTOXA @ Mar 23 2012, 05:37)  Сергей, может, всё же вот так: Код *(.data) *(.data.*) ? Иначе в секцию .data попадут секции с именами .datablablabla, а это может быть неправильно. То есть в результате пишется так: Код .data : { . = ALIGN(4); _sdata = .; /* start of .data label */ *(.ramfunc) *(.ramfunc.*) *(.data) *(.data.*) . = ALIGN(4); _edata = .; /* end of .data label */ } > RAM AT > TEXT _sidata = LOADADDR(.data); /* start of initialized data label */ . Спасибо, AHTOXA.
|
|
|
|
|
Mar 23 2012, 18:11
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(AHTOXA @ Mar 23 2012, 20:03)  Кстати, заметил интересный глюк {arm-none-eabi,arm-kgp-eabi-}size. Как только я добавляю таким макаром хоть одну RAM-функцию, size начинает рапортовать, что размер data = 0. Кстати да: Цитата text data bss dec hex filename 17028 0 5228 22256 56f0 ./exe/lcp11_test_proj.elf Errors: none Непорядок, однако. А если в скрипте пишешь так Цитата *(.ramfunc) *(.data) То Цитата text data bss dec hex filename 17012 12 5228 22252 56ec ./exe/lcp11_test_proj.elf Errors: none
|
|
|
|
|
Mar 23 2012, 18:49
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(_Артём_ @ Mar 24 2012, 00:11)  А если в скрипте пишешь так Код *(.ramfunc) *(.data) Ну, так совсем неправильно, звёздочки в конце таки нужны. (При -ffunction-sections -fdata-sections секции называются .data.имя_переменной и .ramfunc.что-то_там). Ещё поэкспериментировал. С ключом -A size выдаёт совсем другие цифры! Вот например: arm-none-eabi-size STM32VLD.elf : Код text data bss dec hex filename 11732 0 3972 15704 3d58 STM32VLD.elf arm-none-eabi-size -A STM32VLD.elf Код STM32VLD.elf : section size addr .isr_vector 464 134217728 .text 11180 134218192 .text.align 4 134229372 .data 84 536870912 .bss 3716 536870996 ._usrstack 256 536874712 .comment 83 0 Эти цифры больше похожи на правду.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Mar 23 2012, 19:03
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(AHTOXA @ Mar 23 2012, 20:49)  Ну, так совсем неправильно, звёздочки в конце таки нужны. Не спорю - неправильно: не то скопировал. Цитата(AHTOXA @ Mar 23 2012, 20:49)  Ещё поэкспериментировал. С ключом -A size выдаёт совсем другие цифры! Куда ключ-то вставлять? Он от какого замка?
|
|
|
|
|
Mar 23 2012, 20:03
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(_Артём_ @ Mar 24 2012, 01:03)  Куда ключ-то вставлять? Он от какого замка? Дык, я же написал командную строку перед цитатой. А еcли в makefile, то вот сюда: Код $(OK): $(ELF) @$(SIZE) -A $(ELF)
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|