реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> scmRTOS холостой ход и системный таймер
Acvarif
сообщение Jul 4 2011, 11:56
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



"Продолжаем разговор" как говорил Карлсон.
Запустил ОСь на mega128a в WinAvr (в скрепке проект - сделан на базе http://real.kiev.ua/scmrtos/1-eventflag/)

В железе холостой ход явно просматривается, а прерываний системного таймера нет. Все, что зависит от него (это proc1, proc2 ..) естественнго не работает.
Поскольку нет отладчика то понять в чем дело сложно.

В IAR (v5501) ОСь не работает совсем (проект приложен в скрепке). В проекте сделана визуализация холостого хода и переполнения системного таймера (чего уж может быть проще). Поскольку в железе не видать не только системного таймера, но и холостого хода то получается, что зацикливание происходит в OS::Run(); Подсобите please разобраться ...

Спасибо.

Сообщение отредактировал Acvarif - Jul 4 2011, 12:25
Прикрепленные файлы
Прикрепленный файл  WinAvrPrj.rar ( 117.63 килобайт ) Кол-во скачиваний: 11
Прикрепленный файл  TestScmRtosV310.rar ( 136.2 килобайт ) Кол-во скачиваний: 27
 
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jul 6 2011, 08:29
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



ОСь таки запустилась. Проблема была таки в компиляторе. Он не умеет правильно отличать mega128a от 128, хотя они ничем не отличаются кроме некоторых электрических характеристик (пример slon 1-EventFlag для mega128a, в настройках компилятора IAR AVR 5501,5511 нужно ставить mega128 в скрепке ).

Просмотрев в железе прерывания системного таймера стало чуть грустно.
Прерывания системного таймера (период 1,2 ms) явно нестабильны, хотя вроде ничего на прерывания T0 не должно влиять.
Тоесть использовать системные тики для каких-либо более менее точных отсчетов нельзя.
Но посмотрев на взаимодействие между вторым и третьим процессом особой нестабильности не заметил. ОСь начинает нравиться.
Код
template<> void TProc2::Exec()
{
    for(;;)
    {
      ef.Wait();
      PORTC |= (1 << 3);

    }
}
//---------------------------------------------------------------------------
template<> void TProc3::Exec()
{
    for(;;)
    {

       Sleep(20);
       ef.Signal();
      PORTC &= ~(1 << 3);
    }
}


Так до сих пор и не понял зачем в примере нужен аналоговый компаратор?
Код
    ACSR |= (1 << ACBG) | (1 << ACIE); /* Ref ON, IE ON */  
    DDRB |= (1 << 4);                  /* AIN1*/

Если закоментировать этот код ничего не изменится.
В документацци сказано о переключении контекстов. Дергание ногой должно вызывать прерывания по компаратору и соответственно переключение контекстов.
Но где это дергание происходит? И какая все же разница между контекстом и процессом? Я так понимаю, что процесс это все вместе взятое - нить со своими переменными, регистрами стеком.




Прикрепленные файлы
Прикрепленный файл  scmrtos_avr_iar_snapshot.rar ( 301.64 килобайт ) Кол-во скачиваний: 9
 
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 6 2011, 08:50
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Acvarif @ Jul 6 2011, 11:29) *
Так до сих пор и не понял зачем в примере нужен аналоговый компаратор?
Посмотрите внимательно в scmRTOS_config.h чему равно scmRTOS_CONTEXT_SWITCH_SCHEME. Если 0, то компаратор не нужен. Если 1, то таки да, его прерывание переключает контекст.
QUOTE (Acvarif @ Jul 6 2011, 11:29) *
Но где это дергание происходит?
Смотрите OS_Kernel.h, там есть строки
CODE
void OS::TKernel::SchedISR()
{
    TPriority NextPrty = GetHighPriority(ReadyProcessMap);
    if(NextPrty != CurProcPriority)
    {
        SchedProcPriority    = NextPrty;
        RaiseContextSwitch();
    }
}
Вот RaiseContextSwitch() и есть дерганье ногой. Ищите его определение в OS_Target.h
QUOTE (Acvarif @ Jul 6 2011, 11:29) *
Я так понимаю, что процесс это все вместе взятое - нить со своими переменными, регистрами стеком.
Контекст - содержимое регистров для процесса (плюс указатель стека, который в "нормальных" процессорах входит в регистры ядра).


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jul 6 2011, 10:35
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Спасибо. Стало немного светлее.

