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

 
 
 
Reply to this topicStart new topic
Harvester
сообщение Mar 25 2016, 14:46
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846



Добрый день.
Имеется следующий код (Cortex-M3)
Код
static Process prlist[2];
...
uint32_t *p = (uint32_t*)0x10000000;
prlist[0].context.sp = *p;
...
void _proc_stack_init(int id)
{
    _proc_stack_push(&prlist[id].context.sp, 0x01000000);
    _proc_stack_push(&prlist[id].context.sp, 0);
    _proc_stack_push(&prlist[id].context.sp, 0);
}

Который вызывает ассемблерную функцию
Код
_proc_stack_push:
    /* R0 - stack, R1 - value */
    push  {r2}
    ldr   r2, [r0]  // Грузим в R2 содержимое по адресу [R0]
    stmdb r2!,{r1}  // Сохраняем по адресу в R2 с преддекрементом содержимое R1, в R2 записывается новое значение
    str   r2, [r0]  // Сохраняем R2 по адресу [R0]
    pop   {r2}
    bx    lr

Хочу переписать все это на чистом Си, но что-то не получается.
Код
void _proc_stack_init(int id)
{
    uint32_t *sp_ptr = &prlist[id].context.sp;

    *--sp_ptr = 0x01000000;
    *--sp_ptr = 0;
    *--sp_ptr = 0;
}

Такое ощущение, что здесь нужно использовать двойной указатель, но вот как - ума не приложу. В общем, заблудился в трех соснах.
Подскажите, пожалуйста


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 25 2016, 14:53
Сообщение #2


Гуру
******

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



Код
uint32_t *sp_ptr = &prlist[id].context.sp;

& лишний
Go to the top of the page
 
+Quote Post
Harvester
сообщение Mar 25 2016, 17:32
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846



Цитата(aaarrr @ Mar 25 2016, 17:53) *
...
& лишний

Все равно что-то не то получается. В исходном варианте функция _proc_stack_push() изменяет значение переданного ей указателя, а в новом варианте, судя по листингу, ничего похожего нет:
Код
_proc_stack_init:
  ldr    r3, .L20          
  add    r0, r3, r0, lsl #4
  ldr    r3, [r0, #12]    
  mov    r2, #16777216    
  str    r2, [r3, #-4]    
  movs   r2, #0          
  str    r2, [r3, #-8]    
  str    r2, [r3, #-12]    
  bx     lr


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 25 2016, 18:47
Сообщение #4


Гуру
******

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



Можно менять указатель, а можно использовать смещение. Компилятор выбрал последний вариант.
Go to the top of the page
 
+Quote Post
Harvester
сообщение Mar 25 2016, 19:12
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846



Цитата(aaarrr @ Mar 25 2016, 21:47) *
Можно менять указатель, а можно использовать смещение. Компилятор выбрал последний вариант.

Но мне-то нужно и сам указатель менять.
Кажется дошло - добавил в конце
Код
prlist[id].context.sp = (uint32_t)sp_ptr;

Теперь результат похож на правду:
Код
ldr    r3, .L20          
mov    r2, #16777216    
add    r0, r3, r0, lsl #4
ldr    r3, [r0, #12]    
str    r2, [r3, #-4]    
movs    r2, #0          
str    r2, [r3, #-8]    
str    r2, [r3, #-12]!  
str    r3, [r0, #12]    ; <- финальное значение r3 пишется обратно
bx    lr


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
gosha-z
сообщение Mar 29 2016, 18:41
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 327
Регистрация: 30-10-05
Пользователь №: 10 288



Какой-то взрыв мозга. А декремент-то зачем тут предполагается???
Go to the top of the page
 
+Quote Post
Harvester
сообщение Mar 30 2016, 07:19
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846



Цитата(gosha-z @ Mar 29 2016, 21:41) *
Какой-то взрыв мозга. А декремент-то зачем тут предполагается???

Да там весь код - взрыв мозга. Такое вот наследство досталось. laughing.gif
А конкретно этот фрагмент подготавливает стековый фрейм (реально там 8 значений), который в прерывании подставляется вместо штатного. В результате возврат из прерывания происходит не в место прерывания, а на специальную функцию. Т.е. своеобразный аналог SVI-прерывания для вызова из других прерываний. wacko.gif


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 31 2016, 06:31
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Harvester @ Mar 30 2016, 13:19) *
А конкретно этот фрагмент подготавливает стековый фрейм (реально там 8 значений), который в прерывании подставляется вместо штатного. В результате возврат из прерывания происходит не в место прерывания, а на специальную функцию. Т.е. своеобразный аналог SVI-прерывания для вызова из других прерываний. wacko.gif

Вполне себе штатный метод переключения контекстов задач в любой ОС на Cortex-M. Делается обычно внутри ISR PendSV. Изначально такой стековый фрейм создаётся при создании задачи (+остальные регистры), а в ISR PendSV делается переключение с одного стекового фрейма на другой. Остальные регистры контекста перегружаются программно.
Ваша часть кода как раз похожа на часть кода создания новой задачи в ОС (создание стекового фрейма).
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 14:56
Рейтинг@Mail.ru


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