Вся правда про ОСРВ. Стаття #12. Служби для роботи з завданнями

Продовжуємо розглядати служби ОСРВ, які надають додаткову інформацію про завдання і операції з ними.

До додаткових викликів API, пов’язаних з завданнями, відносяться виклики отримання ID завдання, перевірки обсягу стека, скидання завдання, отримання інформації про завдання та визначення кількості завдань в системі. Nucleus RTOS і Nucleus SE забезпечують 4 основних виклику API для цих операцій, про які я розповім в цій статті.

Отримання ID поточної задачі

Цей службовий виклик повертає ID викликається завдання. Для Nucleus RTOS це вказівник на блок управління поточної задачі. Для Nucleus SE – індекс (0-15) поточної задачі.

Виклик поточної задачі в Nucleus RTOS
Прототип службового виклику:
NU_TASK *NU_Current_Task_Pointer(VOID);

Параметри:
Відсутні.

Значення, що повертається:
Вказівник на блок управління поточною завдання;
NU_NULL – ні завдання.

Виклик поточної задачі в Nucleus SE
Цей API-виклик підтримує основний функціонал API Nucleus RTOS.

Прототип службового виклику:
NUSE_TASK NUSE_Task_Current(void);

Параметри:
Відсутні.

Значення, що повертається:
Індекс поточної (викликається) завдання.

Виконання поточної задачі в Nucleus SE
Реалізація виклику API в даному випадку досить проста: повертається значення глобальної змінної NUSE_Task_Active.

Перевірка доступного обсягу стека

Цей службовий виклик повертає доступний об’єм стека (в байтах) для поточного завдання. Це доцільно лише для планувальників, де кожна задача має свій власний стек; тобто не підійде для планувальника Run To Completion (RTC) в Nucleus SE.

Виклик інформації про обсяг стека в Nucleus RTOS
Прототип службового виклику:
UNSIGNED NU_Task_Check_Stack(VOID);

Параметри:
Відсутні.

Значення, що повертається:
Розмір доступного обсягу стека для поточного завдання в байтах.

Виклик інформації про розмір стека в Nucleus SE
Цей виклик API підтримує основний функціонал API Nucleus RTOS. Проте в Nucleus SE потрібно формальний (dummy) параметр, щоб спростити отримання значення покажчика використовується стек.

Прототип службового виклику:
U16 NUSE_Task_Check_Stack(U8 dummy);

Параметри:
dummy – будь-яке значення, оскільки фактично воно не використовується.

Значення, що повертається:
Розмір доступного обсягу стека для поточного завдання в байтах.

Реалізація
Для такого виклику код повинен бути стерпним:

Якщо використовується планувальник RTC, повертається значення 0, оскільки неможливо (при використанні переносимого коду) визначити доступне для завдання простір стека.

В інших випадках значення покажчика стека визначається знаходженням адреси параметра dummy, який перебуватиме майже на початку стека. Строго кажучи, такий метод залежить від засобів розробки/компілятора, але завжди буде робочим. Обчислене значення – це різниця між цим значенням і початковим значенням простору стека, переведена в байти.

Читайте також  15 рад, як пробитися в App Store додатком з підписками

Скидання завдання