Цитата(Сергей Борщ @ Jul 6 2011, 11:50) *
Посмотрите внимательно в scmRTOS_config.h чему равно scmRTOS_CONTEXT_SWITCH_SCHEME. Если 0, то компаратор не нужен. Если 1, то таки да, его прерывание переключает контекст.


Код
#define  scmRTOS_CONTEXT_SWITCH_SCHEME      1

Получается, что если scmRTOS_CONTEXT_SWITCH_SCHEME = 1
то функция RaiseContextSwitch() просто разрешает глобальные прерывания

Код
#if scmRTOS_CONTEXT_SWITCH_SCHEME == 1

    INLINE inline void RaiseContextSwitch() { SPM_CONTROL_REG |= (1 << SPMIE);  } // enable SPM interrupt
    INLINE inline void BlockContextSwitch() { SPM_CONTROL_REG &= ~(1 << SPMIE); } // disable SPM interrupt


Кто или что тогда всетаки переключает процессы? Или с какой частотой переключаются процессы? Кто ее формирует?
Я так понимаю, что переключатель контекста и есть переключатель процессов? Может глупость сморозил...
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jul 6 2011, 10:40
Сообщение #5


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(Acvarif @ Jul 6 2011, 14:35) *
Кто или что тогда всетаки переключает процессы? Или с какой частотой переключаются процессы? Кто ее формирует?
Я так понимаю, что переключатель контекста и есть переключатель процессов? Может глупость сморозил...

Переключается по таймеру. Таймер дёргает прерывание (обычно самое низкоприоритетное), по которому вызывается диспетчер процессов.
По-моему, так. (давно за инструмент не садился)


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jul 6 2011, 10:57
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(MrYuran @ Jul 6 2011, 13:40) *
Переключается по таймеру. Таймер дёргает прерывание (обычно самое низкоприоритетное), по которому вызывается диспетчер процессов.
По-моему, так. (давно за инструмент не садился)


Примерно так и думал. В данном случае получается, что переключателем процессов является Таймер 0 (он же системный таймер или формирователь тиков)?

Зачем тогда еще один вариант переключения процессов (в данном примере scmRTOS_CONTEXT_SWITCH_SCHEME = 1 не работает) внешнее дергание ноги -> вызов таким образом какого нибудь низкоуровневого прерывания для переключения между процессами? Что это дает? Освобождает как то системный таймер?

Сообщение отредактировал Acvarif - Jul 6 2011, 11:01
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 6 2011, 11:47
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Acvarif @ Jul 6 2011, 13:35) *
Получается, что если scmRTOS_CONTEXT_SWITCH_SCHEME = 1
то функция RaiseContextSwitch() просто разрешает глобальные прерывания
Вы, похоже, взяли исходник из другого примера или же настройка компаратора - рудимент от предыдущей версии.
CODE
#if scmRTOS_CONTEXT_SWITCH_SCHEME == 1

    INLINE inline void RaiseContextSwitch() { SPM_CONTROL_REG |= (1 << SPMIE);  } // enable SPM interrupt
    INLINE inline void BlockContextSwitch() { SPM_CONTROL_REG &= ~(1 << SPMIE); } // disable SPM interrupt

