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

 
 
 
Reply to this topicStart new topic
> LPC2138, memcpy и DataAbort
esaulenka
сообщение Jul 22 2009, 19:17
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Наткнулся на непонятную проблему...

Исходные данные:
Keil, компилятор - древний кейловский CARM, оптимизаций нет.
процессор LPC2138


Есть такой код (вопросы по оптимальности использования LDRB/STRB, перебрасывания регистров туда-сюда - к авторам библиотек к CARM)
CODE

0x000388F4 E59FC000 LDR R12,[PC]
0x000388F8 E12FFF1C BX R12
0x000388FC 00038901 DD 0x00038901
strlen:
0x00038900 2100 MOV R1,#0x00
0x00038902 E000 B 0x00038906
0x00038904 3101 ADD R1,#0x01
0x00038906 1C02 ADD R2,R0,#0
0x00038908 3001 ADD R0,#0x01
0x0003890A 7812 LDRB R2,[R2,#0x00]
0x0003890C 2A00 CMP R2,#0x00
0x0003890E D1F9 BNE 0x00038904
0x00038910 1C08 ADD R0,R1,#0
0x00038912 4770 BX LR

0x00038914 E59FC000 LDR R12,[PC]
0x00038918 E12FFF1C BX R12
0x0003891C 00038921 DD 0x00038921
memcpy:
0x00038920 B430 PUSH {R4-R5}
0x00038922 1C03 ADD R3,R0,#0
0x00038924 1C18 ADD R0,R3,#0
0x00038926 E005 B 0x00038934
0x00038928 1C0C ADD R4,R1,#0
0x0003892A 7825 LDRB R5,[R4,#0x00]
0x0003892C 1C04 ADD R4,R0,#0
0x0003892E 7025 STRB R5,[R4,#0x00]
0x00038930 3101 ADD R1,#0x01
0x00038932 3001 ADD R0,#0x01
0x00038934 1C14 ADD R4,R2,#0
0x00038936 3A01 SUB R2,#0x01
0x00038938 2C00 CMP R4,#0x00
0x0003893A D1F5 BNE 0x00038928
0x0003893C 1C18 ADD R0,R3,#0
0x0003893E BC30 POP {R4-R5}
0x00038940 4770 BX LR



вызываем
memcpy (0x40002390, 0x00038910, 0x10)

... и попадаем в DataAbort.

Содержимое регистров:
R0 = 0x0000008A
R1 = 0x00038911
R2 = 0x0000000D
R3 = 0x40002390
R4 = 0x0000008A
R5 = 0x0000001C
R13 (SP) = 0x40002524
R14 (LR) = 0x00038936
R15 (PC) = 0x00000010
SPSR = 0x00000030


Какая-то мистика.
memcpy (0x40002390, 0x00038920, 0x10)
memcpy (0x40002390, 0x00038900, 0x10)
- всё проходит нормально.
Если выполнять этот код по шагам, всё также проходит нормально.
Запускаем в обычном режиме - получите переход на 0x10...

Экспериментально установлено, что если дошагать до
0x00038926 E005 B 0x00038934
дальше всё работает. Если запустить на выполнение до этой строки, получаем ошибку.


Сделал тестовую функцию - она тоже работает нормально!
Да, она действительно работает, оптимизатор до неё не добрался.
Адреса менял - пофигу...
CODE

void Test (void)
{
char buff[128];
int ptr = 0x038910; // этот адрес менял уже из-под отладчика

while (1)
{
memcpy (buff, ptr, 16);
}

}


Собственно, вопрос. Что это было?!

Нарисовал CopyMem, которая копирует по 4 байта за раз - она работает хорошо. Но хочется разобраться...


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 22 2009, 19:36
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Можно сказать только, что кто-то у Вас портит R0, и это не memcpy. Прерывания выключать пробовали?
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Jul 23 2009, 09:36
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Угу, портится R0 и STRB вполне законно вылетает.

Только вот всё остальное-то работает!

В частности, в том же самом месте эта memcpy нормально вызывается 0x3890 раз (собственно, считываем прошивку целиком кусочками по 16 байт в один и тот же буфер). И дальше нормально выполняется, если указатель руками переставить...

Прерывания выключать не пробовал, т.к. всё развалится. Хотя вот Test() вызывал до разрешения прерываний, оно работает.

Освобожусь чуток, постараюсь разобраться...


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 20:34
Рейтинг@Mail.ru


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