Виклик API, в даному випадку, повертає завдання в її первісне невикористовуване стан. Така функція API відрізняється від звичайних функцій скидання API для інших об’єктів ядра, хоча б тому що це саме скидання, а не просте завдання встановлення в її початковий стан (для Nucleus SE це або NUSE_READY, або запис NUSE_Task_Initial_State[] (див. Структури даних в наступній статті); завдання переводиться в стан призупинення (NUSE_PURE_SUSPEND) і повинна бути відновлена для того, щоб знову бути поставленим на планування. Така логіка схожа на функціонал відповідного виклику API в Nucleus RTOS.

Виклик скидання завдання в Nucleus RTOS
Прототип службового виклику:
STATUS NU_Reset_Task(NU_TASK *task, UNSIGNED argc, VOID *argv);

Параметри:
task – вказівник на блок управління завданням;
argc – елемент даних, який може використовуватися для передачі інформації в задачу;
argv – покажчик, який може використовуватися для передачі інформації в завдання.

Значення, що повертається:
NU_SUCCESS – виклик успішно виконано;
NU_INVALID_TASK – некоректний вказівник на завдання;
NU_NOT_TERMINATED – описувана завдання не знаходиться в стані повної припинення (terminated) або завершення (finished); тільки завдання в стані припинення або завершення можуть бути скинуті.

Виклик скидання завдання в Nucleus SE
Цей API-виклик підтримує основний функціонал API Nucleus RTOS.

Прототип службового виклику:
STATUS NUSE_Task_Reset(NUSE_TASK task);

Параметри:
task – індекс (ID) задачі, яку необхідно скинути.

Значення, що повертається:
NUSE_SUCCESS – виклик успішно виконано;
NUSE_INVALID_TASK – некоректний індекс завдання.

Реалізація скидання завдання в Nucleus SE
Основне призначення API функції NUSE_Task_Reset() після перевірки параметра – повторна ініціалізація всіх структур даних завдання:

Якщо завдання заблокована при виклику API для очікування доступу до об’єкта ядра, перше, що необхідно зробити, налаштувати лічильник заблокованих завдань, відповідних об’єкту. Це здійснюється оператором switch.

Потім структури даних завдання ініціалізуються (в основному, нулями, крім її контекстного блоку) з допомогою виклику функції ініціалізації NUSE_Init_Task(). Її виконання більш детально буде розглянуто в наступній статті з описом ініціалізації системи. Нарешті, статус завдання встановлюється у NUSE_PURE_SUSPEND.

Читайте також  Інформаційна безпека банківських безготівкових платежів. Частина 7 — Базова модель загроз

Отримання інформації про задачу

Цей службовий виклик дозволяє отримати часткову інформацію про завдання. Реалізація Nucleus SE відрізняється від Nucleus PLUS, в якій повертається менше інформації, оскільки присвоювати об’єктам імен, витіснення менш пріоритетною завдання і квант часу не підтримуються, а пріоритет не повертається, будучи надлишковою інформацією.

Виклик отримання інформації про завдання в Nucleus RTOS
Прототип службового виклику:
STATUS NU_Task_Information(NU_TASK *task, CHAR *name, DATA_ELEMENT *task_status, UNSIGNED *scheduled_count, OPTION *priority, OPTION *preempt, UNSIGNED *time_slice, VOID **stack_base, UNSIGNED *stack_size, UNSIGNED *minimum_stack;

Параметри:
task – вказівник на завдання, інформація про яку запитується;
name – вказівник на 8-символьну рядок для імені завдання; включає область для нульових символів;
task_status – покажчик на змінну, яка отримує поточне значення статусу завдання;
scheduled_count – покажчик на змінну, яка отримує значення лічильника, скільки разів завдання була додана в планувальник;
priority – покажчик на змінну для отримання пріоритету задачі;
preempt – покажчик на змінну для опцій витіснення менш пріоритетною завдання; NU_PREEMPT показує, що завдання може бути витіснена, і NU_NO_PREEMPT показує, що завдання не може бути витіснена;
time_slice – покажчик на змінну для отримання значення кванта часу завдання; значення 0 показує, що квантування часу для даної задачі неможливо;
stack_base – покажчик на змінну для отримання адреси стека завдання;
stack_size – покажчик на змінну для отримання розміру стека завдання;
minimum_stack – покажчик на змінну для отримання мінімальної кількості байт, що залишалися в стеку.

Значення, що повертається:
NU_SUCCESS – виклик успішно виконано;
NU_INVALID_TASK – некоректний вказівник на завдання.

Виклик отримання інформації про завдання в Nucleus SE
Цей виклик підтримує основний функціонал API Nucleus PLUS.

Прототип службового виклику:
STATUS NUSE_Task_Information(NUSE_TASK task, U8 *task_status, U16 *scheduled_count, ADDR *stack_base, U16 *stack_size);

Параметри:
task – індекс завдання, про яку запитується інформація;
task_status – покажчик на змінну U8, яка отримує поточне значення статусу завдання (якщо стан очікування задачі недоступне, нічого не повертається);
scheduled_count – покажчик на змінну U16, яка отримує значення лічильника кількості завдань, що додаються в планувальник (якщо лічильник планованих завдань відключений, то нічого не повертається);
stack_base – покажчик на змінну ADDR, яка отримує адресу стека завдання (якщо використовується планувальник RTC, нічого не повертається);
stack_size – покажчик на змінну U16, яка отримує розмір стека завдання (якщо використовується планувальник RTC, нічого не повертається).

Читайте також  Схожі на ос дрони піднімають тяжкості, допомагаючи собі черевцем

Значення, що повертається:
NUSE_SUCCESS – виклик успішно виконано;
NUSE_INVALID_TASK – некоректний індекс завдання;
NUSE_INVALID_POINTER – параметри покажчиків (один або більше) некоректні.

Реалізація отримання інформації про завдання в Nucleus SE
Реалізація цього API-виклику досить проста:

Функція повертає статус задачі, враховуючи різні можливості конфігурацій.

Отримання кількості завдань

Цей службовий виклик повертає інформацію про кількість завдань, сконфігурованих в додатку. У той час як в Nucleus RTOS ця кількість може змінюватися, і значення, що повертається, буде представляти поточне кількість завдань на даний момент, в Nucleus SE обчислене значення встановлюється при складанні і не більше не змінюється.

Виклик отримання кількості завдань в Nucleus RTOS
Прототип службового виклику:
UNSIGNED NU_Established_Tasks(VOID);

Параметри:
Відсутні

Значення, що повертається:
Кількість встановлених (створених і не віддалених) завдань у додатку.

Виклик отримання кількості завдань в Nucleus SE
Цей виклик API підтримує основний функціонал API Nucleus PLUS.

Прототип службового виклику:
U8 NUSE_Task_Count(void);

Параметри:
Відсутні

Значення, що повертається:
Кількість сконфігурованих завдань у додатку.

Реалізація
Реалізація цього виклику API досить проста: повертається значення директиви #define NUSE_TASK_NUMBER.

В наступній статті буде розглянуто структури даних в Nucleus SE, пов’язані з завданнями і деякими стандартними викликами API, не підтримуваними Nucleus SE.

Про автора: Колін Уоллс вже більше тридцяти років працює у сфері електронної промисловості, значну частину часу приділяючи вбудованому. Зараз він — інженер в області вбудованого в Mentor Embedded (підрозділ Mentor Graphics). Колін Уоллс часто виступає на конференціях і семінарах, автор численних технічних статей і двох книг по вбудованому. Живе у Великобританії. Професійний блог Коліна, e-mail: colin_walls@mentor.com.

Про переведення: цей цикл статей видався цікавим тим, що, незважаючи на місцями застарілі описуються підходи, автор дуже зрозумілою мовою знайомить малоподготовленного читача з особливостями ОС реального часу. Я сам належу до колективу творців російської ОСРВ, яку ми припускаємо зробити безкоштовною, і сподіваюся, що цикл буде корисний початківцям розробникам.

Степан Лютий

Обожнюю технології в сучасному світі. Хоча частенько і замислююся над тим, як далеко вони нас заведуть. Не те, щоб я прям і знаюся на ядрах, пікселях, коллайдерах і інших парсеках. Просто приходжу в захват від того, що може в творчому пориві вигадати людський розум.

You may also like...

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *