|
вызов супервизора SVCall в STM32 |
|
|
|
Aug 31 2018, 10:27
|
Группа: Участник
Сообщений: 9
Регистрация: 26-08-18
Пользователь №: 107 048
|
В cortex M есть команда вызова системных функций, SVC при исполнении этой команды процессор переходит в обработчик исключения супервизора.
что должно происходить в обработчике исключения супервизора, вызов системной функции прямо в обработчике? как то странно это. логичнее на мой взгляд было бы выйти из обработчика передав управление вызываемой функции в привилегированном режиме. незнаю как только реализовать это попроще
как правильно должно это все работать по задумкам разработчиков?
Сообщение отредактировал FFFF - Aug 31 2018, 10:38
|
|
|
|
|
Aug 31 2018, 11:51
|
Группа: Участник
Сообщений: 9
Регистрация: 26-08-18
Пользователь №: 107 048
|
спасибо. и как это сделано в любой rtos? системная функция вызывается прямо в обработчике исключения и возвращается в него?
я с Си плохо знаком, пробираться в дебрях rtos для меня мучение
Сообщение отредактировал FFFF - Aug 31 2018, 11:53
|
|
|
|
|
Aug 31 2018, 12:17
|
Гуру
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713
|
Цитата(FFFF @ Aug 31 2018, 13:27) что должно происходить в обработчике исключения супервизора, вызов системной функции прямо в обработчике? как то странно это. логичнее на мой взгляд было бы выйти из обработчика передав управление вызываемой функции в привилегированном режиме. незнаю как только реализовать это попроще Как душе угодно: можно прям оттуда вызвать, можно оттуда только программно активировать другое прерывание или задачу, где всё и свершить. Цитата(x893 @ Aug 31 2018, 14:44) Как это сделано в любой RTOS. Видимо uCOS-II - не любая. Так как вообще никак не использует SVC.
|
|
|
|
|
Sep 1 2018, 14:48
|
Местный
Группа: Участник
Сообщений: 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 и поехали }
|
|
|
|
|
Sep 1 2018, 15:21
|
Группа: Участник
Сообщений: 9
Регистрация: 26-08-18
Пользователь №: 107 048
|
А меня жаба душит транжирить SVC на такое... Вообще не хочу, чтобы FreeRTOS использовала SVC.
а Вы как бы распорядились SVC?
Сообщение отредактировал FFFF - Sep 1 2018, 15:22
|
|
|
|
|
Sep 1 2018, 16:27
|
Гуру
Группа: Свой
Сообщений: 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 Что-то у Вас мухи с котлетами намешаны Зачем ещё и указатель стека прерываний на начало стека из таблицы прерываний ставить? Это вобщем-то не относится к данной задаче. Хотя конечно хозяин - барин. Цитата(Arlleex @ Sep 1 2018, 17:48) mov r0, #0 msr control, r0 Опять мухи с котлетами. Тогда сюда ещё до кучи и инициализацию пинов впендюрить можно. Да и вроде - невозможно так записать что-то в 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 не хватит? Для чего???
|
|
|
|
|
Sep 2 2018, 06:03
|
Группа: Участник
Сообщений: 9
Регистрация: 26-08-18
Пользователь №: 107 048
|
если передавать номер функции в регистре перед вызовом SVC то можно и больше чем 256
еще и быстрее будет. надо лишь в регистр ввести значение необходимой функции. 2 команды если число больше 255, не придется доставать значение из SVC в обработчике
Сообщение отредактировал FFFF - Sep 2 2018, 06:14
|
|
|
|
|
Sep 2 2018, 06:49
|
Группа: Участник
Сообщений: 9
Регистрация: 26-08-18
Пользователь №: 107 048
|
собственно я сам до этого дошел, думаю это лежит на поверхности
я Си не знаю, 516 строка для меня темный лес
Сообщение отредактировал FFFF - Sep 2 2018, 06:51
|
|
|
|
|
Sep 2 2018, 08:50
|
Местный
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264
|
Цитата(FFFF @ Sep 1 2018, 18:21) А меня жаба душит транжирить SVC на такое... Вообще не хочу, чтобы FreeRTOS использовала SVC.
а Вы как бы распорядились SVC? Сам факт того, что это прерывание используется только 1 раз... Ужас. Даже если оно мне не нужно - у меня внутренний когнитивный диссонанс Цитата(jcxz @ Sep 1 2018, 19:27) Что-то у Вас мухи с котлетами намешаны Зачем ещё и указатель стека прерываний на начало стека из таблицы прерываний ставить? Это вобщем-то не относится к данной задаче. Хотя конечно хозяин - барин. ... Опять мухи с котлетами. Тогда сюда ещё до кучи и инициализацию пинов впендюрить можно. ... Зачем? Не мое. Это я сейчас порт на Cortex-M4 открыл и сюда вставил Нужно оно там или не нужно - это другой вопрос, конечно же. Цитата Да и вроде - невозможно так записать что-то в 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 ISB лишняя, да... Там весь порт кривущий, но работает. Вычищаю потихоньку, что нужно мне. Вот и решил заморочиться, избавившись от такого не очень, на мой взгляд, разумного использования SVC. Я еще понимаю, если бы оно вызывалось раз в день. Но тут только при старте приложения... Цитата PS: Да и, как видно по приведённому Вами коду, FreeRTOS использует не всю SVC, а только SVC 0. Остальные 255 - свободны. Неужто Вам 255 не хватит? Для чего??? Мне-то хватит. Просто хочу свои SVC как можно короче сделать, без лишних телодвижений. А подход, предложенный индусами-портировщиками, мне не очень нравится. Поэтому и гадаю, как красиво сделать Цитата В uCOS вообще не заморачиваются: они изначально заносят в PSP=0, а потом просто программно возбуждают PendSV (как для любого программного переключения контекста), а в ISR PendSV делают проверку если PSP==0 (начальный старт первой задачи) - просто пропускают сохранение контекста сразу переходя к восстановлению контекста самой приоритетной задачи. Конечно при этом в переключатель контекста добавляется одна лишняя команда, но имхо - это несущественно. Воот. Вот это уже другое дело. Я тоже рассматривал такой вариант, но как раз лишние пару инструкций проверки травят душу перфекциониста Вот и думаю, что это сделать, скорее всего, можно без прерываний и лишних телодвижений в переключателе контекста (я хотел бы, чтобы он был как можно короче и быстрее). Просто нужно исхитриться и восстановить весь контекст выполнения первой запускаемой задачи.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|