Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум разработчиков электроники ELECTRONIX.ru _ scmRTOS _ nRF52 BLE SDK (Cortex M3) SVC

Автор: ox0001 Jan 23 2017, 09:52

Здравствуйте!

кто нибудь пытался вести разработку на scmRTOS для nRF52 BLE SDK ?

Как сочетать API взаимодействия BLE стэка (прошивки) работающее по SVC вызовам ?

спасибо!


Автор: AHTOXA Jan 23 2017, 10:08

Вот тут недавно что-то проскакивало про NRF: http://electronix.ru/redirect.php?https://electronix.ru/forum/index.php?showtopic=139472.

Автор: ox0001 Jan 23 2017, 14:19

OK спасибо!

Автор: a9d Apr 7 2017, 00:16

В nRF SDK есть же примеры с FreeRTOS. Да и nRF52 это Cortex-M4F

Автор: esaulenka Aug 3 2018, 07:39

Цитата(AHTOXA @ Jan 23 2017, 13:08) *
Вот тут недавно что-то проскакивало про NRF: http://electronix.ru/redirect.php?https://electronix.ru/forum/index.php?showtopic=139472.

Коллега sevstels, к сожалению, забил на требование нордика "никогда не отключайте прерывания при работе softdevice'а".
А может, он и не использовал софтдевайс - в примере нет, в сообщениях на форуме "все дураки, я свой велосипед строю"...


Цитата(a9d @ Apr 7 2017, 03:16) *
В nRF SDK есть же примеры с FreeRTOS. Да и nRF52 это Cortex-M4F

Есть, да.
Надо взять порт scmRTOS от STM'ки, переписать критическую секцию, таймер (systick в nrf52 вернули обратно, но он батарейку жрёт), и отладить.
Ну и в процессе раскурить, что они с приоритетами прерываний сделали (нормального описания я не нашёл, к сожалению, только в духе "trust me, i know what i'm doing").

Наличие готового примера и грамотного человека, который это делал, процесс должно сильно ускорить. Ну да ладно, будет повод самому описать...

Автор: esaulenka Aug 8 2018, 08:43

Продолжаем.

Коллеги, у меня вопрос.
Техподдержка Nordic запрещает отключать прерывания, используемые softdevice'ом (это стек блютус, исполняемый на том же процессоре, что и пользовательский код; поставляется как единый hex с документированными точками входа).

