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

 
 
 
Reply to this topicStart new topic
> Вопросы по STM32f10x на Keil, Ошибка с PUSH, загрузка массивов, теневые регистры.
Omnicake
сообщение Apr 30 2014, 02:57
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 30 2014, 04:26
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 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). При входе в прерывание некоторые регистры автоматически сохраняются
в стек, при выходе - извлекаются. Отключить этот механизм нельзя. Соответственно ответ на вопрос: "не сохраняются".
Go to the top of the page
 
+Quote Post
Omnicake
сообщение Apr 30 2014, 04:52
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 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, так как это делается автоматически?
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 30 2014, 05:50
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



чтобы получить доступ ко 2 элементу массива надо делать так

объявить массив
int32_t array[10];

выбрать 2 элемент массива
array[1];

к чему трудно поддерживаемый ассемблер в элементарных операциях? После того как сделаете то что хотите, можно проверить листинг на асме что получилось у компилятора, и если уж очень не понравиться переписать асемблерными вставками, но надо обязательно дать шанс компилятору, уверен что в вопросах копирования массивов и выбора их из памяти он вас не разочарует...
Go to the top of the page
 
+Quote Post
Omnicake
сообщение Apr 30 2014, 06:48
Сообщение #5


Участник
*

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



Использование ассемблера обусловлено спецификой проекта, скажем так, но ваш совет попробую. Спасибо большое за ответы.
Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 30 2014, 06:56
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 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, обработчики).
Go to the top of the page
 
+Quote Post
Omnicake
сообщение May 1 2014, 03:03
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 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?
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 1 2014, 05:42
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Вы поставили уровень оптимизации проекта на 0? Изначально он в кейле, например, дефалт, а это -2 а не 0. А оптимизит он здорово, потому код легко не узнать.
Go to the top of the page
 
+Quote Post
Omnicake
сообщение May 1 2014, 06:00
Сообщение #9


Участник
*

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



Нет, стоит нулевой уровень оптимизации.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 1 2014, 06:33
Сообщение #10


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
Omnicake
сообщение May 1 2014, 06:47
Сообщение #11


Участник
*

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



Извиняюсь, в дальнейшем не повторится. Спасибо большое за разъяснения, буду пробовать дальше.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 1 2014, 07:30
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 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, так как написана очень плохо.
Go to the top of the page
 
+Quote Post

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

 


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


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