Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с Sleep
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > scmRTOS
_Артём_
Добрый день.
Попробовал собрать тестовый проект с scmRTOS.
Вроде всё работало, и вдруг...
Обнаружил что простейший код не работает
Код
PORTG|=(1<<3); // зажёчь led
OS::Sleep(1);
PORTG&=~(1<<3);// потушить led


Процесс засыпает как положено и ... всё - больше не просыпается.
Подскажите что можно (нужно) смотреть смотреть.
Спасибо.
AHTOXA
А нет ли у вас рядом более приоритетного процесса, который не отдаёт управление?
_Артём_
Цитата(AHTOXA @ Dec 19 2011, 19:07) *
А нет ли у вас рядом более приоритетного процесса, который не отдаёт управление?


Нажал в AVRStudio Break: программа выполняет
Код
IdleProcessUserHook


Получается что нет более приоритетного.
А где можно посмотреть текущее значение SysTimer(или как том правильно называется).
AHTOXA
Хм. Тогда похоже не запущен системный таймер.
(Текущее значение счётчика : OS::get_tick_count() для версии 4.00 или OS::GetTickCount() для 3.10)
_Артём_
Цитата(AHTOXA @ Dec 19 2011, 22:12) *
Хм. Тогда похоже не запущен системный таймер.
(Текущее значение счётчика : OS::get_tick_count() для версии 4.00 или OS::GetTickCount() для 3.10)


Да, похоже на: прочитал значение с интервалом несколько секунд вернуло 0.

Но в файле scmRTOS_CONFIG.h
Код
#define  scmRTOS_SYSTEM_TICKS_ENABLE        1


Думал этого достаточно. Нет?
Как тогда его запустить?
AHTOXA
Как-то так (это в main()):
Код
    // Start System Timer
    TIMER0_CS_REG = (1 << CS01) | (1 << CS00); // clk/64
    TIMER0_IE_REG |= (1 << TOIE0);
_Артём_
Цитата(AHTOXA @ Dec 19 2011, 23:48) *
Как-то так (это в main()):
Код
    // Start System Timer
    TIMER0_CS_REG = (1 << CS01) | (1 << CS00); // clk/64
    TIMER0_IE_REG |= (1 << TOIE0);


Наверное был неправ с такой заменой:

Код
void timer1_init(void)
/*
TIMER1 initialize - prescale:1
WGM: 4) CTC, TOP=OCRnA
desired value: 1000Hz
actual value: 1000,090Hz (0,0%)
*/
{
    TCCR1B = 0x00; //stop
    TCNT1H = 0xD4; //setup
    TCNT1L = 0xCF;
    OCR1AH = 0x2B;
    OCR1AL = 0x31;
    OCR1BH = 0x2B;
    OCR1BL = 0x31;
    OCR1CH = 0x2B;
    OCR1CL = 0x31;
    ICR1H  = 0x2B;
    ICR1L  = 0x31;
    TCCR1A = 0x00;
    TCCR1B = 0x09; //start Timer
}
int main()
{    timer1_init();
    external_uart_init();
    TIMSK |=  (1 << OCIE1A);   //




    OS::Run();
}
#pragma vector=TIMER1_COMPA_vect
OS_INTERRUPT void Timer1_period_ISR()
{
    OS::TISRW_SS ISRW;
    if (ExtTxPtr.BufferNotEmpty())
    StartExtUartTx();

    ENABLE_NESTED_INTERRUPTS();
    
    Event1ms.SignalISR();
    PORTB |= (1 << 4);
}


Как-то показалось что при использовании Timer1 миллисекунда будет миллисекунднее, вот где-то что-то напортачил...
AHTOXA
Да, этого недостаточно. В scmRTOS_TARGET_CFG.h определены макросы
Код
SYSTEM_TIMER_VECTOR
LOCK_SYSTEM_TIMER()
UNLOCK_SYSTEM_TIMER()

, которые отвечают за то, какое прерывание будет использоваться в качестве прерывания системного таймера.
(Обработчик этого прерывания определен в OS_Target_cpp.cpp). Если хотите делать что-то ещё по прерыванию системного таймера, то используйте хук:
Определите в scmRTOS_CONFIG.h
Код
scmRTOS_SYSTIMER_HOOK_ENABLE 1

и заведите функцию
Код
void OS::system_timer_user_hook()

. Она будет вызываться из обработчика системного таймера.
И ещё одно соображение. Первый таймер сильно круче нулевого, его жалко на тики (имхо конечно).
IgorKossak
Цитата(AHTOXA @ Dec 20 2011, 05:58) *
И ещё одно соображение. Первый таймер сильно круче нулевого, его жалко на тики (имхо конечно).

Если нулевому отведена роль часов реального времени, то никуда не денешься.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.