Обработка mRTOS напильником

AVR
Вместо вступления.
Это мой первый топик (не здесь а вообще, в этих ваших интернетах). Прощу сильно не пинать. Далее немного нытья.
Здравствуйте, меня зовут Евгений и я алко начинающий микроконтроллерщик. В моей чисто любительской практике с микроконтроллерами еще пару лет назад (тогда я трогал только AVR) не было какой то особой активности. Надо написать какую то простую программку — написал суперлуп и готово. Надо поморгать светодиодиками — запилил стандартный delay(). Положение усугублялось тем что я, как начинающий микроконтроллерщик, не мог не наткнуться на CodeVision AVR и не залипнуть на нем. Ведь там все что хочешь и сразу. Деление программы на отдельные файлы не практиковал — валил все переменные, функции и объявления в одну кучу говкода. Так продолжалось до тех пор пока мне не пришлось писать программу с изобилием задержек и таймаутов. Далее все о чем предупреждал товарищ DI HALT в статьях об архитектуре программ, прочитанных позже. Программные уродцы, полная невозможность модернизации и поддержки, тормоза, зависания, паранойя, депрессия, плохой стулсон. Далее я взял за правило всегда писать по правилам даже простые программы. Я написал свою таймерную службу, правда очень минималистичную, натаскался использовать структуры, союзы и прочие полезные вещи для читаемости кода и легкости модернизации-поддержки. Но сложность программ росла, мне потребовался диспетчер, иначе написание программы становилось очень печальным процессом. Почитав статьи, решил для начала найти готовое решение чтобы попробовать как все это будет работать. Выбор пал на mRTOS, т.к. требует мало накладных расходов (кооперативная все таки), проста в подключении и использовании. Копию ос взял отсюда mRTOS — кооперативная операционная система для микроконтроллеров AVR версия 1.09. ОС мне понравилась. Все запустилось сразу, светодиодики в двух разных задачах весело моргали… только не с той частотой. Я выбрал тик ос равный 1мс, выставил задержку мигания 1000мс, но получалось что-то около 0.2сек. ОС состоит всего из 2х файлов: mrtos.h и mrtos.c. Решил поковыряться. Сразу бросилось в глаза объявление функции
void wait_task(char delay, switch_buf cpu_state);

завернутой в макрос WAIT(x), в который я пытался писать число 1000. При тике 1мс максимальная задержка 255мс. Печаль. Далее я прошелся глазами по хидеру mrtos.h. Оптимизма придало объявление
// Task Control Block - структура блока контроля задачи
struct TCB {
    char pri;             // приоритет задачи
    char current_pri;     // текущий приоритет задачи
    enum StateTask st;    // текущее состояние задачи 
    int delay;            // время задержки в тиках в состоянии задачи Wait
    switch_buf cpu_state; // контекст задачи
           };

Значит, задержка все таки планировалась поболее. Неужели автор не доглядел? Рою далее.

#pragma warn-
void wait_task(char delay, switch_buf cpu_state)
{
tasks[current_task].st = Wait;
tasks[current_task].delay = delay;
#asm("cli")
#ifdef _MODEL_TINY_
#asm
    ld r26, y
    clr r27
#endasm
#else
#asm
    ld r26, y    
    ldd r27, y+1  
#endasm
#endif           
#asm   
    pop r24
    pop r25
    st x+, r25
    st x, r24    
#endasm      
#ifdef _MODEL_TINY_
#asm   
    adiw R28,2
    sei
#endasm      
#else
#asm   
    adiw R28,3
    sei
#endasm      
#endif           
Sheduler();
}
#pragma warn+

Приехали. Ну а чего я ожидал? Какая ос без асма? Надо сказать, я знаю язык ассемблера… для 8051… Для AVR я писал на асме дважды в жизни (этот случай второй), первый был уже после старта на си, это была проба пера — бегающий по порту со светодиодами огонек. Попробовав поменять char delay на int delay, я с удивлением обнаружил что программа рушится сразу после старта в симуляторе. Внезапный переход на адресс 0x0000, запись по несуществующему адресу. Пришла мысль, что пора бы заглянуть в справку CV. Почитав справку и заодно книгу Лебедева, я примерно понял смысл манипуляций автора ос. После замены adiw R28,3 на adiw R28,4 система перестала рушиться и заработала как надо. Да,
void wait_task(char delay, switch_buf cpu_state);
было заменено на
void wait_task(int delay, switch_buf cpu_state);
и после этого светодиоды заморгали с секундным интервалом. Погоняв симуляцию 10 минут и не увидев вонингов, я успокоился.
Возможно я тоже что-то упустил, недоглядел. Замечания приветствуются. Почему CodeVision? Потому что у меня есть лицензия, покупал не я, но раз уж есть, почему бы ею не пользоваться.
ЗЫ
На попытки вставить кат я потратил больше времени чем на статью. Так и не смог, простите.
UPD
Спасибо товарищам, вставил cut
UPD 2
Прицепил проект с двумя светодиодами, 1с и 1.5с. Проект содержит перепиленные исходники с задержкой через WAIT(x) до 65535мс для задач и корректно работающим остановом задачи с помощью макроса STOP (спасибо товарищу noblako)
  • +5
  • 16 ноября 2013, 01:33
  • XOR
  • 1
Файлы в топике: Atmega328_GPIO_2.zip

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

RSS свернуть / развернуть
На попытки вставить кат я потратил больше времени чем на статью

я когда писАл первую заметку — то же самое было:)

надо вставить тэг cut в таких вот кавычках: <> в то место текста, где должен быть кат. именно один открывающий тэг! закрывающий не надо ставить.
0
а можно просто встать курсором в место где должен быть кат, и нажать кнопку с ножницами (крайняя правая), которая так и подписана…
0
естественно:) только, блин, лично у меня такой подход ассоциируется с выделением куска текста. и в первый раз я долго с катом мучился, выделяя текст:)
0
вы меня удивляете. не понять два предложения…
да и простой эксперимент с выделением текста и нажатием кнопки наставит на путь истинный. а потом Ctrl+Z, и делаем правильно.
0
Мне тоже понравилась данная ОС, и я тоже сижу на CVAVR. С задержками я решал по другому, через событие, например так:
void task20()
{
init_event(0);
while(1)
{
set_event(0);
if (pop_event(0)=255) {какое то действие;get_event(0);STOP}
WAIT(255);
}
}
Задержка получилась 254*255=64770 миллисекунды или 65 секунд.
А вообще у меня что то не работало в данной ОС (не помню точно, вроде STOP не останавливал запущенную задачу), я списывался с автором, он мне на мыло скинул рабочую ОС. Перезалил ли он файл на своем сайте или нет, я не знаю. Если что, стучи мне в личку. Но даже в рабочей версии функция WAIT принимает только значение char.
0
Проверил, действительно STOP не работает. Прицепил свой пробный проект.
0
Поскольку я тоже совсем начинающий, то эта ОС будет для меня полезна.
Попробую перепилить её на AVRStudio4.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.