Перейти к содержанию
    

LPC2138, memcpy и DataAbort

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

 

Исходные данные:

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

процессор LPC2138

 

 

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

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

дальше всё работает. Если запустить на выполнение до этой строки, получаем ошибку.

 

 

Сделал тестовую функцию - она тоже работает нормально!

Да, она действительно работает, оптимизатор до неё не добрался.

Адреса менял - пофигу...

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

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

}

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно сказать только, что кто-то у Вас портит R0, и это не memcpy. Прерывания выключать пробовали?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

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

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...