API проекта автоматизации 5277. Структура данных ответа на запрос выбора локации.

Для коммуникации между собой таких узлов как клиент, контроллер и сервер я использую бинарный протокол.  Моя Java библиотека, с реализацией этого протокола, может преобразовывать его в JSON.  Для удобства чнетия я привожу описание структуры именно на JSON.

  *Это больше ознакомительная часть, чтобы иметь представление как оно работает. Вся детальная информация будет описана в отдельной документации.

  Здесь я опущу заголовочные данные пакета и рассмотрю только тело:


SCB - блок сценариев
LOCATIONS - блок локаций


TIMESTAMP - метка времени(в миллисекундах) последнего изменения сценариев, для определения актуальности данных
SCENARIO_GROUPS - блок  с группами сценариев


ID - идентификатор группы сценариев
LOCATION_ID - идентификатор локации, к которой привязана данная группа
DISABLED - сстояние группы(заблокирована или нет)
NAME - имя группы
SCENARIOS - блок сценариев данной группы


ID - идентификатор сценария
DISABLED - сстояние сценария(заблокирован или нет)
NAME - имя сценария
COMMENT - комментарий к сценарию
PARAMS - блок параметров


ID - идентификатор параметра
TYPE_ID - тип параметра
VALUE - данные параметра(структура и данные зависят от типа параметра)
*детально параметры сценария будут описаны отдельно

Блок SCB рассмотрен, возвращаюсь к верхним элементам.

ID - идентификатор локации
SERIAL - серийный номер контроллера(десятеричная форма), к которому привязана локация
NAME - имя локации
ICON - имя иконки локации
COMMENT - комментарий к локации
INTERROGATE_PERIOD_ID - идентификатор периода опроса устройств
AGGREGATION_PERIOD_ID - идентификатор периода выгрузки данных в БД для статистики
DISABLED - сстояние локации(заблокирован или нет)
IS_LINK - признак локации из другого проекта
PLACES - блок помещений в данной локации
GATEWAYS - блок шлюзов для конечных устройств
DEVICES - блок конечных устройств
GROUPS - группы конечных устройств(для режима вывода наборов показаний, вместо упорядоченного списка устройств с показаниями)
PERMS - блок разрешений, в рамках локации, для пользователей
DATA - блок с данными


ID - идентификатор помещения
NAME - имя помещения
ICON - имя иконки помещения
COMMENT - комментарий к помещению


ID - идентификатор шлюза
TYPE_ID - идентификатор типа шлюза
DEVICE_ID - идентификатор устройства в линейке устройств производителя
VENDOR_ID - идентификатор производителя
PARAMS - параметры устройства(ниже будут описаны на примере конечного устройства)
OWNER_IFACE_ID - идентфикатор физического порта интерфейса к которому подключено данное устройство(входящий).
IFACE - физический порт иннтерфейса который соединен с устройством к которому подключается данное устройство.


ID - идентифкатор интерфейса
IFACE_TYPE_ID - идентификатор типа интерфейса(например UART)
IFACE_NUM - порядковый номер интерфейса(например '0' - UART0)
PARAMS - блок параметров интерфейса


ID - идентификатор параметра
EXT_PARAM_ID - идентфикатор параметра из табличных данных описания набора интерфейсов и параметров каждого типа шлюза(дает гибкость системе, позволяя расширять систему буквально налету)
TYPE_ID - идентификатор типа параметра
SUBTYPE_ID - подтип идентификатора параметра(позволяет описать несколько параметров одного типа)

 Возвращаемся назад.

ID - идентификатор конечного устройства
TYPE_ID - идентификатор типа конечного устройства
NAME - имя конечного устройства
PLACE_ID - идентификатор помещения
COMMENT - комментарий к конечному устройству
INTERROGATE_PERIOD_ID - идентификатор периода опроса конкретного устройства
DISABLED - сстояние устройства(заблокирован или нет)
PARAMS - блок параметров устройства
DEVICE_ID - идентификатор устройства в линейке устройств производителя
VENDOR_ID - идентификатор производителя
GATEWAY_ID - шлюз, к которому подключено данное устройство, null - подключено непосредственно к контроллеру
ICON - имя иконки конечного устройства
AGGREGATION_PERIOD_ID - идентификатор периода выгрузки данных конкретного устройства в БД для статистики
AGGREGATION_EVENT_ID - идентификатор события вне периодической выгрузки данных конкретного устройства в БД для статистики
EXTRASCAN - признак поддержки конкретным устройством функционала экстренного опроса конечных устройств
PERMS - блок разрешений в рамках данного устройства для пользователей(аналогичен PERMS в описании LOCATION)
OWNER_IFACE_ID - идентфикатор физического порта интерфейса к которому подключено данное устройство(входящий).
IFACE - физический порт иннтерфейса который соединен с устройством к которому подключается данное устройство(аналогичен IFACE в GATEWAY).


