69,382
社区成员
发帖
与我相关
我的任务
分享
/*
参考:
[源代码] C语言队列实现
http://avr.cnta.net/forum.php?mod=viewthread&tid=287
*/
#if defined(__CIRCLE_BUFFER__)
//"circle_buffer.h"
#ifndef __CIRCLE_BUFFER_H__
#define __CIRCLE_BUFFER_H__
#if defined(__CIRCLE_BUFFER__)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
typedef unsigned char cb_u8;
typedef unsigned short int cb_u16;
typedef unsigned int cb_u32;
typedef signed char cb_s8;
typedef signed short int cb_s16;
typedef signed int cb_s32;
typedef char cb_char;
typedef enum {cb_false, cb_true} cb_bool;
typedef struct {
cb_u8 *bufptr;
cb_u32 buflen;
cb_u32 datalen;
cb_u32 readpos;
cb_u32 writepos;
}CircleBufferMngr;
typedef struct {
void (*cb_init)(CircleBufferMngr **, cb_u32);
void (*cb_deinit)(CircleBufferMngr **);
void (*cb_info)(CircleBufferMngr *, cb_char *, cb_u32);
cb_u32 (*cb_read)(CircleBufferMngr *, cb_u8 *, cb_u32);
cb_u32 (*cb_write)(CircleBufferMngr *, cb_u8 *, cb_u32);
cb_u32 (*cb_datalen)(CircleBufferMngr *);
cb_bool (*cb_full)(CircleBufferMngr *);
cb_bool (*cb_empty)(CircleBufferMngr *);
}CircleBufferApi;
#define CB_MEMCPY memcpy
#define CB_MEMSET memset
#define CB_SPRINT sprintf
#define CB_MALLOC malloc
#define CB_MFREE free
#define CB_ASSERT assert
#define CB_SNPRINT snprintf
#define CB_TRACE printf
//锁定, 禁止中断和任务调度
#define CB_GLOBAL_LOCK
#define CB_GLOBAL_UNLOCK
extern const CircleBufferApi circleBufApi;
#define CBMA_INIT circleBufApi.cb_init
#define CBMA_DEINIT circleBufApi.cb_deinit
#define CBMA_INFO circleBufApi.cb_info
#define CBMA_READ circleBufApi.cb_read
#define CBMA_WRITE circleBufApi.cb_write
#define CBMA_DATALEN circleBufApi.cb_datalen
#define CBMA_FULL circleBufApi.cb_full
#define CBMA_EMPTY circleBufApi.cb_empty
#endif/*__CIRCLE_BUFFER__*/
#endif/*__CIRCLE_BUFFER_H__*/
/*******************************************************************************
** 函数: cb_init
** 功能: 初始化
** 作者: avrbase_lei
*******/
static void cb_init(CircleBufferMngr **ppmngr, cb_u32 buflen);
/*******************************************************************************
** 函数: cb_deinit
** 功能: 资源释放
** 作者: avrbase_lei
*******/
static void cb_deinit(CircleBufferMngr **ppmngr);
/*******************************************************************************
** 函数: cb_info
** 功能: 打印管理变量中的各种值到长度为buflen的outbuf中
** 作者: avrbase_lei
*******/
static void cb_info(
CircleBufferMngr *pmngr,
int (*user_printf)(const char *, ...));
/*******************************************************************************
** 函数: cb_read
** 功能: 读取不超过buflen长度的数据到outbuf中, 其中outbuf的长度不得低于buflen
** 返回: 返回实际读取的数据长度, 字节为单位
** 说明: 如果传入的outbuf地址为NULL, 则直接删除buflen长度的数据
** 作者: avrbase_lei
*******/
static cb_u32 cb_read(
CircleBufferMngr *pmngr,
cb_u8 *outbuf,
cb_u32 buflen);
/*******************************************************************************
** 函数: cb_write
** 功能: 将datptr所指向的地址中的datlen长度的数据写入到pmngr->bufptr中
** 返回: 返回实际写入的数据长度, 字节为单位
** 作者: avrbase_lei
*******/
static cb_u32 cb_write(
CircleBufferMngr *pmngr,
cb_u8 *datptr,
cb_u32 datlen);
/*******************************************************************************
** 函数: cb_datalen
** 功能: 查询pmngr->bufptr中的数据长度
** 返回: 返回pmngr->bufptr数据长度, 字节为单位
** 作者: avrbase_lei
*******/
static cb_u32 cb_datalen(CircleBufferMngr *pmngr);
/*******************************************************************************
** 函数: cb_full
** 功能: 判断缓冲区是否已满
** 作者: avrbase_lei
*******/
static cb_bool cb_full(CircleBufferMngr *pmngr);
/*******************************************************************************
** 函数: cb_empty
** 功能: 判断缓冲区是否为空
** 作者: avrbase_lei
*******/
static cb_bool cb_empty(CircleBufferMngr *pmngr);
/*******************************************************************************
** 函数: cb_init
** 功能: 初始化
** 作者: avrbase_lei
*******/
static void cb_init(CircleBufferMngr **ppmngr, cb_u32 buflen)
{
CB_ASSERT(NULL != ppmngr);
if (NULL != *ppmngr)
return;
if (0 == buflen)
return;
*ppmngr = (CircleBufferMngr*)CB_MALLOC(sizeof(CircleBufferMngr));
CB_ASSERT(NULL != *ppmngr);
CB_MEMSET((void*)*ppmngr, 0, sizeof(CircleBufferMngr));
(*ppmngr)->bufptr = (cb_u8*)CB_MALLOC(buflen);
CB_ASSERT(NULL != (*ppmngr)->bufptr);
(*ppmngr)->buflen = buflen;
CB_MEMSET((void*)(*ppmngr)->bufptr, 0, buflen);
}
/*******************************************************************************
** 函数: cb_deinit
** 功能: 资源释放
** 作者: avrbase_lei
*******/
static void cb_deinit(CircleBufferMngr **ppmngr)
{
CB_ASSERT(NULL != ppmngr);
if(NULL == *ppmngr)
return;
if (NULL != (*ppmngr)->bufptr)
{
CB_MFREE((*ppmngr)->bufptr);
(*ppmngr)->bufptr = NULL;
(*ppmngr)->buflen = 0;
}
CB_MFREE(*ppmngr);
*ppmngr = NULL;
}
/*******************************************************************************
** 函数: cb_info
** 功能: 打印管理变量中的各种值到长度为buflen的outbuf中
** 作者: avrbase_lei
*******/
static void cb_info(
CircleBufferMngr *pmngr,
int (*user_printf)(const char *, ...))
{
CB_ASSERT(NULL != pmngr);
user_printf(
"datalen=%d,readpos=%d,writepos=%d.",
pmngr->datalen,
pmngr->readpos,
pmngr->writepos);
}
/*******************************************************************************
** 函数: cb_read
** 功能: 读取不超过buflen长度的数据到outbuf中, outbuf的长度不得低于buflen
** 返回: 返回实际读取的数据长度, 字节为单位
** 说明: 如果传入的outbuf地址为NULL, 则直接删除buflen长度的数据
** 作者: avrbase_lei
*******/
static cb_u32 cb_read(
CircleBufferMngr *pmngr,
cb_u8 *outbuf,
cb_u32 buflen)
{
cb_u32 readlen = 0, tmplen = 0;
CB_ASSERT(NULL != pmngr);
CB_ASSERT(NULL != pmngr->bufptr);
if(cb_empty(pmngr))
return 0;
CB_GLOBAL_LOCK;
readlen = buflen > pmngr->datalen ? pmngr->datalen : buflen;
tmplen = pmngr->buflen - pmngr->readpos;
if(NULL != outbuf)
{
if(readlen <= tmplen)
{
CB_MEMCPY(
(void*)outbuf,
(void*)&pmngr->bufptr[pmngr->readpos],
readlen);
}
else
{
CB_MEMCPY(
(void*)outbuf,
(void*)&pmngr->bufptr[pmngr->readpos],
tmplen);
CB_MEMCPY(
(void*)&outbuf[tmplen],
(void*)pmngr->bufptr,
readlen - tmplen);
}
}
pmngr->readpos = (pmngr->readpos + readlen) % pmngr->buflen;
pmngr->datalen -= readlen;
CB_GLOBAL_UNLOCK;
return readlen;
}
/*******************************************************************************
** 函数: cb_write
** 功能: 将datptr所指向的地址中的datlen长度的数据写入到pmngr->bufptr中
** 返回: 返回实际写入的数据长度, 字节为单位
** 作者: avrbase_lei
*******/
static cb_u32 cb_write(CircleBufferMngr *pmngr, cb_u8 *datptr, cb_u32 datlen)
{
cb_u32 writelen = 0, tmplen = 0;
CB_ASSERT(NULL != pmngr);
CB_ASSERT(NULL != pmngr->bufptr);
if(cb_full(pmngr))
return 0;
CB_GLOBAL_LOCK;
tmplen = pmngr->buflen - pmngr->datalen;
writelen = tmplen > datlen ? datlen : tmplen;
if(pmngr->writepos < pmngr->readpos)
{
CB_MEMCPY(
(void*)&pmngr->bufptr[pmngr->writepos],
(void*)datptr,
writelen);
}
else
{
tmplen = pmngr->buflen - pmngr->writepos;
if(writelen <= tmplen)
{
CB_MEMCPY(
(void*)&pmngr->bufptr[pmngr->writepos],
(void*)datptr,
writelen);
}
else
{
CB_MEMCPY(
(void*)&pmngr->bufptr[pmngr->writepos],
(void*)datptr,
tmplen);
CB_MEMCPY(
(void*)pmngr->bufptr,
(void*)&datptr[tmplen],
writelen - tmplen);
}
}
pmngr->writepos = (pmngr->writepos + writelen) % pmngr->buflen;
pmngr->datalen += writelen;
CB_GLOBAL_UNLOCK;
return writelen;
}
/*******************************************************************************
** 函数: cb_datalen
** 功能: 查询pmngr->bufptr中的数据长度
** 返回: 返回pmngr->bufptr数据长度, 字节为单位
** 作者: avrbase_lei
*******/
static cb_u32 cb_datalen(CircleBufferMngr *pmngr)
{
CB_ASSERT(NULL != pmngr);
return pmngr->datalen;
}
/*******************************************************************************
** 函数: cb_full
** 功能: 判断缓冲区是否已满
** 作者: avrbase_lei
*******/
static cb_bool cb_full(CircleBufferMngr *pmngr)
{
CB_ASSERT(NULL != pmngr);
return (cb_bool)(pmngr->buflen == pmngr->datalen);
}
/*******************************************************************************
** 函数: cb_empty
** 功能: 判断缓冲区是否为空
** 作者: avrbase_lei
*******/
static cb_bool cb_empty(CircleBufferMngr *pmngr)
{
CB_ASSERT(NULL != pmngr);
return (cb_bool)(0 == pmngr->datalen);
}
const CircleBufferApi circleBufApi = {
cb_init,
cb_deinit,
cb_info,
cb_read,
cb_write,
cb_datalen,
cb_full,
cb_empty,
};
#endif
//循环向a函数每次发送200个字节长度(这个是固定的)的buffer,
//a函数中需要将循环传进来的buffer,组成240字节(也是固定的)的新buffer进行处理,
//在处理的时候每次从新buffer中取两个字节打印
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <process.h>
#include <io.h>
//Log{
#define MAXLOGSIZE 20000000
#define MAXLINSIZE 16000
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
static char logstr[MAXLINSIZE+1];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
void Lock(CRITICAL_SECTION *l) {
EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
LeaveCriticalSection(l);
}
void LogV(const char *pszFmt,va_list argp) {
struct tm *now;
struct timeb tb;
if (NULL==pszFmt||0==pszFmt[0]) return;
_vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);
ftime(&tb);
now=localtime(&tb.time);
sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
sprintf(timestr,"%02d:%02d:%02d",now->tm_hour ,now->tm_min ,now->tm_sec );
sprintf(mss,"%03d",tb.millitm);
printf("%s %s.%s %s",datestr,timestr,mss,logstr);
flog=fopen(logfilename1,"a");
if (NULL!=flog) {
fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
if (ftell(flog)>MAXLOGSIZE) {
fclose(flog);
if (rename(logfilename1,logfilename2)) {
remove(logfilename2);
rename(logfilename1,logfilename2);
}
} else {
fclose(flog);
}
}
}
void Log(const char *pszFmt,...) {
va_list argp;
Lock(&cs_log);
va_start(argp,pszFmt);
LogV(pszFmt,argp);
va_end(argp);
Unlock(&cs_log);
}
//Log}
#define ASIZE 200
#define BSIZE 240
#define CSIZE 2
char Abuf[ASIZE];
char Cbuf[CSIZE];
CRITICAL_SECTION cs_HEX ;
CRITICAL_SECTION cs_BBB ;
struct FIFO_BUFFER {
int head;
int tail;
int size;
char data[BSIZE];
} BBB;
int No_Loop=0;
void HexDump(int cn,char *buf,int len) {
int i,j,k;
char binstr[80];
Lock(&cs_HEX);
for (i=0;i<len;i++) {
if (0==(i%16)) {
sprintf(binstr,"%03d %04x -",cn,i);
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
} else if (15==(i%16)) {
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
sprintf(binstr,"%s ",binstr);
for (j=i-15;j<=i;j++) {
sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
}
Log("%s\n",binstr);
} else {
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
}
}
if (0!=(i%16)) {
k=16-(i%16);
for (j=0;j<k;j++) {
sprintf(binstr,"%s ",binstr);
}
sprintf(binstr,"%s ",binstr);
k=16-k;
for (j=i-k;j<i;j++) {
sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
}
Log("%s\n",binstr);
}
Unlock(&cs_HEX);
}
int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
int lent,len1,len2;
lent=0;
Lock(cs);
if (fbuf->size>=len) {
lent=len;
if (fbuf->head+lent>BSIZE) {
len1=BSIZE-fbuf->head;
memcpy(buf ,fbuf->data+fbuf->head,len1);
len2=lent-len1;
memcpy(buf+len1,fbuf->data ,len2);
fbuf->head=len2;
} else {
memcpy(buf ,fbuf->data+fbuf->head,lent);
fbuf->head+=lent;
}
fbuf->size-=lent;
}
Unlock(cs);
return lent;
}
void thdB(void *pcn) {
char *recv_buf;
int recv_nbytes;
int cn;
int wc;
int pb;
cn=(int)pcn;
Log("%03d thdB thread begin...\n",cn);
while (1) {
Sleep(10);
recv_buf=(char *)Cbuf;
recv_nbytes=CSIZE;
wc=0;
while (1) {
pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);
if (pb) {
Log("%03d recv %d bytes\n",cn,pb);
HexDump(cn,recv_buf,pb);
Sleep(1);
} else {
Sleep(1000);
}
if (No_Loop) break;//
wc++;
if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
}
if (No_Loop) break;//
}
}
int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {
int lent,len1,len2;
Lock(cs);
lent=len;
if (fbuf->size+lent>BSIZE) {
lent=BSIZE-fbuf->size;
}
if (fbuf->tail+lent>BSIZE) {
len1=BSIZE-fbuf->tail;
memcpy(fbuf->data+fbuf->tail,buf ,len1);
len2=lent-len1;
memcpy(fbuf->data ,buf+len1,len2);
fbuf->tail=len2;
} else {
memcpy(fbuf->data+fbuf->tail,buf ,lent);
fbuf->tail+=lent;
}
fbuf->size+=lent;
Unlock(cs);
return lent;
}
void thdA(void *pcn) {
char *send_buf;
int send_nbytes;
int cn;
int wc;
int a;
int pa;
cn=(int)pcn;
Log("%03d thdA thread begin...\n",cn);
a=0;
while (1) {
Sleep(100);
memset(Abuf,a,ASIZE);
a=(a+1)%256;
if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop
send_buf=(char *)Abuf;
send_nbytes=ASIZE;
Log("%03d sending %d bytes\n",cn,send_nbytes);
HexDump(cn,send_buf,send_nbytes);
wc=0;
while (1) {
pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);
Log("%03d sent %d bytes\n",cn,pa);
HexDump(cn,send_buf,pa);
send_buf+=pa;
send_nbytes-=pa;
if (send_nbytes<=0) break;//
Sleep(1000);
if (No_Loop) break;//
wc++;
if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
}
if (No_Loop) break;//
}
}
int main() {
InitializeCriticalSection(&cs_log );
Log("Start===========================================================\n");
InitializeCriticalSection(&cs_HEX );
InitializeCriticalSection(&cs_BBB );
BBB.head=0;
BBB.tail=0;
BBB.size=0;
_beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);
_beginthread((void(__cdecl *)(void *))thdB,0,(void *)2);
if (!access("No_Loop",0)) {
remove("No_Loop");
if (!access("No_Loop",0)) {
No_Loop=1;
}
}
while (1) {
Sleep(1000);
if (No_Loop) break;//
if (!access("No_Loop",0)) {
No_Loop=1;
}
}
Sleep(3000);
DeleteCriticalSection(&cs_BBB );
DeleteCriticalSection(&cs_HEX );
Log("End=============================================================\n");
DeleteCriticalSection(&cs_log );
return 0;
}