Pull to refresh

Comments 11

Спасибо, очень круто!
Подумывал тоже применить корутины на Stm, но, как понял из описания, они используют динамическую память, требуя наличия операторов new/delete. Можете подсказать (самому все осилить выглядит слишком сложным), так ли это и как вы с этим справились?

Добрый день. Для промиса можно определить new и delete операторы. Я постараюсь это в следующих статьях рассмотреть, планирую в связке с FreeRTOS посмотреть это. В данном случае, т.к. это proof of concept- менеджменту памяти не уделил внимание. Но обязательно постараюсь это показать дальше. Материала получилось много для одного захода.

В дополнение к посту выше. Аллокация происходит не всегда. Более подробно это в статьях Lewis Baker можно глянуть.

Да, эти статье в его блоге и статья на Хабре:

https://habr.com/ru/post/519464/

Тут были затронуты моменты про определение new delete для Promise для корутин.

поставил бы "+", да кармы не хватает.

Весьма интересно почитать, хоть пока и не во всем разобрался. Утащил в закладки, на досуге поразберусь ещё.

Немного вопросов, если не возражаете:
1. LittleFS портировали самостоятельно или есть готовый порт для нордиков?
2. стек BLE использовали? если да, то чей?

Добрый. Little FS в процессе портирования сейчас. LVGL для графики портирована, свой порт писал, все что нужно было - вызвать lv_tick() для тиков в библиотеке и lv_task_handler(), для "прокрутки" задач в библиотеке + реализовать функцию заполнения экранной области (прямоугольника) и по окончанию заполнения вызвать lv_flush_ready.

https://github.com/ValentiWorkLearning/GradWork/blob/2bb2b8a045bc45c3c5d2f5d6251779f43b2032b7/Firmware/graphics/platform/gs_platform_layer.cpp#L30

На счёт стека BLE- использую от Nordic с S112 softdevice реализацией. Слышал, что есть open-source( например в прошивке Pine time), но пока руки не дошли разобраться.

из open-source есть apache nimBLE, а сами нордики предлагают зефир (zephyr). Смотрел и одно, и второе, пока не ясно что проще в использовании будет. Коллеги по работе настоятельно рекомендуют apache.

графика пока не сильно интересует, а вот ФС которая умеет в равномерный износ и работать с NAND флешкой было бы интересно посмотреть. LittleFS, судя по описанию, как раз это умеет.

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

тема интересная, но понять что-то очень сложно из-за отсуствия картины с высоты птичьего полета и перегруза деталями

Hi!

Однако, рутины - это гуд, как оказалось. Давно хотел это проверить.

Ты заставил меня это сделать.

Решил сразу на боевом проекте, без прелюдий.

Итак

  1. Исходный проект.

    Пользую кипарисовские (Cypress) девайсы. На самой маленькой из них cyble-012011-00 (BLE, 16k/128k) такой функционал: 8 термисторов + hr202 (влажность), bootloader (OTA FU), конфигуратор (маяк, RTC, long sleep, периоды измерений), кольцевой архив (в ОЗУ).

  2. Как работает.

    Две задачи FreeRTOs:

    task_ble - ble стек,

    task_measure - различные периодические измерения (здесь ADC термисторов, hr202, батарейки).

    Понятно, что вытесняющая многозадачность от RTOS здесь не нужна (как и в 100% моих проектах на этих железках), поэтому от FreeRTOS используется только taskYIELD() c полностью остановленным sys_tick таймером (никаких tickless idle mode ).

  3. Что не нравилось.

    В общем, мы имеем две задачи с переключением их контекстов (стеков) через системный вызов FreeRTOS. Было ясно, что 16k RAM (flash в меньшей степени меня интересовал) расходуется, мягко говоря, не оптимально, а конкретно так:

    для кольцевого буфера оставалось место только на 100 отсчетов (hr202 + термистор), занятость flash 95%,

    размер образа для обновления OTA FU 64k

  4. Что правилось.

    RTOS выпилил полностью. Задачи заменились соответствующими рутинами (самыми простыми, без изысков) обе задачи возвращают один и тот же тип класса resumable. Исходники с рутинами с++ компилируется отдельно с дополнительными опциями:

    -fcoroutines -std=c++20 

    -fno-exceptions 

    -fno-threadsafe-statics 

    -fnothrow-opt

    Для пущей оптимизации переопределен глобальный new (чтобы выпилить стандартный terminate)

    using namespace std;

    void * operator new(size_t size)

    {

        return malloc(size); 

  5. В сухом остатке.

    Кольцевой буфер 1000 отсчетов (в 10 раз).

    Заполненность flash 78%

    Размер образа для обновления OTA FU 47k.

Коротенько, как то так.

Sign up to leave a comment.

Articles