ID - идентификатор параметра
PARAM_ID  - идентификатор типа параметра
VALUE - значение параметра
SUBTYPE_ID - подтип параметра(например для параметра 'Имя показания' здесь содержится идентификатор типа показания)

Возвращаемся назад.

ID - идентфикатор группы
NAME - имя группы
ICON - имя иконки группы
PLACE_ID - идентификатор помещения
COMMENT - комментарий к группе
*все вышеперечисленные параметры используются аналогично как и в DEVICE
SORT - значение для сорировки групп
ITEMS - блок элементов группы


ID - идентификатор элемента
DEVICE_ID - идентификатор конечного устройства
MEASURE_TYPE_ID - идентфикатор типа показания
NAME - имя показания
SORT - значение для сортировки элементов


ID - идентификатор разрешения
USER_ID - идентификатор пользователя
TYPE_ID - идентификатор типа разрешения


ID - идентфикатор локации
DEVICES - блок данных конечных устройств


ID - идентифкатор конечного устройства
MEASURES - блок показаний конечного устройства


TYPE_ID - идентификатор типа показания устройства
VALUE - значение показания устрйоства


Как сказал ранее, здесь далеко не вся информация, запросов и различных типов ответов большое количество.

Кроме описания структуры и данных таких параметров как значения PARAMS есть еще большое количество табличных данных, в которых описаны практически все данные с которыми работает система.
К примеру, если рассматривать показания, то в таблицах можно найти их типы, иднетификатор текста для словарей, идентификатор единицы измерения, идентификатор типа данных и цвет.
В свою очередь единица измерения содержит идентификатор текста для словарей, идентификатор базовой единицы измерения и множитель. Т.е. система понимает, к примеру, как амперы, так и миллиамперы и может их, при необходимости, преобразовать.

Все это дает некоторую гибкость системе и позволяет ее достаточно легко расширять без участия разработчика.

core5277 - ядро на ассемблере для ATmega, поддержка ATmega16

Сегодня я ввел поддержку ATmega16 в своем ядре.

По сути, если задачи(как и задумано) используют функции ядра и драйвера, то их код будет идентичен для ATmega16,ATmega88,ATmega328. Понятно, что ввести поддержку после ATmega16 таких как ATmega8,48,168 не составит большого труда.

Единственное но, это конечно ресурсы, объем памяти разный, из-за этого есть ограничение по количеству задач и драйверов, например для ATMega16/88 я выставил максимальное общее количество - 8, для ATMega328 - 23. Такие проблемы, как отсутствие команд CALL и разные таблицы прерываний я решил.

Пока я еще не столкнулся с проблемой, например, когда на МК нет аппаратного TWI. Но для работы с I2C в моем ядре нужно использовать драйвер. Т.е. для МК без аппаратного TWI необходимо за место драйвера аппаратного TWI подгрузить драйвер программного TWI.

ZX Spectrum, продолжение.

Сегодня я устроил холивар на одном из каналов телеграмма с тематикой железа под Спектрум.

Вкратце все было в стиле Си говно, а я тупой. Собственно чего еще ожидать от фанатиков Си. Но вот только от Спектрумистов любви к Си я не ожидал. Похоже это просто не правильные пчелы.

Буду ли я дальше что-то делать в своем проекте для Спектрум сообщества? Наверное да, но больше не для них, а ради себя, не зря же я купил 300 рублевую сетевую карту за 3 тысячи. Просто для того, чтобы показать, что мой проект может работать даже на Спектруме, пусть и частично.

И да, про Спектрум я не забыл. Где-то через пару недель ко мне придет сетевая карта для него.
Ось и среду разработки я уже приметил.
Первое, что я сделаю - это управление устройствами через telnet или http.

Есть другая мега задача - велосипед - свой GUI с логической частью на удаленном сервере, что-то типа тонкого клиента. И при чем тут Sun Microsystems если я даже не читал о подобном решении?...
Да, есть задумка реализовать функционал тонкого клиента на разные устройства, но это большая работа, и выполняться будет неспеша. Зато я смогу любое свое решение размещать под любую ос или железку.

5277, гараж

