|
|
  |
Вопросы по STM32f10x на Keil, Ошибка с PUSH, загрузка массивов, теневые регистры. |
|
|
|
Apr 30 2014, 02:57
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002

|
Здравствуйте, хотелось узнать несколько подробностей по поводу работы с микропроцессором STM32f10x в Keil uVision 5:
1) На процессорах C55x на ассемблере командами:
AMOV #Label, xar0 MOV dbl(*ar0), xar0 MOV dbl(*ar0), xar0 MOV *ar0, ac0
Метка Label была указателем на массив, заданный во внешнем файле C, первые две команды mov выгружали каким-то образом сначала адрес массива, потом его структуру, а потом отдельный элемент. Хотелось сделать аналог такой же выгрузки на STM32F10x но не нашел в Instruction Set аналога обозначения *ar0 – то есть выгрузки значения из адреса r0 (заменять на LDR?), а также что такое dbl и как зовется его аналог в Cortex-M3 командах.
2) Знаю, что в Cortex-M3 существуют так называемые "теневые регистры", которые, как я понял, включаются на момент прерывания. Как обозначаются эти регистры при работе с ними, и сохраняется ли их значения после выхода из прерывания?
Заранее спасибо.
Сообщение отредактировал Omnicake - Apr 30 2014, 04:22
|
|
|
|
|
Apr 30 2014, 04:26
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
1. Попробуйте push {r0}. В скобках можно передавать список регистров, например, push {r0-r3, lr}. 2. Не совсем понятна задача. Вот пример копирования массива (r0 - куда копировать, r1 - откуда копировать, r2 - сколько слов копировать) Код memcpy_dw_loop: ldr r3, [r1], #4 str r3, [r0], #4 subs r2, #1 bne memcpy_dw_loop 3. В Cortex-M3 теневых регистров нет (правда, есть два стека MSP и PSP). При входе в прерывание некоторые регистры автоматически сохраняются в стек, при выходе - извлекаются. Отключить этот механизм нельзя. Соответственно ответ на вопрос: "не сохраняются".
|
|
|
|
|
Apr 30 2014, 04:52
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002

|
1. Да, действительно нужно было регистры брать в фигурные скобки, спасибо. 2. Задача в том, что есть некий массив, в котором хранятся числа (например 1,2,3,4) из массива нужно в ассемблере вытаскивать только одно число, чтобы потом использовать его для сравнения. Как реализовать загрузку именно не всего массива, а одного числа на выбор (например только 2го по порядку, или последнего и.т.д.)? 3. Вот здесь http://www.arm.com/files/pdf/introToCortex-M3.pdf нашел такую строчку "To reduce gate count and enhance system flexibility the Cortex-M3 has migrated from the banked shadow register exception model of the ARM7 processor to a stack based exception model. When an exception takes place, the Program Counter, Program Status Register, Link Register and the R0-R3,R12 general purpose registers are pushed on to the stack." То есть как я понимаю перед входом и выходом в прерывание мне не нужно сохранять состояние регистров R0-R3, R12, LR, SR и PC, так как это делается автоматически?
|
|
|
|
|
Apr 30 2014, 06:48
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002

|
Использование ассемблера обусловлено спецификой проекта, скажем так, но ваш совет попробую. Спасибо большое за ответы.
|
|
|
|
|
Apr 30 2014, 06:56
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(Omnicake @ Apr 30 2014, 08:52)  Вот здесь http://www.arm.com/files/pdf/introToCortex-M3.pdf нашел такую строчку "To reduce gate count and enhance system flexibility the Cortex-M3 has migrated from the banked shadow register exception model of the ARM7 processor to a stack based exception model. When an exception takes place, the Program Counter, Program Status Register, Link Register and the R0-R3,R12 general purpose registers are pushed on to the stack." То есть как я понимаю перед входом и выходом в прерывание мне не нужно сохранять состояние регистров R0-R3, R12, LR, SR и PC, так как это делается автоматически? Написано, что ушли от модели теневых регистров, принятой в ARM7, к модели сохранения регистров на стеке. Ничего сохранять/восстанавливать не нужно, если в прерывании используются только указанные регистры. Вообще, в Cortex-M практически все можно делать на C (startup, обработчики).
|
|
|
|
|
May 1 2014, 03:03
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002

