Телесистемы
 Разработка, производство и продажа радиоэлектронной аппаратуры
На главную   | Карта сайта | Пишите нам | В избранное
Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс.
e-mail:jobsmp@pochta.ru

Телесистемы | Электроника | Конференция «Микроконтроллеры и их применение»

Покритикуйте код таймеров для АРМа (+)

Отправлено 507 07 апреля 2008 г. 13:45


Написал небольшой модуль для создания таймеров. Вроде работает :) Хотел бы услышать ваше мнение - что криво, что не так.
Небольшие пояснения:
- Таймера основаны на PIT'e, точность 1мс
- Функции add_timer и kill_timer статические - юзаются только внутри модуля. Для юзера функции start_timer и stop_timer.

Недостатки/баги/вопросы, которые я вижу:
- невозможно сделать проверку на валидность структуры для stop_timer'a
- не очень красиво запрещать прерывания для SYS на время обработки функций. может быть мьютексы?
- если экспаряться сразу несколько таймеров, то их обработчики дёргаются в цикле без возвращения управления. Если заводится очень маленький таймер, то вообще может получится вечный цикл
- может быть не самая оптимальная реализация порядка таймеров - по времени экспирейшена, но я чет лучше не знаю

Заранее спасибо за ревью )


typedef struct s_timer_tag
{
void (*callback) (struct s_timer_tag *);
struct s_timer_tag * next;
struct s_timer_tag * prev;
int mode;
unsigned int duration;
unsigned long expiration;

} s_timer;

#define TIMER_MODE_SINGLE 0
#define TIMER_MODE_CYCLIC 1

static s_timer * sys_timers=0;
static unsigned long sys_ticks=0;

static void add_timer(s_timer * new_timer)
{
s_timer * timer=sys_timers;

new_timer->expiration+=new_timer->duration;
while(timer)
{
if(new_timer->expiration < timer->expiration)
{
new_timer->next=timer;
if(new_timer->prev=timer->prev) timer->prev->next=new_timer; else sys_timers=new_timer;
timer->prev=new_timer;
return;
}

if(0 == timer->next)
{
new_timer->next=0;
new_timer->prev=timer;
timer->next=new_timer;
return;
}
timer=timer->next;
}

sys_timers=new_timer;
new_timer->next=0;
new_timer->prev=0;
}

static void kill_timer(s_timer * timer)
{
if(timer->next) timer->next->prev=timer->prev;
if(timer->prev) timer->prev->next=timer->next; else sys_timers=timer->next;
timer->next=0;
timer->prev=0;
}

void stop_timer(s_timer * timer)
{
AT91C_BASE_AIC->AIC_IDCR=(1 << AT91C_ID_SYS);
kill_timer(timer);
AT91C_BASE_AIC->AIC_IECR =(1 << AT91C_ID_SYS);
}


void start_timer(s_timer * timer, int mode, unsigned int duration, void (*callback) (struct s_timer_tag *))
{
AT91C_BASE_AIC->AIC_IDCR=(1 << AT91C_ID_SYS);

timer->callback=callback;
timer->duration=duration;
timer->mode=mode;
timer->expiration=sys_ticks;

add_timer(timer);

AT91C_BASE_AIC->AIC_IECR =(1 << AT91C_ID_SYS);
}

int sys_irq_handler(void)
{
s_timer * next, * timer=sys_timers;

sys_ticks++;

while(timer && timer->expiration<=sys_ticks)
{
next=timer->next;
kill_timer(timer);
if(TIMER_MODE_CYCLIC == timer->mode) add_timer(timer);
if(timer->callback) timer->callback(timer);
timer=next;
}

return AT91C_BASE_PITC->PITC_PIVR;
}

void init_timers(void)
{
// Disable the interrupt on the interrupt controller
AT91C_BASE_AIC->AIC_IDCR=(1 << AT91C_ID_SYS);
// Save the interrupt handler routine pointer and the interrupt priority
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (unsigned int) &sys_irq_handler;
// Store the Source Mode Register
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 7;
// Clear the interrupt on the interrupt controller
AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_SYS);
//enable interrupt in AIC
AT91C_BASE_AIC->AIC_IECR =(1 << AT91C_ID_SYS);

AT91C_BASE_PITC->PITC_PIMR=(3000 & AT91C_PITC_PIV) | AT91C_PITC_PITEN | AT91C_PITC_PITIEN;
}


Составить ответ | Вернуться на конференцию

Ответы


Отправка ответа
Имя*: 
Пароль: 
E-mail: 
Тема*:

Сообщение:

Ссылка на URL: 
URL изображения: 

если вы незарегистрированный на форуме пользователь, то
для успешного добавления сообщения заполните поле, как указано ниже:
поделите 6 на два:

Перейти к списку ответов | Конференция | Раздел "Электроника" | Главная страница | Карта сайта

Rambler's Top100 Рейтинг@Mail.ru
 
Web telesys.ru