Biblioteca rápida de Timer, Delay e Timeout sem desperdícios

Timer

Dessa vez vou apresentar rapidamente uma biblioteca contendo rotinas de Timer, Delay e Timeout, e no final do post o código da biblioteca será divulgado por completo.

 

Ela usa apenas um timer, configurado para contar a cada microssegundo e as funções da biblioteca são ditas rápidas porque aceitam que o registrador contador dê overflow sem fazer uso de código condicional, ou seja, sem “if” para verificar se o contador deu overflow. Isso é feito usando uma subtração que elimina o efeito causado pelo overflow do contador, que é: 

 

/* Elimina o efeito de um overflow, sempre retorna um valor positivo, contanto que as variáveis sejam do tipo unsigned e tenham o mesmo número de bits. */
tempoQuePassou = tempoAgora - tempoAntes;

 

Na biblioteca todas as verificações de delay e timeout usam essa subtração, por isso não é gasto tempo extra com verificações e as funções passam a ter um overhead independente do argumento e do valor do contador de tempo. Caso seja necessário saber esse overhead basta medir.

 

Só existe uma situação onde a subtração pode falhar: overflow duplo, entretanto essa situação é impossível por dois motivos:

  1. O argumento de uint32_t não permite a espera necessária por um duplo overflow;
  2. Um duplo overflow levaria: 2 x 2³² micro segundos, ou seja, 2 horas, 23 minutos e 10 segundos.

 

E conforme prometido, usem e abusem do código abaixo.

 

timer.h

 

#ifndef _TIMER_H_
#define _TIMER_H_

/* Initilize the Timer library */
void delayInit(void);

/* Delay Functions, argument in milisecs and microsecs */
void delayMs(uint32_t delayInMs);
void delayUs(uint32_t delayInUs);

/* Timeout functions */

/* Return a Timeout seed used by the timeoutCheck functions */
uint32_t timeoutInit(void);

/* Check if timeouted a initilized seed */
uint32_t timeoutCheck_ms(uint32_t delayInMs, uint32_t seed);
uint32_t timeoutCheck_us(uint32_t delayInUs, uint32_t seed);

/* Get the system time */
uint32_t getTime_us(void);
uint32_t getTime_ms(void);

#endif //_TIMER_H_

 

timer.c

 

/*
 ####        #
 #           #
 ## ### #  # #
 #  #-# #\ # #
 #  # # # \# ####
 Author: Felipe de Andrade Neves Lavratti

 Copyright: There are no restrictions. Use as you want.
*/

static __inline void _HwTimerInit(void) 
{
	/* Setup a 32bits Timer or Ticker to increment each 1us, allow it to overflow */
}

static __inline uint32_t _HwTick(void)
{
       /* return the 32bits Timer/Ticker value */
}

void delayInit()
{
	_HwTimerInit();
}

void delayMs(uint32_t delayInMs)
{
	uint32_t compval =  delayInMs*1000;
	uint32_t start = _HwTick();
	while( (_HwTick() - start) < compval);  //This comparison tolerates overflow
}

void delayUs(uint32_t delayInUs)
{
	uint32_t compval = delayInUs;
	uint32_t start = _HwTick();
	while( (_HwTick() - start) < compval);  //This comparison tolerates overflow
}

uint32_t timeoutInit(void)
{
	return _HwTick();
}

uint32_t timeoutCheck_ms(uint32_t delayInMs, uint32_t seed)
{
	uint32_t compval = delayInMs*1000; 
	return ( !( (_HwTick() - seed) < compval) ); //This comparison tolerates overflow
}

uint32_t timeoutCheck_us(uint32_t delayInUs, uint32_t seed)
{
	uint32_t compval = delayInUs;
	return ( !( (_HwTick() - seed) < compval) ); //This comparison tolerates overflow
}

uint32_t getTime_us(void)
{
	return _HwTick();
}

uint32_t getTime_ms(void)
{
	return (_HwTick()/1000);
}
 
 
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Inscrever-se
Notificar de
1 Comentário
mais recentes
mais antigos Mais votado
Otavio Augusto Gomes
Otavio Augusto Gomes
08/06/2016 20:44

Olá Felipe. Era exatamente o que eu estava buscando! Por hora estava tentando fazer uma função delayUs utilizando instruções assembly para o meu Cortex-M4F, porém não gostei do resultado. Então passei a usar um Timer32 pra fazer o delayUs, mas essa sua implementação parece mais elegante que a minha, e por isso passarei a usar essa sua. Muito obrigado pelo artigo!
Abraço.

Home » Software » Firmware » Biblioteca rápida de Timer, Delay e Timeout sem desperdícios

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: