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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> вызов супервизора SVCall в STM32
FFFF
сообщение Aug 31 2018, 10:27
Сообщение #1





Группа: Участник
Сообщений: 9
Регистрация: 26-08-18
Пользователь №: 107 048



В cortex M есть команда вызова системных функций, SVC
при исполнении этой команды процессор переходит в обработчик исключения супервизора.

что должно происходить в обработчике исключения супервизора, вызов системной функции прямо в обработчике?
как то странно это. логичнее на мой взгляд было бы выйти из обработчика передав управление вызываемой функции в привилегированном режиме. незнаю как только реализовать это попроще

как правильно должно это все работать по задумкам разработчиков?

Сообщение отредактировал FFFF - Aug 31 2018, 10:38
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Aug 31 2018, 11:27
Сообщение #2


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(FFFF @ Aug 31 2018, 13:27) *
как правильно должно это все работать по задумкам разработчиков?

Если выйти из обработчика, то кончится и привилегированный режим.
Поэтому обработчик вызывает функцию, она возвращается в обработчик и обработчик закрывается, а если надо, то перед этим сделает переключение контекста.
Смотрите как сделано в Mbed OS.
Go to the top of the page
 
+Quote Post
x893
сообщение Aug 31 2018, 11:44
Сообщение #3


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

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



Как это сделано в любой RTOS.
Go to the top of the page
 
+Quote Post
FFFF
сообщение Aug 31 2018, 11:51
Сообщение #4





Группа: Участник
Сообщений: 9
Регистрация: 26-08-18
Пользователь №: 107 048



спасибо.
и как это сделано в любой rtos? системная функция вызывается прямо в обработчике исключения и возвращается в него?

я с Си плохо знаком, пробираться в дебрях rtos для меня мучение

Сообщение отредактировал FFFF - Aug 31 2018, 11:53
Go to the top of the page
 
+Quote Post
x893
сообщение Aug 31 2018, 11:54
Сообщение #5


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

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



Там в основном ассемблер. Для изучения сильно помогает Source Insight.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Aug 31 2018, 12:13
Сообщение #6


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(x893 @ Aug 31 2018, 14:44) *
Как это сделано в любой RTOS.

Не в любой. Зависит от порта.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 31 2018, 12:17
Сообщение #7


Гуру
******

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



Цитата(FFFF @ Aug 31 2018, 13:27) *
что должно происходить в обработчике исключения супервизора, вызов системной функции прямо в обработчике?
как то странно это. логичнее на мой взгляд было бы выйти из обработчика передав управление вызываемой функции в привилегированном режиме. незнаю как только реализовать это попроще

Как душе угодно: можно прям оттуда вызвать, можно оттуда только программно активировать другое прерывание или задачу, где всё и свершить.

Цитата(x893 @ Aug 31 2018, 14:44) *
Как это сделано в любой RTOS.

Видимо uCOS-II - не любая. Так как вообще никак не использует SVC.
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Sep 1 2018, 13:44
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата(jcxz @ Aug 31 2018, 15:17) *
Видимо uCOS-II - не любая. Так как вообще никак не использует SVC.

А во FreeRTOS вообще плохо поступили - SVC используется один раз в жизни -только при запуске первой задачи crying.gif Но это дело можно под себя перепилить, если что, как мне кажется.

Сообщение отредактировал Arlleex - Sep 1 2018, 14:48
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Sep 1 2018, 14:48
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Открыл вот порт FreeRTOS на Cortex-M4.
В этой RTOS переключатель контекста построен по следующей модели:
1. Сохранить контекст прерванной задачи;
2. Переключить указатель на контекст новой задачи;
3. Восстановить регистры из этого контекста.

Все 3 пункта выполняются в обработчике исключения PendSV.
Для того, чтобы начать выполнение, нужно как-то запустить первую задачу.
FreeRTOS предлагает решение на исключении SVC
Код
__asm void prvStartFirstTask( void )
{
    PRESERVE8

    /* Use the NVIC offset register to locate the stack. */
    ldr r0, =0xE000ED08
    ldr r0, [r0]
    ldr r0, [r0]
    /* Set the msp back to the start of the stack. */
    msr msp, r0
    /* Clear the bit that indicates the FPU is in use in case the FPU was used
    before the scheduler was started - which would otherwise result in the
    unnecessary leaving of space in the SVC stack for lazy saving of FPU
    registers. */
    mov r0, #0
    msr control, r0
    /* Globally enable interrupts. */
    cpsie i
    cpsie f
    dsb
    isb
    /* Call SVC to start the first task. */
    svc 0
    nop
    nop
}

Сам обработчик
Код
__asm void vPortSVCHandler( void )
{
    PRESERVE8

    /* Get the location of the current TCB. */
    ldr    r3, =pxCurrentTCB
    ldr r1, [r3]
    ldr r0, [r1]
    /* Pop the core registers. */
    ldmia r0!, {r4-r11, r14}
    msr psp, r0
    isb
    mov r0, #0
    msr    basepri, r0
    bx r14
}