Тут разрешаются не глобальные прерывания, а прерывание по окончанию записи во флешь. Этот такой трюк - флаг этого прерывания при нормальной работе всегда взведен, и разрешение этого прерывания (естетсвенно, при разрешенных глобальных прерываниях) вызовет переход на его обработчик. А уже в обработчике произойдет, собственно, переключение контекстов. Следствием которого является переключение текущего процесса. Если же переключение контекстов потребовалось во время обработки какого-либо прерывания, то глобально прерывания в этот момент запрещены и будут разрешены по команде RETI. В этот-то момент и вызовется обработчик.
QUOTE (Acvarif @ Jul 6 2011, 13:35) *
Кто или что тогда всетаки переключает процессы? Или с какой частотой переключаются процессы? Кто ее формирует?
Это вытесняющая ОСь. Здесь переключение происходит в тот момент, когда процесс отдает управление в ожидании какого-либо сервиса либо уходя в спячку либо если произошло событие (вызов сервиса из прерывания или текушего процесса), требующее пробуждения более приоритетного процесса.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jul 6 2011, 13:10
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(Сергей Борщ @ Jul 6 2011, 14:47) *
Тут разрешаются не глобальные прерывания, а прерывание по окончанию записи во флешь. Этот такой трюк - флаг этого прерывания при нормальной работе всегда взведен, и разрешение этого прерывания (естетсвенно, при разрешенных глобальных прерываниях) вызовет переход на его обработчик. А уже в обработчике произойдет, собственно, переключение контекстов. Следствием которого является переключение текущего процесса. Если же переключение контекстов потребовалось во время обработки какого-либо прерывания, то глобально прерывания в этот момент запрещены и будут разрешены по команде RETI. В этот-то момент и вызовется обработчик.
Это вытесняющая ОСь. Здесь переключение происходит в тот момент, когда процесс отдает управление в ожидании какого-либо сервиса либо уходя в спячку либо если произошло событие (вызов сервиса из прерывания или текушего процесса), требующее пробуждения более приоритетного процесса.

Спасибо. Еще немного посветлело.

Код
//    scmRTOS Context Switch Scheme
//
//    The macro defines a context switch manner. Value 0 sets direct context
//    switch in the scheduler and in the OS ISRs. This is the primary method.
//    Value 1 sets the second way to switch context - by using of software
//    interrupt. See documentation fo details.
//
//
#define  scmRTOS_CONTEXT_SWITCH_SCHEME      1


У меня все работает одинаково (во всяком случае внешне) при 0 и при 1

Получается,что в случае когда scmRTOS_CONTEXT_SWITCH_SCHEME = 1 - выбрана передача управления на основе программного прерывания. Поскольку все при этом работает, не пойму какого прерывания?
Когда scmRTOS_CONTEXT_SWITCH_SCHEME = 0 - выбрана передача управления на основе прерывание по окончанию записи во флешь.
Или все наоборот?

Сообщение отредактировал Acvarif - Jul 6 2011, 15:53
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 6 2011, 20:49
Сообщение #9


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Сергей Борщ @ Jul 6 2011, 14:47) *
Вы, похоже, взяли исходник из другого примера или же настройка компаратора - рудимент от предыдущей версии.
В AVR/IAR 3.10 -- рудимент после замены на прерывание SPM_READY. Когда я это обнаружил, то уже думал, что вот-вот 4.00 выйдт и не стал править. А потом забыл.
В AVR/GCC 3.10 всё нормально и в примере 2, в котором компаратор оставлен для примера, инициализация компаратора охвачена
#if scmRTOS_CONTEXT_SWITCH_SCHEME == 1

В pre-400 поправлено и для AVR/IAR.

Acvarif, кстати, в pre-400 и в AVR/IAR пример 1-EventFlag приведён в почти полное соответствие с упомянутой в первом сообщении статьёй. "Почти", так как в порте в репозитории в переключатель контекста в OS_Target_asm, естественно, не вставлено махание ножкой осциллографу.

Цитата(Acvarif @ Jul 6 2011, 16:10) *
Код
#define  scmRTOS_CONTEXT_SWITCH_SCHEME      1

У меня все работает одинаково (во всяком случае внешне) при 0 и при 1
Потому что в примерах реализованы оба способа.

Цитата(Acvarif @ Jul 6 2011, 16:10) *
Получается,что в случае когда scmRTOS_CONTEXT_SWITCH_SCHEME = 1 - выбрана передача управления на основе программного прерывания. Поскольку все при этом работает, не пойму какого прерывания?
Задаётся в scmRTOS_TARGET_CFG.h, например,
Код
#define CONTEXT_SWITCH_ISR_VECTOR  SPM_READY_vect
или
Код
#define CONTEXT_SWITCH_ISR_VECTOR  ANA_COMP_vect
Это дело передаётся в OS_Target_asm.S (.s90 для IAR), где и используется для организации входа в обработчик прерывания.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jul 7 2011, 07:37
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Спасибо.

