Notice: Memcache::get(): Server localhost (tcp 11211) failed with: Connection refused (111) in /home/a146/www/we.easyelectronics.ru/engine/lib/external/DklabCache/Zend/Cache/Backend/Memcached.php on line 134
ОС как библиотека / Блог им. teplofizik / Сообщество EasyElectronics.ru

ОС как библиотека

Иногда внезапно возникает необходимость сделать какую-то работу в коде программы в синхронном режиме — то есть, не конечным автоматом, а просто дожидаясь результата каких-то действий. Например, скачать http-страничку, или, того хуже, https-страничку.

Но и тормозить основной цикл тоже как-то не очень хорошо. На этот случай есть известное решение — ОС.

Но если требуется допилить уже существующий проект с минимальным вмешательством в остальной код?
Вот мне стало интересно сделать мини-ОС, которая подключается к проекту как библиотека. То есть, делаем вызов какой-нибудь функции os_Init() и получаем возможность создавать потоки, не вмешиваясь в работу основного цикла. Он продолжает работать, как будто никакой ОС и нет, просто иногда управление передаётся дополнительным потокам.


ОС у меня была сделана когда-то из интереса под STM32F4, оставалось только перевести её в фоновый режим.
В аттаче лежит минимальный демо-пример для stm32f0discovery. Основной код выглядит так:

// Дополнительный поток #1, моргает зелёной лампочкой
void main2(uint32_t Arg)
{
    bool State = false;
    while(1)
    {
        led_Set(LED_GREEN, State = !State);
        delay_ms(Arg);
    }
}

// Дополнительный поток #2, моргает синей лампочкой
void main3(uint32_t Arg)
{
    bool State = false;
    while(1)
    {
        led_Set(LED_BLUE, State = !State);
        delay_ms(Arg);
    }
}

int main(void)
{
    // Запуск ОС
    // Первая запись таблицы процессов после выхода из функции будет оккупирована уже выполняемым сейчас кодом (main).
    thoto_Init();
    
    // Инициализация периферии (gpio, systick) и драйверов (светодиоды)
    drivers_Init();
    
    // Создадим поток #1
    // Зеленый светодиод моргает с частотой 1 Гц
    createprocess("main2", main2, 500);
    
    // Создадим поток #2
    // Синий светодиод моргает с частотой 2 Гц
    createprocess("main3", main3, 250);
    
    while(1)
    {
        // Делаем тут что угодно полезное, цикл свободен для любого использования
        // как если бы потоков не было.
    }
}


Метод достаточно прост: вместо стандартной функции Idle, которую можно встретить в любой уважающей себя ОС, будет вертеться главный цикл.
При инициализации в таблицу процессов вписываем выполняемый прямо сейчас код (PC,SP всё равно при выходе в прерывание сохранятся в стеке автоматом) жёстко под номером 1 и делаем ему фоновый приоритет — пока никому управление не нужно, будет вертеться именно он.
Процесс дополнительный может быть вызван в нужный момент — отработает свой алгоритм и завершится, как обычная функция (но параллельно и с задержками, и с ожиданием событий) или может работать как параллельный main.

ОС не описываю, там ничего особо интересного, просто было любопытно сделать что-то такое.
Просто как идея. Использовал пока такое в реальном проекте только один раз — пришлось подключать библиотеку, которая работала с tcp и читала и писала поток синхронно: read(...), write(...).
Файлы в топике: stm32f0_demo.zip

Комментарии (0)

RSS свернуть / развернуть
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.