А меня жаба душит транжирить SVC на такое... Вообще не хочу, чтобы FreeRTOS использовала SVC.
Есть идея сделать почти все то же самое, что в обработчике, но вызовом функции: только вместо bx r14 перевести процессор на использование PSP + непривилегированный режим. Ну и регистры все восстановить, потому как не в прерывании находимся. И это будет возможно сделать, поскольку после сброса CPU находится в привилегированном режиме, соответственно все системные функции работы с регистрами специального назначения ему разрешены.
Нужно попробовать, но хотелось бы выслушать критику... Работать будет?

Итого, что-то типа
Код
__asm void prvStartFirstTask( void )
{
    PRESERVE8

    /* Use the NVIC offset register to locate the stack. */
    ldr r0, =0xE000ED08
    ldr r0, [r0]
    ldr r0, [r0]
    /* Set the msp back to the start of the stack. */
    msr msp, r0
    /* Clear the bit that indicates the FPU is in use in case the FPU was used
    before the scheduler was started - which would otherwise result in the
    unnecessary leaving of space in the SVC stack for lazy saving of FPU
    registers. */
    mov r0, #0
    msr control, r0
    /* Globally enable interrupts. */
    cpsie i
    cpsie f
    dsb
    isb

        // Финт ушами

        /* Get the location of the current TCB. */
    ldr    r3, =pxCurrentTCB
    ldr r1, [r3]
    ldr r0, [r1]
    // восстановить контекст первой задачи в нужной последовательности
    ldmia r0!, {тут список регистров R0-R12, LR, XPSR в правильном порядке}
    msr psp, r0
    isb
    mov r0, #0
    msr    basepri, r0
        // а тут восстановить PC и поехали
}
Go to the top of the page
 
+Quote Post
FFFF
сообщение Sep 1 2018, 15:21
Сообщение #10





Группа: Участник
Сообщений: 9
Регистрация: 26-08-18
Пользователь №: 107 048



А меня жаба душит транжирить SVC на такое... Вообще не хочу, чтобы FreeRTOS использовала SVC.

а Вы как бы распорядились SVC?

Сообщение отредактировал FFFF - Sep 1 2018, 15:22
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 1 2018, 16:27
Сообщение #11


Гуру
******

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



Цитата(Arlleex @ Sep 1 2018, 17:48) *
ldr r0, =0xE000ED08
ldr r0, [r0]
ldr r0, [r0]
msr msp, r0

Что-то у Вас мухи с котлетами намешаны wink.gif
Зачем ещё и указатель стека прерываний на начало стека из таблицы прерываний ставить?
Это вобщем-то не относится к данной задаче. Хотя конечно хозяин - барин.

Цитата(Arlleex @ Sep 1 2018, 17:48) *
mov r0, #0
msr control, r0

Опять мухи с котлетами. Тогда сюда ещё до кучи и инициализацию пинов впендюрить можно. laughing.gif
Да и вроде - невозможно так записать что-то в CONTROL. Нужно юзать EXC_RETURN.

Цитата(Arlleex @ Sep 1 2018, 17:48) *
dsb
isb

Зачем?

Цитата(Arlleex @ Sep 1 2018, 17:48) *
ldmia r0!, {тут список регистров R0-R12, LR, XPSR в правильном порядке}

Ну вообще-то тут R0-R3,R12,LR,XPSR совершенно лишние.
Вроде как достаточно восстановить R4-R11, занести в LR нужное значение и сделать BX LR (сымитировать возврат из прерывания с переключением на нужный стек и в нужный режим).

Цитата(Arlleex @ Sep 1 2018, 17:48) *
msr psp, r0
isb
mov r0, #0
msr basepri, r0
// а тут восстановить PC и поехали

В результате режим процессора Вы не переключили и он остался в handler-режиме.
Для переключения нужно юзать BX LR с правильным значением в нём.
И опять же - ISB тут лишняя.

В uCOS вообще не заморачиваются: они изначально заносят в PSP=0, а потом просто программно возбуждают PendSV (как для любого программного переключения контекста), а в ISR PendSV делают проверку если PSP==0 (начальный старт первой задачи) - просто пропускают сохранение контекста сразу переходя к восстановлению контекста самой приоритетной задачи.
Конечно при этом в переключатель контекста добавляется одна лишняя команда, но имхо - это несущественно.

PS: Да и, как видно по приведённому Вами коду, FreeRTOS использует не всю SVC, а только SVC 0. Остальные 255 - свободны. Неужто Вам 255 не хватит? Для чего???
Go to the top of the page
 
+Quote Post
FFFF
сообщение Sep 2 2018, 06:03
Сообщение #12





Группа: Участник
Сообщений: 9
Регистрация: 26-08-18
Пользователь №: 107 048



если передавать номер функции в регистре перед вызовом SVC то можно и больше чем 256

еще и быстрее будет. надо лишь в регистр ввести значение необходимой функции. 2 команды если число больше 255, не придется доставать значение из SVC в обработчике

Сообщение отредактировал FFFF - Sep 2 2018, 06:14
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Sep 2 2018, 06:38
Сообщение #13


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(FFFF @ Sep 2 2018, 09:03) *
если передавать номер функции в регистре перед вызовом SVC то можно и больше чем 256
еще и быстрее будет. надо лишь в регистр ввести значение необходимой функции. 2 команды если число больше 255, не придется доставать значение из SVC в обработчике

Цитируя давайте ссылки на первоисточник:
ARM Mbed OS, файл rtx_ketnel.c, строка 516

Go to the top of the page
 
+Quote Post
FFFF
сообщение Sep 2 2018, 06:49
Сообщение #14





Группа: Участник
Сообщений: 9
Регистрация: 26-08-18
Пользователь №: 107 048



собственно я сам до этого дошел, думаю это лежит на поверхности

я Си не знаю, 516 строка для меня темный лес

Сообщение отредактировал FFFF - Sep 2 2018, 06:51
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Sep 2 2018, 08:50
Сообщение #15


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата(FFFF @ Sep 1 2018, 18:21) *
А меня жаба душит транжирить SVC на такое... Вообще не хочу, чтобы FreeRTOS использовала SVC.

а Вы как бы распорядились SVC?

Сам факт того, что это прерывание используется только 1 раз... Ужас.
Даже если оно мне не нужно - у меня внутренний когнитивный диссонанс biggrin.gif

Цитата(jcxz @ Sep 1 2018, 19:27) *
Что-то у Вас мухи с котлетами намешаны wink.gif
Зачем ещё и указатель стека прерываний на начало стека из таблицы прерываний ставить?
Это вобщем-то не относится к данной задаче. Хотя конечно хозяин - барин.

...

Опять мухи с котлетами. Тогда сюда ещё до кучи и инициализацию пинов впендюрить можно. laughing.gif

...

Зачем?

Не мое. Это я сейчас порт на Cortex-M4 открыл и сюда вставил laughing.gif Нужно оно там или не нужно - это другой вопрос, конечно же.

Цитата
Да и вроде - невозможно так записать что-то в CONTROL. Нужно юзать EXC_RETURN.

В привилегированном режиме можно. EXC_RETURN используется при входе в прерывание и выходе из него.

Цитата
Ну вообще-то тут R0-R3,R12,LR,XPSR совершенно лишние.
Вроде как достаточно восстановить R4-R11, занести в LR нужное значение и сделать BX LR (сымитировать возврат из прерывания с переключением на нужный стек и в нужный режим).

В этом и фишка, что я хочу полностью избавиться от SVC, передать управление на первую задачу без использования прерывания. Поэтому я и предложил восстановить весь регистровый стек, потому как мы не в прерывании еще находимся, поэтому R0-R3, R12, LR, XPSR восстановить нужно будет.
Интересно вот, что будет если в привилегированном режиме потока записать EXC_RETURN в LR со значениями (PSP + Thread Mode) и сделать BX LR... Какой-нибудь Usage Fault, скорее всего.

Цитата
В результате режим процессора Вы не переключили и он остался в handler-режиме.
Для переключения нужно юзать BX LR с правильным значением в нём.
И опять же - ISB тут лишняя.

Повторюсь, что режим процессора должен оставаться в Thread. Если бы прерывание было - как в исходном примере, то я не задался бы целью обойти использование SVC sad.gif
ISB лишняя, да... Там весь порт кривущий, но работает. Вычищаю потихоньку, что нужно мне. Вот и решил заморочиться, избавившись от такого не очень, на мой взгляд, разумного использования SVC. Я еще понимаю, если бы оно вызывалось раз в день. Но тут только при старте приложения...

Цитата
PS: Да и, как видно по приведённому Вами коду, FreeRTOS использует не всю SVC, а только SVC 0. Остальные 255 - свободны. Неужто Вам 255 не хватит? Для чего???

Мне-то хватит. Просто хочу свои SVC как можно короче сделать, без лишних телодвижений. А подход, предложенный индусами-портировщиками, мне не очень нравится. Поэтому и гадаю, как красиво сделать wink.gif

Цитата
В uCOS вообще не заморачиваются: они изначально заносят в PSP=0, а потом просто программно возбуждают PendSV (как для любого программного переключения контекста), а в ISR PendSV делают проверку если PSP==0 (начальный старт первой задачи) - просто пропускают сохранение контекста сразу переходя к восстановлению контекста самой приоритетной задачи.
Конечно при этом в переключатель контекста добавляется одна лишняя команда, но имхо - это несущественно.

Воот. Вот это уже другое дело. Я тоже рассматривал такой вариант, но как раз лишние пару инструкций проверки травят душу перфекциониста biggrin.gif
Вот и думаю, что это сделать, скорее всего, можно без прерываний и лишних телодвижений в переключателе контекста (я хотел бы, чтобы он был как можно короче и быстрее). Просто нужно исхитриться и восстановить весь контекст выполнения первой запускаемой задачи.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th April 2024 - 13:22
Рейтинг@Mail.ru


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