Значит в примере от IAR 310 пропущено только дрыгание ногой по прерываниям компаратора при scmRTOS_CONTEXT_SWITCH_SCHEME 1?
Или я опять недопонял...

Для уточнения
если
Код
#define  scmRTOS_CONTEXT_SWITCH_SCHEME      0

переключение контекстов происходит по прерыванию записи во флешь (он - вектор прерывания все время взведен)
если
Код
#define  scmRTOS_CONTEXT_SWITCH_SCHEME      1

по прерываниям от аналогового компаратора
В последнем случае немного непонятно. Получается, что прерывания по аналоговому компаратору тоже должны быть все время взведены?
Вобщем и целом тогда особой разницы в scmRTOS_CONTEXT_SWITCH_SCHEME нет?

Посмотрел pre 400, там код под IAR очень похож на WinAvr:

Код
//---------------------------------------------------------------------------
//  "Hello, scope!" pins in pin_macros.h notation.
#define TIMER1_ISR      D,5,H
#define TIMER1_TO_PROC1 B,0,H
#define PROC1           B,1,H
#define PROC2           B,2,H
#define PROC3           B,3,H
#define TIMER_HOOK      B,4,H
#define IDLE_HOOK       B,5,H


//---------------------------------------------------------------------------
//
//      Process types
//

// demonstrate process switching from Proc2 to Proc3 in sleep() or ef.signal() call
#if PROC2_HIGHER_THAN_PROC3
# define PROC2_PRIO OS::pr1
# define PROC3_PRIO OS::pr2
#else
# define PROC2_PRIO OS::pr2
# define PROC3_PRIO OS::pr1
#endif


typedef OS::process<OS::pr0, 120, 32> TProc1;
typedef OS::process<PROC2_PRIO, 160, 32> TProc2;
typedef OS::process<PROC3_PRIO, 120, 32> TProc3;

template<> void TProc1::exec();
template<> void TProc2::exec();
template<> void TProc3::exec();

//---------------------------------------------------------------------------
//
//      Process objects
//
TProc1 Proc1;
TProc2 Proc2;
TProc3 Proc3;

//---------------------------------------------------------------------------
tick_count_t tick_count;    // global variable for OS::GetTickCount testing

OS::TEventFlag Timer1_Ovf;  // set in TIMER1_COMPA_vect(), waited in Proc1
OS::TEventFlag ef;          // set in Proc3, waited in Proc2

//---------------------------------------------------------------------------
int main()
{
    TCCR1B = (1 << WGM12) | (1 << CS10);    // CTC mode, clk/1
    OCR1A  = 40000U;
    TIMSK = (1 << OCIE1A); // Timer1 OC interrupt enable

    // Start System Timer
    TCCR0  = (1 << CS01) | (1 << CS00); // clk/64
    TIMSK |= (1 << TOIE0);

    DRIVER(TIMER1_ISR,OUT);
    DRIVER(TIMER_HOOK,OUT);
    DRIVER(IDLE_HOOK,OUT);
    //
    OS::run();
}


Правда компилится без проблем
Я так понял, что там для идентичности с gcc добавлены функции типа DRIVER(TIMER1_ISR,OUT);
и др.

Сообщение отредактировал Acvarif - Jul 7 2011, 07:38
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 7 2011, 08:49
Сообщение #11


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Acvarif @ Jul 7 2011, 10:37) *
Значит в примере от IAR 310 пропущено только дрыгание ногой по прерываниям компаратора при scmRTOS_CONTEXT_SWITCH_SCHEME 1?
Нет. В IAR310 вариант "1" переведен с аналогового компаратора на готовность записи во флеш, но из main недовычищено то, что касалось компаратора.