Не прошло и 5 лет, и вот я в гараже.



Первое размещение моей железки в гараже. Пока только мониторим тепреатуру и влажность. Сеть обеспечивает GSM соединение.

Главное 'стабильность':

core5277, регистры

  Семейство AVR имеет 32 регистра, первые 16 регистров обозначены как 'source' и не могут быть использованы в некоторых командах.
  Из-за многопоточности ядру приходится, при переключении задач, сохранять в стек регистры. У каждой задачи свой собственный стек. Более того, в ядре есть узкие места, где нельзя использовать стек, но регистрами пользоваться необходимо.
  Держать в стеке все регистры для каждой задачи слишком жирно, да и зачем? Я считаю, что для задачи вполне достаточно остальных 16 регистров, тем более они используются гораздо чаще первых.

Поэтому одно из требований к драйверу или задаче - использовать только старшие 16 регистров.

  Также при инициализации ядра задаются имена регистрам:
.DEF    TEMP_L   = r16                ;Младший регистр общего назначения
.DEF    TEMP_H   = r17                ;Старший регистр общего назначения
.DEF    TEMP   = r18                ;Регистр общего назначения
.DEF   TEMP_EL   = r19                ;Младший расширенный регистр общего назначения
.DEF    TEMP_EH   = r20                ;Старший расширенный регистр общего назначения
.DEF    LOOP_CNTR   = r21                ;Регистр счета циклов
.DEF    FLAGS   = r22                ;Регистр флагов
.DEF    TRY_CNTR   = r23                ;Счетчик ошибок
.DEF    ACCUM   = r24                ;Аккумулятор
.DEF    DRIVER_ID   = r25                ;ИД драйвера, используется для удобства вызова драйвера


Остальные регистры уже имеют названия, кстати для них есть макросы работы со стеком:
  PUSH_X,PUSH_Y,PUSH_Z и аналогично POP_Z,POP_Y,POP_X

core5277, логирование

Сразу несколько изменений.

  Ранее логирование было вынесено в виде драйвера, при этом часть кода находилась в ядре.
Скорость UART логирования в порт(BAUDRATE) была 115200, что сулило большие проблемы так как при передаче октета прерывания запрещались.
Удобство было не очень, например часто приходилось писать конструкции вида:

LDI YH,high(_CORE5277_TEXT_STARTED)|0x80 ;ROM
LDI YL,low(_CORE5277_TEXT_STARTED)
MCALL CORE5277_LOG



Теперь так:
1) В основном файле проекта необходимо объявить LOGGING_PORT:
.SET    LOGGING_PORT                            = (PORTC<<4)|PC0
  После чего, в инициализации ядра произойдет подгрузка файла с функционалом для логирования и инициализация логирования.
  Если LOGGING_PORT не объявлять, то файл подгружен не будет, но все метки для логирования будут также доступны, и мы сэкономим сотни байт ПЗУ.

2) Скорость UART для логирования теперь 460800. При передачи байта прерывания также запрещаются, но теперь на передачу байта требуется ~22 микросекунды. Таймер к примеру тикает каждые 50 микросекунд. Т.е. в теории времени вполне достаточно для логирования и прерываний.

3) Добавлены процедуры логирования символа, байта, слова, строки, строки из ПЗУ.
Теперь предыдущий пример выглядит так:
LOG_ROM _LOGSTR_CORE_STARTED

4) В процессе монитор - процедура позволяющая логировать состояние задач и ядра. К приеру, при перезагрузки контроллера, если включено логирование, мы получим вот такой дамп:

