5277 (5277) wrote,
5277
5277

Category:

core5277, пример многопоточности

  Здесь я привожу дампы логики при параллельном выполнении нескольких задач на микроконтроллере ATmega328. Да, тот самый, с которым работает большинство Arduino поклонников восхваляя торговую марку вместо производителей чипа.
  Здесь чип работает на частоте 16МГц, среди прочего он имеет один аппаратный UART(который в данном примере не используется), и аппаратную поддержку TWI(I2C) - она задействована.

  На первом скрине показаны три события:
  - чтение с микросхемы реального времени DS3231(аппаратный TWI)
  - логирование в порт(программный UART 115200 8N1)
  - передача пакета данных(своя реализация шины на базе программного UART 19200 8N1)

Чтение микросхемы и логирование выполняются в одной задаче, передача пакета в другой, и еще есть две: мигание сетодиодом и анализ портов(открыта/закрыта дверь), но в дампе их не видно.




Далее немного увеличим дамп каждого события:

  3-ий канал - передача пакета:


  0-ой и 1-ый канал - TWI:


  2-ой канал - логирование в порт:


Кстати в логе указано текущее время, количество свободной динамической памяти(1018 байт) и динамической памяти всего(1246 байт). На данном чипе всего 2048 байта памяти, 802 байта было потрачено на нужды ядра, из которых только 368 байт выделено под 16 байт переменных 23-х задач и 253 байта под заголовки этих задач. Т.е. реально на нужды ядра выделено 181 байт, из них 64 байта под стек, 75 байт под таблицу прерываний и 20 байт под таблицу программных таймеров. При этом в данной прошивке проинициализировано 6 драйверов и 5 задач.

  Думаю отдельно стоит рассмотреть точность таймингов для передачи данных. К примеру канал 3, скорость не большая 19200, но, здесь важно то, что таймер программный, предоставляется ядром, при этом для данной скорости расходуется ровно 1 тик таймера. Все используемые таймеры в ядре основаны на TIMER0, он же отсчитывает тики ядра(кванты).



  А здесь скорость 115200, не используются таймеры и прерывания. Логирование выполняется как обычный код задачи, просто подсчитаны такты и на время передачи октета прерывания блокируются.


Блокировка прерываний, особенно в многопоточной ОС может привести к плачевным последствиям, например такое логирование при передаче или приеме данных по программному UART обязательно приведет к ошибкам. Для этого будет введен функционал похожий на мьютексы.

  Главное, что мне доставляет удовольствие в данном увлечении, это написание самих исполняемых задач, они просты, там нет никакой сложной логики для контролирования ресурсов.
  Вот например код задачи для тестирования драйвера моей шины:
;---CONSTANTS--------------------------------------------
_BUS5277_TEST_HELLO:
    .db   "Hello",0x00

BUS5277_TEST_INIT:
    MCALL CORE5277_TASK_READY
;--------------------------------------------------------
_BUS5277_TEST_INFINITE_LOOP:
    LDI TEMP,TID_BUS5277_DRV
    LDI YH,high(_BUS5277_TEST_HELLO)|0x80
    LDI YL,low(_BUS5277_TEST_HELLO)
    LDI TEMP_EH,BUS5277_RESP_OK
    LDI TEMP_EL,0x06
    MCALL CORE5277_DRIVER_EXEC
 
    LDI TEMP,0x01
    MCALL CORE5277_TASK_WAIT_1S

    MJMP _BUS5277_TEST_INFINITE_LOOP
    RET



И да, core5277 имеет прямое отношение к текущему проекту, так как прошивки всех устройств будут реализованы на моем ядре. Это, по большему счету сводит программирование на ассемблере к уровню программирования на Бейсике.

Update: А вто как выглядят три задачи типа
BURN_INIT:
    MCALL CORE5277_TASK_READY
    SBI PINB,PB2
    RJMP PC-0x01


Tags: core5277, Ардуино
Subscribe
  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 0 comments