Strict Standards: Declaration of action_plugin_importoldchangelog::register() should be compatible with DokuWiki_Action_Plugin::register($controller) in /home/aqq20189/public_html/embedders.org/kurt/wiki/lib/plugins/importoldchangelog/action.php on line 8

Deprecated: Function split() is deprecated in /home/aqq20189/public_html/embedders.org/kurt/wiki/inc/auth.php on line 146

Warning: Cannot modify header information - headers already sent by (output started at /home/aqq20189/public_html/embedders.org/kurt/wiki/lib/plugins/importoldchangelog/action.php:8) in /home/aqq20189/public_html/embedders.org/kurt/wiki/inc/auth.php on line 236

Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/aqq20189/public_html/embedders.org/kurt/wiki/inc/auth.php on line 390

Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/aqq20189/public_html/embedders.org/kurt/wiki/inc/auth.php on line 390

Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/aqq20189/public_html/embedders.org/kurt/wiki/inc/auth.php on line 387

Strict Standards: Only variables should be passed by reference in /home/aqq20189/public_html/embedders.org/kurt/wiki/doku.php on line 69

Warning: Cannot modify header information - headers already sent by (output started at /home/aqq20189/public_html/embedders.org/kurt/wiki/lib/plugins/importoldchangelog/action.php:8) in /home/aqq20189/public_html/embedders.org/kurt/wiki/inc/actions.php on line 359
sources:circ_buf
Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/aqq20189/public_html/embedders.org/kurt/wiki/inc/template.php on line 222
Список содержимого

Циклический буфер

Не самая красивая реализация буфера. Мне самому он не нравится, поэтому и выкладываю :-)

Для формирования используется финт ушами из макроса DECLARE_CIRC_BUFFER(). Первый параметр переменная для буфера, второй - размер буфера в байтах. Очень важно чтобы размер был кратен степени двойки, то бишь 4,8,16,32 и т.д. Преимущество данного метода меньше писанины в клиентском коде, из недостатков - накладные расходы на вызов функций и неконстантность SizeMask.

example

См. также аппаратный уарт

#include "circ_buf.h"
 
#define MY_BUFFER_SIZE (32)
#if (MY_BUFFER_SIZE & (MY_BUFFER_SIZE-1))
#error MY_BUFFER_SIZE must be power of 2
#endif
 
 
  DECLARE_CIRC_BUFFER( buf, MY_BUFFER_SIZE );
 
  circ_Init(&buf.b);
  while( circ_Put( &buf.b, '1' ) != 0 ) continue;
  print( circ_Get( &buf.b ) );

h-file

/**
* @file	circ_buf.h
* @brief Circular Buffer
*
* @author      Rustem Kalimullin
* @par E-mail:
*              hellos@mail.ru
* @par Copyright:
*              (c) Kurt, 2006
*/
 
#ifndef KR_CIRCBUF_INC_H_
#define KR_CIRCBUF_INC_H_
 
typedef struct circ_buffer_t {
	volatile unsigned int Get;
	volatile unsigned int Put;
	unsigned int SizeMask;
	unsigned char Buffer[0];
} circ_buffer_t;
 
 
#define DECLARE_CIRC_BUFFER(name,size) \
struct {\
	circ_buffer_t b;\
	unsigned char name##pad[ size-0 ];\
} name = { 0, 0, size-1 };
 
 
int circ_Get( circ_buffer_t * p );
int circ_Put( circ_buffer_t * p, unsigned char data );
 
void circ_Init( circ_buffer_t * p );
int circ_HasSpace( circ_buffer_t * p );
int circ_HasData( circ_buffer_t * p );
 
 
#endif

c-file

/**
* @file	circ_buf.c
* @brief Circular Buffer
*
* @author      Rustem Kalimullin
* @par E-mail:
*              hellos@mail.ru
* @par Copyright:
*              (c) Kurt, 2006
*/
 
#include "common.h"
#include "circ_buf.h"
 
//---------------------------------------------------------
//! Get byte from buffer
//! @return -1 if failed
int circ_Get( circ_buffer_t * p )
{
	unsigned int t = p->Get;
	if ( t != p->Put ) {
		p->Get = t+1 &  p->SizeMask;
		return p->Buffer[t];
	}
	return -1;  
}
 
 
//---------------------------------------------------------
//! Put byte to buffer
//! @return -1 if failed
int circ_Put( circ_buffer_t * p, unsigned char data )
{
	unsigned int t = p->Put+1 &  p->SizeMask;
	if( t != p->Get ) {
		p->Buffer[p->Put] = data;
		p->Put = t;
		return 0;
	}
	return -1;
}
 
//---------------------------------------------------------
//! Init buffer
void circ_Init( circ_buffer_t * p )
{
	p->Get = p->Put = 0;   
}
 
//---------------------------------------------------------
int circ_HasSpace( circ_buffer_t * p )
{
	unsigned int t = ( (p->Put + 1) &  p->SizeMask );
	return ( t != p->Get );
}
 
//---------------------------------------------------------
int circ_HasData( circ_buffer_t * p )
{
	unsigned int t = p->Get;
	return ( t != p->Put );
}