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 350
===== Циклический буфер =====
Не самая красивая реализация буфера. Мне самому он не нравится, поэтому и выкладываю :-)
Для формирования используется финт ушами из макроса **DECLARE_CIRC_BUFFER()**. Первый параметр
переменная для буфера, второй - размер буфера в байтах. Очень важно чтобы размер был кратен степени двойки, то бишь 4,8,16,32 и т.д.
Преимущество данного метода меньше писанины в клиентском коде, из недостатков - накладные расходы на вызов функций и неконстантность SizeMask.
*[[circ_buf#h-file]]
*[[circ_buf#c-file]]
*[[circ_buf#example]]
==== example ====
См. также [[sources:uart1|аппаратный уарт]]
#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 );
}