Перейти к содержанию
    

mRTOS-кооперативная операционная система, порт CodeVision, порт WinAvr

если уж каждой задаче выделен свой стек - чего такого сильно экономит кооперативка по сравнению с вытеснялкой.

Только прыгать от задачи к задаче может чаще, пмсм, ввиду меньшего переключаемого контекста.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

если уж каждой задаче выделен свой стек - чего такого сильно экономит кооперативка по сравнению с вытеснялкой

время программиста экономит при межзадачном взаимодействии, за счет простого обращения с общей памятью.

не нужно ни локов, ни крит секций.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрел mRTOS, решил до кучи написать свою переключалку задач под CVAVR (1.25.3) кооперативная, карусельная со своими стеками. MyOS.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В процессе отладки реального проекта, пришлось немножко все облагородить. Вроде работает.MyOS.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сделал вариант для мелких AVR. Прерывания теперь имеют свой стек данных, что позволяет сделать глубины стеков данных задач оптимальными. Требования для малых стеков:

 

FLASH: 20 байт переключение задач, 6 байт на опрос задачи, 12 байт инициализация задачи, 4-14 (+10 прерывания) байт на сохранение в стек локальных регистровых переменных при каждом переключении, того на три задачи 74 байта FLASH, если не считать сохранений при переключении

 

ОЗУ: 2 байта на задачу, байт на прерывания , 2 байта на задачу для каждого стека задачи (т.к. возникновение прерывания случайно в любом из стеков) , того на три задачи 13 байт лишнего ОЗУ .

MyOS2.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сделал вариант для мелких AVR.

Спасибо. Хотелось бы (для тупых) легонькое описание типа как у LVII.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Даже не и знаю что тут объяснять

 

void OS_yeld(void) - Смена стеков Z-указывает на текущий своп стека.

 

Идея сохранения локальных регистровых переменных (ЛРП) основана на том, что CV(У меня 1.25.3 у новых CV не знаю) при входе в функцию сохраняет их в стек данных в последнюю очередь (до 6 регистров ), этот стек и используется для сохранения ЛРП при смене задач, но задачи и сопроцедуры теперь НЕ сохраняют ЛРП, эта задача теперь возложена на ВЫЗЫВАЮЩЮЮ задачу.

Код для сохранения восстановления в стеке ЛРП такой же, как у самого компилятора, но что делает компилятор автоматически при входе и выходе из функции, для смены задач приходится делать вручную (подсмотрев код для сохранения восстановления в стеке ЛРП в asm файле, для CV 1.25.3 - шесть вариантов).

 

пример допустим 4 ЛРП, Swp –своп стека.

 

#asm("adiw R28,4");#asm("rcall __SAVELOCR4"); - сохранили ЛРП (__SAVELOCR4-подсмотрели asm)

 

Swp; Z указывает на Swp (в CV 1.25.3 работает)

 

OS_yeld(); - переход

 

#asm("rcall __LOADLOCR4");-восстановили ЛРП

 

Попытался как-то это автоматизировать с помощью дефайнов.

 

Начальная инициализация свопов стеков и первого входа в задачи дело вкуса разработчика как у меня сделано мне не нравится неудобно.

Таймеры , события, mutex – тоже дело вкуса разработчика.

 

Передача данных задаче через R22R23, пример есть для варианта для mega128

 

Кстати подобная идея для IAR где то на форуме уже была.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ОС создает скелетон кода. Далее подключайте необходимые драйвера. Для последовательных портов, параллельной и последовательной FLASH, параллельной и последовательной ОЗУ, индикаторами, разнообразными дачиками написал сам. Драйвера для контроллера Ethernet предоставляются фирмой-производителем. На просторах Интернета огромное количество разнообразных открытых библиотек, особенно под компилятор WinAVR, просто портируемых на CodeVision. Если очень упрощенно, то далее так - для отдельного устройства(драйвера), отдельный процесс(ы) с приоритетом(и), установленным по степени важности событий происходящим на этом устройстве.

 

"Embedded Multitasking with small microcontrollers" Keith E. Curtis. - http://www.onlinedisk.ru/file/257940/

 

 

