Однако, рутины - это гуд, как оказалось. Давно хотел это проверить.
Ты заставил меня это сделать.
Решил сразу на боевом проекте, без прелюдий.
Итак
Исходный проект.
Пользую кипарисовские (Cypress) девайсы. На самой маленькой из них cyble-012011-00 (BLE, 16k/128k) такой функционал: 8 термисторов + hr202 (влажность), bootloader (OTA FU), конфигуратор (маяк, RTC, long sleep, периоды измерений), кольцевой архив (в ОЗУ).
Как работает.
Две задачи FreeRTOs:
task_ble - ble стек,
task_measure - различные периодические измерения (здесь ADC термисторов, hr202, батарейки).
Понятно, что вытесняющая многозадачность от RTOS здесь не нужна (как и в 100% моих проектах на этих железках), поэтому от FreeRTOS используется только taskYIELD() c полностью остановленным sys_tick таймером (никаких tickless idle mode ).
Что не нравилось.
В общем, мы имеем две задачи с переключением их контекстов (стеков) через системный вызов FreeRTOS. Было ясно, что 16k RAM (flash в меньшей степени меня интересовал) расходуется, мягко говоря, не оптимально, а конкретно так:
для кольцевого буфера оставалось место только на 100 отсчетов (hr202 + термистор), занятость flash 95%,
размер образа для обновления OTA FU 64k
Что правилось.
RTOS выпилил полностью. Задачи заменились соответствующими рутинами (самыми простыми, без изысков) обе задачи возвращают один и тот же тип класса resumable. Исходники с рутинами с++ компилируется отдельно с дополнительными опциями:
-fcoroutines -std=c++20
-fno-exceptions
-fno-threadsafe-statics
-fnothrow-opt
Для пущей оптимизации переопределен глобальный new (чтобы выпилить стандартный terminate)
Да ребята-демократы, вам бы матчасть изучать.
Почитайте спецификацию, хотя бы что такое RPA.
Не смешите гусей. ))
Hi!
Однако, рутины - это гуд, как оказалось. Давно хотел это проверить.
Ты заставил меня это сделать.
Решил сразу на боевом проекте, без прелюдий.
Итак
Исходный проект.
Пользую кипарисовские (Cypress) девайсы. На самой маленькой из них cyble-012011-00 (BLE, 16k/128k) такой функционал: 8 термисторов + hr202 (влажность), bootloader (OTA FU), конфигуратор (маяк, RTC, long sleep, периоды измерений), кольцевой архив (в ОЗУ).
Как работает.
Две задачи FreeRTOs:
task_ble - ble стек,
task_measure - различные периодические измерения (здесь ADC термисторов, hr202, батарейки).
Понятно, что вытесняющая многозадачность от RTOS здесь не нужна (как и в 100% моих проектах на этих железках), поэтому от FreeRTOS используется только taskYIELD() c полностью остановленным sys_tick таймером (никаких tickless idle mode ).
Что не нравилось.
В общем, мы имеем две задачи с переключением их контекстов (стеков) через системный вызов FreeRTOS. Было ясно, что 16k RAM (flash в меньшей степени меня интересовал) расходуется, мягко говоря, не оптимально, а конкретно так:
для кольцевого буфера оставалось место только на 100 отсчетов (hr202 + термистор), занятость flash 95%,
размер образа для обновления OTA FU 64k
Что правилось.
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);
}
В сухом остатке.
Кольцевой буфер 1000 отсчетов (в 10 раз).
Заполненность flash 78%
Размер образа для обновления OTA FU 47k.
Коротенько, как то так.