---COREDUMP:
TID:01 STA:00 RAM:0000.00 STK:0000.00 VRS:00000000000000000000000000000000
TID:02 STA:84 RAM:03E1.13 STK:0B13.00 VRS:00000000000000000000000000000000
TID:03 STA:84 RAM:03F4.39 STK:0C21.00 VRS:00000000000000000000000000000000
TID:04 STA:84 RAM:0000.00 STK:0CE5.00 VRS:05040000000000000000000000000000
TID:05 STA:84 RAM:0000.00 STK:0DB9.00 VRS:04000000000000000000000000000000
TID:06 STA:84 RAM:0000.00 STK:0E5E.00 VRS:D0041201139E4A042D80000000000000
TID:07 STA:84 RAM:042D.13 STK:0F31.00 VRS:16252412062006000000000000000000
TID:08 STA:00 RAM:0000.00 STK:0000.00 VRS:00000000000000000000000000000000
TID:09 STA:03 RAM:0000.00 STK:08A4.1B VRS:53503A303846430D0A00200000000000
TID:0A STA:03 RAM:0000.00 STK:0889.17 VRS:00000000000000000000000000000000
TID:0B STA:00 RAM:0000.00 STK:0000.00 VRS:00000000000000000000000000000000
TID:0C STA:03 RAM:0000.00 STK:08BF.1B VRS:00000000000000000000000000000000
TID:0D STA:00 RAM:0000.00 STK:0000.00 VRS:00000000000000000000000000000000
TID:0E STA:00 RAM:0000.00 STK:0000.00 VRS:00000000000000000000000000000000
TID:0F STA:03 RAM:0440.0C STK:0872.1E VRS:00000000000000000000000000000000
TID:10 STA:00 RAM:0000.00 STK:0000.00 VRS:00000000000000000000000000000000
TID:11 STA:00 RAM:0000.00 STK:0000.00 VRS:00000000000000000000000000000000
TID:12 STA:00 RAM:0000.00 STK:0000.00 VRS:00000000000000000000000000000000
TID:13 STA:00 RAM:0000.00 STK:0000.00 VRS:00000000000000000000000000000000
TID:14 STA:00 RAM:0000.00 STK:0000.00 VRS:00000000000000000000000000000000
TID:15 STA:00 RAM:0000.00 STK:0000.00 VRS:00000000000000000000000000000000
TID:16 STA:00 RAM:0000.00 STK:0000.00 VRS:00000000000000000000000000000000
TID:17 STA:00 RAM:0000.00 STK:0000.00 VRS:00000000000000000000000000000000
---DONE


В нем видно:
- номер задачи и ее состояние,
- адрес выделенной динамической памяти и ее размер,
- адрес стека и его размер ,
- дамп 16 байт переменных.

Пока так, потом будет больше полезной информации.

Вот кстати, как пример, часть кода монитора:
...
    LOG_ROM _LOGSTR_COREDUMP
    LDI LOOP_CNTR,0x01
_LOG_COREDUMP__TASK_LOOP:
    LOG_ROM LOGSTR_NEW_LINE

    MOV TEMP,LOOP_CNTR
    LOG_ROM _LOGSTR_TID
    MCALL LOG_BYTE
    LOG_ROM LOGSTR_SPACE

    MOV TEMP,LOOP_CNTR
    MCALL _CORE5277_TASK_HEADER_GET

    LDD TEMP,Z+_CORE5277_TASK_STATE
    LOG_ROM _LOGSTR_STATE
    MCALL LOG_BYTE
    LOG_ROM LOGSTR_SPACE

    LDD TEMP_H,Z+_CORE5277_TASK_RAM_OFFSET+0x00
    LDD TEMP_L,Z+_CORE5277_TASK_RAM_OFFSET+0x01
    LDD TEMP,Z+_CORE5277_TASK_RAM_SIZE
    LOG_ROM _LOGSTR_RAM
    MCALL LOG_WORD
    LOG_ROM LOGSTR_DOT
    MCALL LOG_BYTE
    LOG_ROM LOGSTR_SPACE
    ...



update:
  У драйвера нет собственного стека, он работает в стеке вызванной задачи. В мониторе STK драйвера указывает на точку входа в драйвер после инициализации. Различить драйвер от задачи можно по старшему биту в STA.

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


core5277, примеры использования

  Пример освновного файла:
    ;Идентификаторы задач и драйверов(1-16)
    ;---DIREVER-IDS---
    .EQU    TID_LOG_DRV                                = 0x01
    .EQU    TID_PCINT_DRV                            = 0x02
    .EQU    TID_BUS5277_DRV                        = 0x03
    .EQU    TID_1WIRE_DRV                            = 0x04
    .EQU    TID_DS18B20_DRV                        = 0x05
    ;---TASK-IDS---
    .EQU    TID_MONITOR                                = 0x09
    .EQU    TID_LEDS                                    = 0x0a
    .EQU    TID_PCINT_CHECK                        = 0x0b
    .EQU    TID_BUS                                    = 0x0c
    .EQU    TID_TEMPERATURE                        = 0x0e

    ;---TIMER_IDS---
    .EQU    TIMER_BUS5277                            = 0x01
    ;---FLAG-IDS---
    .EQU    FLAG_PCINT_DOOR                        = 0x01
    .EQU    FLAG_PCINT_BUS5277_RX                = 0x02
    .EQU    FLAG_BUS5277_RX_BUSY                    = 0x03
    .EQU    FLAG_BUS5277_TX_BUSY                    = 0x04
    .EQU    FLAG_BUS5277_HAVE_DATA                = 0x05
    ;---
    .EQU    BUS5277_BUS_ADDR                        = 0x7f