|
В дизассемблере происходят странные вещи: SUB sp,sp,#0x18 MOVS r2,#0x14 LDR r1,|L0.24| ADD r0,sp,#4 BL __aeabi_memcpy4 LDR r1,|L0.28| LDR r0,[sp,#0xc] STR r0,[r1,#0] ; x По метке |L0.28| находится DCD x По метке |L0.24| находится DCD ||.constdata||
__aeabi_memcpy4: PUSH {r4,lr} SUBS r2,r2,#0x20 BCC.W 0x080001FA LDM r1!,{r3-r4,r12,lr} SUBS r2,r2,#0x20 STM r0!,{r3-r4,r12,lr} LDM r1!,{r3-r4,r12,lr} STM r0!,{r3-r4,r12,lr} BCS.W 0x080001E4 LSLS r12,r2,#28 ITT CS LDM r1!,{r3-r4,r12,lr} STM r0!,{r3-r4,r12,lr} ITT MI LDM r1!,{r3-r4} STM r0!,{r3-r4} POP {r4,lr} LSLS r12,r2,#30 ITT CS LDR r3,[r1],#0x04 STR r3,[r0],#0x04 IT EQ BX lr
Это реакция на команду: int32_t array[5]={1,2,3,4,5}; x=array[2]; Я вообще не понимаю логику того, что там происходит и что такое __aeabi_memcpy4.
Я опишу еще раз подробнее то, что мне нужно сделать, возможно я просто неправильно задал вопрос: У меня есть файл task1.c содержащий простейшую команду и описание des1 ddd1={1,2,3}; где des1 ddd1 берется из header файла descriptors.h и выглядит так: typedef struct { int Status; int CurrentTic; int NumberTic; int Command; long CurrentPC; long StartPC; long CurrentSP; long StartSP; long CurrentSSP; long StartSSP; long temp; } des1; При импорте ddd1 в ассемблерную подпрограмму структура корректно грузится и задает значения Status=1, CurrentTic=2 и NumberTic=3, мне нужно там же в ассемблерной вставке вытащить из структуры в регистр значение, например Status и сравнить с 1. В микропроцессоре C55x это делалось последовательностью команд:
amov #TaskPointer, xar0 mov dbl(*ar0), xar0 mov dbl(*ar0), xar0 mov *ar0, ac0 ; getting Status
TaskPointer: .long TaskTableStart TaskTableStart: .long _ddd1 .long _ddd2 .long _ddd3 .long _ddd4 TaskTableEnd:
Как можно сделать то же самое, но на Cortex-M3?
|
|
|
|
|
May 1 2014, 06:00
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002

|
Нет, стоит нулевой уровень оптимизации.
|
|
|
|
|
May 1 2014, 06:33
|

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

|
Omnicake, используйте, пожалуйста, кнопочку  когда выкладываете код. Цитата(Omnicake @ May 1 2014, 06:03)  В дизассемблере происходят странные вещи: ... Это реакция на команду: int32_t array[5]={1,2,3,4,5}; x=array[2]; Я вообще не понимаю логику того, что там происходит и что такое __aeabi_memcpy4. Абсолютно ничего странного тут не происходит. Код SUB sp,sp,#0x18 // Сдвинули указатель стека на 24 байта, зарезервировав 20 байт под array и 4 байта под что-то еще MOVS r2,#0x14 // загрузили размер array в R2 LDR r1,|L0.24| // загрузили в R1 адрес {1, 2, 3, 4, 5} ADD r0,sp,#4 // загрузили в R0 адрес array[0] BL __aeabi_memcpy4 // вызвали библиотечную функцию memcpy, скопировали {1, 2, 3, 4, 5} в array LDR r1,|L0.28| // загрузили в R1 адрес x LDR r0,[sp,#0xc] // загрузили в R0 содержимое array[2] STR r0,[r1,#0]; x // сохранили R0 в х memcpy - стандартная библиотечная функция. Цитата(Omnicake @ May 1 2014, 06:03)  Как можно сделать то же самое, но на Cortex-M3? Код LDR r1,=ddd1 // загрузили в R1 адрес ddd1 LDR r1,[r0,#0] // загрузили в R0 ddd1.Status (0 - смещение Status относительно начала des)
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 1 2014, 06:47
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002

|
Извиняюсь, в дальнейшем не повторится. Спасибо большое за разъяснения, буду пробовать дальше.
|
|
|
|
|
May 1 2014, 07:30
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Omnicake @ Apr 30 2014, 08:57)  1) На процессорах C55x на ассемблере командами: AMOV #Label, xar0 MOV dbl(*ar0), xar0 MOV dbl(*ar0), xar0 MOV *ar0, ac0 си: { uint ac0 = *(typ *)*(void **)*(void **)Label; } typ здесь - это или signed short или unsigned short (в зависимости от соотв.флага C55-ядра). асм Cortex: Код LDR R0, =Label;или ADR R0, Label - если Label находится в const-секции рядом с кодом LDR R0, [R0] LDR R0, [R0] LDRSH R0, [R0] ;или LDRH R0, [R0] - см. выше ;R0==AC0 PS: Давненько не имел дела с C55x, может что напутал. Но до сих пор помню, что конструкция приведённая Вами вызовет кучу stalls на C55x, так как написана очень плохо.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|