Цитата(Acvarif @ Jul 7 2011, 10:37) *
если
Код
#define  scmRTOS_CONTEXT_SWITCH_SCHEME      0
переключение контекстов происходит по прерыванию записи во флешь (он - вектор прерывания все время взведен)
если
Код
#define  scmRTOS_CONTEXT_SWITCH_SCHEME      1
по прерываниям от аналогового компаратора
В последнем случае немного непонятно. Получается, что прерывания по аналоговому компаратору тоже должны быть все время взведены?
Вобщем и целом тогда особой разницы в scmRTOS_CONTEXT_SWITCH_SCHEME нет?
В случае "0" переключение производится прямым вызовом os_context_switcher.
В случае "1" переключение производится обработчиком специального прерывания, которое возбуждается при помощи raise_context_switch. Какое именно прерывание будет задействовано (а хоть и от свободного канала output compare) -- зависит от настроек проекта в scmRTOS_TARGET_CFG.h
В AVR/IAR-овских примерах было всё на компараторе, потом всё перевелось на запись во флеш. В AVR/GCC-шніх во втором примере оставлен компаратор, в остальных -- флеш. Сравните файлы scmRTOS_TARGET_CFG.h от первого и второго примера AVR/GCC (не важно, 310 или pre-400).
Для компаратора raise делается дёрганьем ноги, а само прерывание всегда разрешено. Для вектора записи во флеш запрос всегда взведён, а raise делается разрешением.

Цитата(Acvarif @ Jul 7 2011, 10:37) *
Посмотрел pre 400, там код под IAR очень похож на WinAvr:
...
Я так понял, что там для идентичности с gcc добавлены функции типа DRIVER(TIMER1_ISR,OUT); и др.
"Волковские" макросы из pin_macros.h добавлены для простоты обеспечения идентичности.
Просто скопирован кусок из AVR/GCC-шных примеров для полного соответствия поведения, чтобы можно было пользоваться статьёй-описанием для обеих компиляторов.
Если (когда wink.gif ) доберусь до CM3-шного примера, то тогда перепишу под тамошний pin.h


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jul 7 2011, 11:00
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата
В случае "0" переключение производится прямым вызовом os_context_switcher.
В случае "1" переключение производится обработчиком специального прерывания, которое возбуждается при помощи raise_context_switch. Какое именно прерывание будет задействовано (а хоть и от свободного канала output compare) -- зависит от настроек проекта в scmRTOS_TARGET_CFG.h


Спасибо. Нашел.
Код
#if scmRTOS_CONTEXT_SWITCH_SCHEME == 0
     public  OS_ContextSwitcher
#else
     extern  OS_ContextSwitchHook
#endif


Тоесть при scmRTOS_CONTEXT_SWITCH_SCHEME == 1 переключать контексты можно будет только извне дергая ногой, например одного из входов компаратора?
Если это так то с какой частотой нужно ее дергать?
Хотя я сам сомневаюсь в том, что написал...
Скорее всего если просто сделать ACSR = (1 << ACBG) и (так сказать изнутри) установить одну из ног компаратора в еденицу то тогда он постоянно будет находиться в состоянии прерывания, а значит будет extern OS_ContextSwitchHook.
И в этом неуверен...
Как все же правильно?


Цитата(ReAl @ Jul 7 2011, 11:49) *
В AVR/IAR-овских примерах было всё на компараторе, потом всё перевелось на запись во флеш. В AVR/GCC-шніх во втором примере оставлен компаратор, в остальных -- флеш. Сравните файлы scmRTOS_TARGET_CFG.h от первого и второго примера AVR/GCC (не важно, 310 или pre-400).
Для компаратора raise делается дёрганьем ноги, а само прерывание всегда разрешено. Для вектора записи во флеш запрос всегда взведён, а raise делается разрешением.

Да, действительно так. Спасибо.
Код
#if scmRTOS_CONTEXT_SWITCH_SCHEME == 1
    // Setup analog comparator as software interrupt source
    #if PORT_TOGGLE_BY_PIN_WRITE      // see pin_macros.h for PORT_TOGGLE_BY_PIN_WRITE definition and sing
    ACSR = (1 << ACBG);        // Ref ON, interrupt on both edges
    #else
    ACSR = (1 << ACBG) | (1 << ACIS1);    // Ref ON, falling edge
    #endif
    DRIVER(RAISE_PIN,OUT);    // AIN1 - output
    // analog comparator propagation and synchronization delay
    _delay_us(2);
    ACSR |= (1 << ACI);    // needed for new chips with improved sbi/cbi behavior
    ACSR |= (1 << ACIE);