;---INCLUDES---------------------------------------------
    ;Обязательный блок, добавляем всегда
    .INCLUDE "core5277_header328.asm"
    .INCLUDE "core5277.asm"
    ;Не обязательный, добавляем по мере необходимости
    .INCLUDE "core5277_ram.asm"
    .INCLUDE "drv5277_log.asm"
    .INCLUDE "drv5277_pcint8.asm"
    .INCLUDE "drv5277_bus5277.asm"
    .INCLUDE "drv5277_1wire.asm"
    .INCLUDE "drv5277_ds18b20.asm"
    ;Блок задач
    .INCLUDE    "task_monitor.asm"
    .INCLUDE "task_temperature.asm"
    .INCLUDE    "task_sim_leds.asm"


MAIN:
    ;Запрещение прерываний
    CLI
    ;Инициализация стека
    LDI TEMP_H,high(RAMEND)
    LDI TEMP_L,low(RAMEND)
    OUT SPH,TEMP_H
    OUT SPL,TEMP_L

    ;Инициализация ядра
    CALL CORE5277_INIT

    ;Инициализация драйвера логирования
    LDI DRIVER_ID,TID_LOG_DRV
    LDI TEMP,high(DRV_LOG_INIT)
    MOV r0,TEMP
    LDI TEMP,low(DRV_LOG_INIT)
    MOV r1,TEMP
    LDI TEMP_H,PORTC
    LDI TEMP_L,(1<<PC0)
    CALL CORE5277_DRIVER_CREATE

    ;Инициализация драйвера внешних прерываний
    LDI DRIVER_ID,TID_PCINT_DRV
    LDI TEMP,high(DRV_PCINT_INIT)
    MOV r0,TEMP
    LDI TEMP,low(DRV_PCINT_INIT)
    MOV r1,TEMP
    CALL CORE5277_DRIVER_CREATE

    ;Инициализация драйвера шины 5277
    LDI DRIVER_ID,TID_BUS5277_DRV                                    ;Driver id
    LDI TEMP,high(DRV_BUS5277_INIT)                                ;Driver init offset
    MOV r0,TEMP
    LDI TEMP,low(DRV_BUS5277_INIT)
    MOV r1,TEMP
    LDI XH,(PORTD<<4|PD0)                                            ;RX pin
    LDI XL,(PORTD<<4|PD1)                                            ;TX pin
    LDI YH,(PORTB<<4|PB0)                                            ;DR pin
    LDI YL,(PORTB<<4|PB2)                                            ;TX led pin
    LDI ZH,BUS5277_BUS_ADDR                                            ;Bus Addr
    LDI TEMP_H,FLAG_BUS5277_RX_BUSY                                ;RX busy flag id
    LDI TEMP_L,FLAG_BUS5277_TX_BUSY                                ;TX busy flag id
    LDI LOOP_CNTR,FLAG_BUS5277_HAVE_DATA                        ;ES have data flag id
    LDI TEMP_EH,TID_PCINT_DRV                                        ;PCINT driver id
    LDI TEMP_EL,FLAG_PCINT_BUS5277_RX                            ;PCINT RX flag id
    LDI ACCUM,TIMER_BUS5277                                            ;Soft timer id
    ;CALL CORE5277_DRIVER_CREATE

    ;Инициализация 1wire
    LDI DRIVER_ID,TID_1WIRE_DRV
    LDI TEMP,high(DRV_1WIRE_INIT)
    MOV r0,TEMP
    LDI TEMP,low(DRV_1WIRE_INIT)
    MOV r1,TEMP
    LDI TEMP_H,PORTB
    LDI TEMP_L,(1<<PB2)
    CALL CORE5277_DRIVER_CREATE

    ;Инициализация DS18B20
    LDI DRIVER_ID,TID_DS18B20_DRV
    LDI TEMP,high(DRV_DS18B20_INIT)
    MOV r0,TEMP
    LDI TEMP,low(DRV_DS18B20_INIT)
    MOV r1,TEMP
    LDI ACCUM,TID_1WIRE_DRV
    CALL CORE5277_DRIVER_CREATE

    ;Инициализация монитора
    LDI TEMP,TID_MONITOR
    MOV TASK_ID,TEMP
    LDI TEMP,high(MONITOR_INIT)
    MOV r0,TEMP
    LDI TEMP,low(MONITOR_INIT)
    MOV r1,TEMP
    LDI TEMP,(0<<CORE5277_TASK_MODEBITS_NSUSP)
    MOV r2,TEMP
    CALL CORE5277_TASK_CREATE

    ;Инициализация задачи мигания светодиодов
    LDI TEMP,TID_LEDS
    MOV TASK_ID,TEMP
    LDI TEMP,high(SIM_LEDS_INIT)
    MOV r0,TEMP
    LDI TEMP,low(SIM_LEDS_INIT)
    MOV r1,TEMP
    LDI TEMP,(0<<CORE5277_TASK_MODEBITS_NSUSP)
    MOV r2,TEMP
    CALL CORE5277_TASK_CREATE

    ;Инициализация задачи вывода температуры
    LDI TEMP,TID_TEMPERATURE
    MOV TASK_ID,TEMP
    LDI TEMP,high(TEMPERATURE_INIT)
    MOV r0,TEMP
    LDI TEMP,low(TEMPERATURE_INIT)
    MOV r1,TEMP
    CLR r2
    CALL CORE5277_TASK_CREATE

    ;Запуск диспетчера
    JMP CORE5277_DISPATCHER

