Перейти к содержанию
    

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

 

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

 

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

 

спасибо!

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот тут недавно что-то проскакивало про NRF: ссылка.

Коллега sevstels, к сожалению, забил на требование нордика "никогда не отключайте прерывания при работе softdevice'а".

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

 

 

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

Есть, да.

Надо взять порт scmRTOS от STM'ки, переписать критическую секцию, таймер (systick в nrf52 вернули обратно, но он батарейку жрёт), и отладить.

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Продолжаем.

 

Коллеги, у меня вопрос.

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

 

Для организации критических секций у них предусмотрен следующий костыль:

https://github.com/NordicPlayground/nrf52-b...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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

sd_nvic_critical_region_enter(), sd_nvic_critical_region_exit()

Т.е:

- запретить все прерывания

- сохранить во временную переменную регистры заррешённых прерываний

- обнулить эти регистры (точнее, записать маску "только прерывания softdevice'а)

- разрешить прерывания

Ваше мнение, как лучше:

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

Такая оптимизация позволит сэкономить и такты и байты.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не вижу особой пользы.

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не вижу особой пользы.

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

В смысле "как"? Работа с одной переменной ведь проще/быстрее чем с несколькими. Не находите?

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

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

 

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

 

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

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В смысле "как"? Работа с одной переменной ведь проще/быстрее чем с несколькими. Не находите?

Не знаю сколько прерываний в вашем МК,

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

 

Что довольно-таки долго и в каждом таком месте требует 4 слова по 32 бита.

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

 

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

Вопрос про конкретную реализацию. Каковая состоит из моего софта и чужого стека.

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

 

это просто запрет прерывания и в действительности не является критической секцией.

О как.

 

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

Да, действительно.

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я ожидал советов от авторов операционки в духе "В ядре наиболее длинные крит. секции, пожалуй, в 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; }

ключевое отличие - просто запись вместо модификации.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ваше мнение, как лучше:

- обернуть эти функции в OS::TCritSect

- оставить обычную критическую секцию - они всё равно делают disable_irq()/enable_irq(), несмотря на заявление техподдержки "прерывания отключать нельзя, ни на 1 секунду, ни на 1 микросекунду"

- сделать прерывания ОС и пользовательского кода с приоритетом 5..7 и разобраться с запретом через изменение регистра BASEPRI

 

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

 

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

 

Также, на мой взгляд, правильнее

INLINE void raise_context_switch() { SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; }

вместо

INLINE void raise_context_switch() { *((volatile uint32_t*)0xE000ED04) |= 0x10000000; }

ключевое отличие - просто запись вместо модификации.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прошу прощения за вероятный оффтоп...

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 8/3/2018 at 3:39 PM, esaulenka said:

Коллега sevstels, к сожалению, забил на требование нордика "никогда не отключайте прерывания при работе softdevice'а".

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

Только увидел сообщение.

Вы батенька зря "волну не гоните"...

В моем примере и не предусматривалось использование стека от Нордика, поэтому мне было не интересно, что их индусы написали в "рекомендациях". А не нужен их стек по причине ущербности, не работает он с многими моделями тлф в отличии от моего самопального. Добиться от них исправлений ошибок так и не удалось.  Если бы Вам тема была интересна, мой мылоадрес в порте был указан.

 

 

Изменено пользователем Gradient

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...