#endif


Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jul 7 2011, 14:00
Сообщение #13


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Всем спасибо.

Появилось кое-какое понимание.

Пытаюсь организовать простую передачу данных USART по прерыванию таймера 1.
Для этого попытался организовать ассемблерную инициализацию порта в отдельном файле
с надеждой, что там будет еще всяко разное
Код
USART_Init:
  out UBRRH, r17
  out UBRRL, r16
  ldi r16, (1<<RXEN)|(1<<TXEN)
  out UCSRB,r16
  ldi r16, (1<<USBS)|(3<<UCSZ0)
  out UCSRC,r16
  ret
end

Возникла проблема с подключением этого файла к main. Сплошные ошибки типа Error[Pe077]: this declaration has no storage class or type specifier
Читал доку на OCЬ. Не нашел как можно подключить к проекту отдельный файл (cpp или asm). Или все нужно прописывать в самой main? А если понадобится много asm функций?
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 7 2011, 20:07
Сообщение #14


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



1. Подключение файлов к проекту смотрят не в доке на ось, а в доке на среду разработки.
2. А назачем для такого асм?
Код
void uart_init(uint16_t baud_div)
{
        UBRRH = baud_div >> 8;
        UBRRL = baud_div;
        UCSRB = (1<<RXEN)|(1<<TXEN);
        UCSRC = (1<<USBS)|(3<<UCSZ0);
}

avr-gcc -Os -S -mmcu=atmega8 uartinit.c
Код
uart_init:
/* prologue: function */
/* frame size = 0 */
    out 64-32,r25
    out 41-32,r24
    ldi r24,lo8(24)
    out 42-32,r24
    ldi r24,lo8(14)
    out 64-32,r24
/* epilogue start */
    ret


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jul 8 2011, 07:12
Сообщение #15


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Да, понял. Спасибо.
С IAR плотно работал несколько лет тому назад. Забывается блин...
После запуска ОСи возникла другая проблема - объектное программирование.
Оно еще в PHP мне не нравилось. Наверное потому, что толком его не понимал.
Поскольку все же решил сделать задачу на scmRTOS придется почитать немного буквари...
Сделал так:
Код
void USART_Init( unsigned int baudrate, bool usart_number)
{
    if(!usart_number)
    {
        // установка частоты бод
        UBRR0H = (unsigned char) (baudrate>>8);                  
        UBRR0L = (unsigned char) baudrate;
        // Разрешить передачу
        UCSR0B = ( 1 << TXEN0 );
        // Установка формата фреймов: 8 data 1stop
        UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);              
    }
    else
    {  
        // установка частоты бод
        UBRR1H = (unsigned char) (baudrate>>8);                  
        UBRR1L = (unsigned char) baudrate;
        // Разрешить прием и передачу
        UCSR1B = ( ( 1 << RXEN1 ) | ( 1 << TXEN1 ) );
        // Установка формата фреймов: 7 data 2stop
        UCSR1C = (1<<USBS1)|(1<<UCSZ11);              
    }        
}

Поставил перед main.
Задача - обмен по Modbus по USART0, приведение в нужный вид полученых данных и передача в PC по USART1.
Обмен по Modbus с периодом 400 мс. Передача в PC с периодом 100 мс (100мс выглядят глупо, но это для иденчности со старым модулем).
Наверное можно сделать так:
По прерываниям T1 переходить в поцесс1 делать полный обмен по Modbus и сохранять полученные данные в глобальн. массиве.
В процессе 2 проспав нужное количество тиков системного таймера преобразовать в нужный вид данные из гл. массива и передать все в PC
Приоритетным в этом случае сделать процесс1 - пока идет обмен по модбас в PC ничего не передавать.
Первое, что пришло в голову. Может глупость...
Прошу прокомментировать.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 9th July 2025 - 08:44
Рейтинг@Mail.ru


Страница сгенерированна за 0.01538 секунд с 7
ELECTRONIX ©2004-2016