Для организации критических секций у них предусмотрен следующий костыль:
http://electronix.ru/redirect.php?https://github.com/NordicPlayground/nrf52-ble-app-uart-long-range/blob/master/s140_nrf52840_6.0.0-6.alpha/s140_nrf52840_6.0.0-6.alpha_API/include/nrf_nvic.h#L437
sd_nvic_critical_region_enter(), sd_nvic_critical_region_exit()
Т.е:
- запретить все прерывания
- сохранить во временную переменную регистры разрешённых прерываний
- обнулить эти регистры (точнее, записать маску "только прерывания softdevice'а)
- разрешить прерывания

При этом:
- допустимые ядром приоритеты прерываний - 0..7
- софтдевайс использует приоритеты 0 и 4 (во всяком случае, так в последнем SDK 15.0, в документации это не описано)

Ваше мнение, как лучше:
- обернуть эти функции в OS::TCritSect
- оставить обычную критическую секцию - они всё равно делают disable_irq()/enable_irq(), несмотря на заявление техподдержки "прерывания отключать нельзя, ни на 1 секунду, ни на 1 микросекунду"
- сделать прерывания ОС и пользовательского кода с приоритетом 5..7 и разобраться с запретом через изменение регистра BASEPRI

Автор: jcxz Aug 8 2018, 09:13

Цитата(esaulenka @ Aug 8 2018, 11:43) *
sd_nvic_critical_region_enter(), sd_nvic_critical_region_exit()
Т.е:
- запретить все прерывания
- сохранить во временную переменную регистры заррешённых прерываний
- обнулить эти регистры (точнее, записать маску "только прерывания softdevice'а)
- разрешить прерывания
Ваше мнение, как лучше:

Я бы последовал их рекомендации, но с оптимизацией её: сохранять/обнулять не все биты разрешения прерываний, а только важные для данной конкретной критической секции.
Такая оптимизация позволит сэкономить и такты и байты.

Автор: esaulenka Aug 8 2018, 10:04

Не вижу особой пользы.
Как оно экономит? Уменьшается latency, но (забыл сказать) мне оно некритично. Общая скорость не растёт, размер не уменьшается.

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

Автор: jcxz Aug 8 2018, 10:47

Цитата(esaulenka @ Aug 8 2018, 13:04) *
Не вижу особой пользы.
Как оно экономит? Уменьшается latency, но (забыл сказать) мне оно некритично. Общая скорость не растёт, размер не уменьшается.

В смысле "как"? Работа с одной переменной ведь проще/быстрее чем с несколькими. Не находите?
Не знаю сколько прерываний в вашем МК, но в моём сейчас их биты масок растянулись аж на 4-е 32-битных регистра. Это значит что в критической секции которая без разбора запрещает всё, надо будет все 4 регистра прочитать, сохранить и записать в них маскирующие значения. Что довольно-таки долго и в каждом таком месте требует 4 слова по 32 бита.
В то время как данная критическая секция может нужна для защиты всего от одного прерывания (только один регистр можно сохранить, одно прерывание запретить).

И если Вы говорите что латентность Вас не беспокоит, то к чему тогда вообще был вопрос? Вы же спрашивали насчёт наиболее оптимального способа? Или нет?

Цитата(esaulenka @ Aug 8 2018, 13:04) *
Геморрой только добавляется, т.к. эту оптимизацию руками надо делать, и постоянно следить, чтобы из N-цати кртитических секций выбрать нужную.

Геморрой это только если без головы делать. С умом если, то достаточно написать макрос в котором на входе задаётся маска интересующих прерываний, а внутри он по этой маске всю работу и сделает.
И вообще-то в серьёзных системах там так и есть - для каждого защищаемого объекта - своя критическая секция. Например в винде. А то что Вы называете критической секцией, это просто запрет прерывания и в действительности не является критической секцией.

PS: Кстати - маскирование прерываний через NVIC не запрещает все прерывания. Есть ещё Systick и PendSV и другие fault-ы (если они у Вас используются).

Автор: esaulenka Aug 8 2018, 11:58

Цитата(jcxz @ Aug 8 2018, 13:47) *
В смысле "как"? Работа с одной переменной ведь проще/быстрее чем с несколькими. Не находите?
Не знаю сколько прерываний в вашем МК,

Он указан. Точнее, указано семейство, но внутри семейства они достаточно одинаковые.

Цитата(jcxz @ Aug 8 2018, 13:47) *
Что довольно-таки долго и в каждом таком месте требует 4 слова по 32 бита.

В решении "запретить всё", кстати, хранилище только одно.

Цитата(jcxz @ Aug 8 2018, 13:47) *
И если Вы говорите что латентность Вас не беспокоит, то к чему тогда вообще был вопрос? Вы же спрашивали насчёт наиболее оптимального способа? Или нет?

Вопрос про конкретную реализацию. Каковая состоит из моего софта и чужого стека.
И если меня латентность не очень волнует, то для софтдевайса требования к латентности указаны жёсткие (хоть и несоответствующие реальному состоянию дел).

Цитата(jcxz @ Aug 8 2018, 13:47) *
это просто запрет прерывания и в действительности не является критической секцией.

О как.

Цитата(jcxz @ Aug 8 2018, 13:47) *
PS: Кстати - маскирование прерываний через NVIC не запрещает все прерывания. Есть ещё Systick и PendSV и другие fault-ы (если они у Вас используются).

Да, действительно.
Используется ли PendSV - Вы можете посмотреть в исходниках операционной системы, которую мы обсуждаем.

Вообще, очень прошу ознакомиться с обсуждаемой темой. Мне не очень интересно разговаривать о сферических конях, мне хочется запустить конкретную ОС на конкретном чипе. О конях - пожалуйста, в прекрасный раздел "общение".

Автор: jcxz Aug 8 2018, 12:26

Цитата(esaulenka @ Aug 8 2018, 14:58) *
И если меня латентность не очень волнует, то для софтдевайса требования к латентности указаны жёсткие (хоть и несоответствующие реальному состоянию дел).

Странный подход к делу. Т.е. - будет ли работать этот самый девайс в составе вашего изделия или нет - Вам фиолетово?

Цитата(esaulenka @ Aug 8 2018, 14:58) *
Он указан. Точнее, указано семейство, но внутри семейства они достаточно одинаковые.
Используется ли PendSV - Вы можете посмотреть в исходниках операционной системы, которую мы обсуждаем.

Может мне за Вас ещё и код написать? smile3046.gif

Автор: esaulenka Aug 8 2018, 17:08

Я ожидал советов от авторов операционки в духе "В ядре наиболее длинные крит. секции, пожалуй, в OS::channel. Если длина устраивает - можно тупо запрещать прерывания. BASEPRI не используется, потому что ...".
А разговор "вот если бы у рыб была шерсть, то на ней были бы блохи" - повторюсь, в "общение". Спасибо.


Возвращаясь к теме.
Класс TCritSect и enable/disable _context_switch() делают __set_BASEPRI() - ноль и (0xFE <<(8 - кол-во бит приоритета)).

Вроде б работает...

Также, на мой взгляд, правильнее
INLINE void raise_context_switch() { SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; }
вместо
INLINE void raise_context_switch() { *((volatile uint32_t*)0xE000ED04) |= 0x10000000; }
ключевое отличие - просто запись вместо модификации.

Автор: AHTOXA Aug 9 2018, 06:32

Цитата(esaulenka @ Aug 8 2018, 13:43) *
Ваше мнение, как лучше:
- обернуть эти функции в OS::TCritSect
- оставить обычную критическую секцию - они всё равно делают disable_irq()/enable_irq(), несмотря на заявление техподдержки "прерывания отключать нельзя, ни на 1 секунду, ни на 1 микросекунду"
- сделать прерывания ОС и пользовательского кода с приоритетом 5..7 и разобраться с запретом через изменение регистра BASEPRI


Я за второй вариант. Если они сами запрещают прерывания, то и нам можно. В коде ОС критические секции достаточно короткие, на всякий случай потестировать связь - и считать, что порядок.

Для полного спокойствия можно (временно) добавить в TCritSect замеры максимального времени запрета прерывания в тиках DWT. Кстати, интересно будет попробоватьsm.gif

Цитата(esaulenka @ Aug 8 2018, 22:08) *
Также, на мой взгляд, правильнее
INLINE void raise_context_switch() { SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; }
вместо
INLINE void raise_context_switch() { *((volatile uint32_t*)0xE000ED04) |= 0x10000000; }
ключевое отличие - просто запись вместо модификации.


Странно, я был уверен, что исправлял "|=" на "="... Видимо, это было в каком-то другом месте. Обязательно исправлю, спасибо.

Автор: Axel Aug 13 2018, 12:38

Прошу прощения за вероятный оффтоп...
В последней (15-й) версии nRF52 SDK появилась симпатичная примочка: task manager. Скромная (есть только task и event), но экстремально легкая. Под спектр задач, которй я могу представить себе для, например nRF52832, вполне годится.

Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)