core5277, примеры использования

А вот пример инициализации в драйвере drv5277_pcint8.asm

;--------------------------------------------------------
DRV_PCINT_INIT:
;--------------------------------------------------------
;Инициализация
;--------------------------------------------------------
;Выделяем память и очищаем ее
MOV TEMP,DRIVER_ID
LDI ACCUM,DRV_PCINT__RAM_USAGE_SIZE
RCALL CORE5277_RAM_REALLOC

MOV XH,ZH
MOV XL,ZL
CLR TEMP
LDI LOOP_CNTR,DRV_PCINT__RAM_USAGE_SIZE
RCALL CORE5277_RAM__FILL8
;Сбрасываем настройки внешних перываний(выключаем)
CLR TEMP
STS PCICR,TEMP
STS PCMSK2,TEMP
STS PCMSK1,TEMP
STS PCMSK0,TEMP
;Устанавливаем векторы прерываний
MOV TEMP,DRIVER_ID
LDI TEMP_H,high(DRV_PCINT_EVENT)
LDI TEMP_L,low(DRV_PCINT_EVENT)
LDI ACCUM,CORE5277_IR_PCINT0
RCALL CORE5277_IR_VECTOR_SET
LDI ACCUM,CORE5277_IR_PCINT1
RCALL CORE5277_IR_VECTOR_SET
LDI ACCUM,CORE5277_IR_PCINT2
RCALL CORE5277_IR_VECTOR_SET

CALL CORE5277_DRIVER_READY
...

core5277, примеры использования

Просто пара примеров задач.

Прример 1:
SIM_LEDS_INIT:
    LDI TEMP_H,PORTC
    LDI TEMP_L,(1<<PC1)
    CALL CORE5277_PORTS__MODE_OUT
    CALL CORE5277_PORTS__SET_LO
    CALL CORE5277_TASK_READY
;--------------------------------------------------------
SIMS_LEDS_INFINITE_LOOP:
    RCALL CORE5277_PORTS__SET_HI
    LDI TEMP,1
    CALL CORE5277_TASK_WAIT_1S

    RCALL CORE5277_PORTS__SET_LO
    LDI TEMP,1
    CALL CORE5277_TASK_WAIT_1S
    RJMP SIMS_LEDS_INFINITE_LOOP

Пример 2:
TEMPERATURE_INIT:
    CALL CORE5277_TASK_READY
;--------------------------------------------------------
    MOV TEMP,TASK_ID
    RCALL CORE5277_VARS_GET_OFFSET
    MOV YH,ZH
    MOV YL,ZL
;--------------------------------------------------------
TEMPERATURE_INFINITE_LOOP:
    LDI TEMP,1
    CALL CORE5277_TASK_WAIT_1S

    LDI TEMP,TID_DS18B20_DRV
    CALL CORE5277_DRIVER_EXEC
    CPI TEMP_L,0xff
    BRNE TEMPERATURE_NO_T_ERROR
   LOG_MARK_R 'E',TEMP_H,TEMP_L
    RJMP TEMPERATURE_INFINITE_LOOP
TEMPERATURE_NO_T_ERROR:
    CALL CORE5277_CONV__SDNF_TO_STR
    CALL CORE5277_LOG
    RJMP TEMPERATURE_INFINITE_LOOP


Обе задачи выполняются, в основном, независимо.