Уважаемый LVII проверил Ваш вариант mRTOS на Atmega 128. Собственно проект дергает 3-мя ножками с помощью 3-х тасков(инверсия пина). есть ряд вопросов:

1. если запускаю 1 таск есть разрывы между соседними "пачками" :05: :05: - откуда вообще пачки ? В мануале о них не слова. выход по DISPATCH.

2. если запускаю таск с выходом WAIT(x). Идет повторение со скважностью "пачек". ситуация от изменения х не зависит.

3. запуск 2 и более тасков дает такой же результат .

что с этим делать ? (сделано все по мануалу).

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

HELP Уважаемый LVII проверил Ваш вариант mRTOS на Atmega 128. Собственно проект дергает 3-мя ножками с помощью 3-х тасков(инверсия пина). есть ряд вопросов:

1. если запускаю 1 таск есть разрывы между соседними "пачками" 05.gif 05.gif - откуда вообще пачки ? В мануале о них не слова. выход по DISPATCH.

2. если запускаю таск с выходом WAIT(x). Идет повторение со скважностью "пачек". ситуация от изменения х не зависит.

3. запуск 2 и более тасков дает такой же результат .

что с этим делать ? (сделано все по мануалу).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Даже не и знаю что тут объяснять

Не знаю, актуален ли этот форум, тем более для oleg_lwd.

Но поинтересуюсь в целях повышения своей компьютерной безграмотности, что означает выделенное:

#define OS_DEF_TASK(n,x)Tswap x={ST_##n,DATA_ST_##n};char PST_##n @(ST_##n+1)

 

#define _YELD(x) {x;OS_yeld();}

, где x типа Tswap:

typedef struct {
    #ifdef _STACK_ONE_BYTE_
    unsigned char sp;
    #else 
    unsigned int sp;
    #endif 
    #ifdef _DATA_STACK_ONE_BYTE_
    unsigned char dp;
    #else 
    unsigned int dp;
    #endif 
} Tswap;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В образовательных целях решил попробовать разобраться, как устроена это ОС. В процессе изучения исходного кода появились пару вопросов:

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

2) В исходниках есть несколько функций, написанных на ассемблере - насколько я понял, в них проводятся какие-то манипуляции с указателями на вершину стека. А почему написано на ассемблере - это такая максимальная оптимизация по скорости или на СИ этого просто не сделать?

Заранее спасибо за ответы!

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если об ОС от oleg_lwd, имхо (я сам учусь :))

1) явно указывается размер выделяемой памяти

в main2.c

// глубина стека данных
#define L_SD_MAIN 16
#define L_SD_1    16
#define L_SD_2    16
#define L_SD_3    16
// глубина стека
#define L_S_MAIN 16
#define L_S_1    16
#define L_S_2    16
#define L_S_3    16

(для реальной задачи 16 - маловато)

далее os2.h

// абсолютные стеки      
#define DATA_ST_MAIN SRAM_BEGIN+_DATA_STACK
#define DATA_ST_1 DATA_ST_MAIN-L_SD_MAIN
#define DATA_ST_2 DATA_ST_1-L_SD_1
#define DATA_ST_3 DATA_ST_2-L_SD_2
#define DATA_ST_4 DATA_ST_3-L_SD_3
#define DATA_ST_5 DATA_ST_4-L_SD_4
#define DATA_ST_6 DATA_ST_5-L_SD_5

#define _STACK _HEAP_START_-1 
#define ST_MAIN _STACK
#define ST_1 ST_MAIN-L_S_MAIN-2
#define ST_2 ST_1-L_S_1
#define ST_3 ST_2-L_S_2  
#define ST_4 ST_3-L_S_3  
#define ST_5 ST_4-L_S_4  
#define ST_6 ST_5-L_S_5

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Наконец-то, скачал этот mRTOS (на работе narod блокирован, дома - забываю :))

Мои наблюдения - поправьте, если не прав.

Похоже, всё упрощено. (Имхо, можно ещё проще - simple task switcher)

стек вызовов и локальные переменные

Вход в задачу всегда в одной точке, так что стек вызовов - пустой?

Локальные переменные, которые должны сохраняться между вызовами, должны быть статическими. Об этом сказано в документации.

 

Изменено пользователем gabd

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...