📄 chr_buf.c
字号:
/*********************************************************************
* Copyright (c) 2011-2012,李士伟
* All rights reserved.
*文 件 名:chr_buf.c
*描 述:字符设备队列缓冲区管理模块,
* 这个模块适合顺序访问的字符设备,
* 这只是个参考,汇编写的要效率好点
* 该源文件提供了管理卷绕式单缓冲区的操作函数
* OS_CreateChrBuf: 分配缓冲区内存,并创建缓冲区控制块,
* OS_FreeChrBuf: 释放缓冲区内存和缓冲区控制块内存
* 这种缓冲区是双工工作方式,存取操作能并发进行
* 缓冲区的数据存取操作要严格地使用以下四个函数
* OS_PutChrBufNBytes、OS_GetChrBufNBytes
* OS_GetBufByte、OS_PutBufByte
* 不能直接通过其OS_CHR_BCB指针对缓冲区存取
*编 译:对于ARM处理器使用tcc编译成Thumb指令
*当前版本:V1.00
*作 者:李士伟
*创建日期:2012.01.01
**********************************************************************/
#include <kernel\chr_buf.h>
#include <mm\memory.h>
#include <kernel\asm.h>
/*********************************************************************
*函 数 名:OS_CreateChrBuf
*描 述:创建字符缓冲区
*输入参数:buf_size:缓冲区大小(bytes)
*输出参数:无
*返 回 值:缓冲区控制块指针
*注 意:无
**********************************************************************/
OS_CHR_BCB *OS_CreateChrBuf(INT32U buf_size)
{
OS_CHR_BCB *pbcb;
/* 分配缓冲区内存块 */
pbcb =(OS_CHR_BCB *) malloc(sizeof(OS_CHR_BCB) + buf_size);
if (pbcb == NULL)
{
return NULL;
}
/* 初始化BCB */
pbcb->BufLock = 0;
pbcb->BufTotalSize = buf_size;
pbcb->BufSavedSize = 0;
pbcb->BufStart = (INT8U *)((INT32U)pbcb + sizeof(OS_CHR_BCB));
pbcb->BufEnd = pbcb->BufStart + buf_size - 1;
pbcb->BufIn = pbcb->BufStart;
pbcb->BufOut = pbcb->BufStart;
return pbcb;
}
/*********************************************************************
*函 数 名:OS_FreeChrBuf
*描 述:释放缓冲区
*输入参数:pbcb:缓冲区控制块指针
*输出参数:无
*返 回 值:0,释放失败(有任务在使用缓冲区)
* 1,释放成功
*注 意:
**********************************************************************/
INT32U OS_FreeChrBuf(OS_CHR_BCB *pbcb)
{
if (pbcb == NULL)
{
return 0;
}
OS_ENTER_CRITICAL();
free(pbcb);
OS_EXIT_CRITICAL();
return 1;
}
/*********************************************************************
*函 数 名:OS_PutChrBufNBytes
*描 述:向字符缓冲区输入n个字节
*输入参数:pbcb: 字符缓冲区控制块指针
* s: 字符串指针
* n: 输入字符个数
*输出参数:
*返 回 值:0, 输入失败,表示有任务在输入数据到缓冲区,或缓冲区内存不足
* 1, 输入成功
*注 意:
**********************************************************************/
INT32U OS_PutChrBufNBytes(OS_CHR_BCB *pbcb, INT8U *s, INT32U n)
{
/* 对于非ARM处理器,加register 能够更好的工作 */
register INT8U *in, *out;
register INT32U i;
register INT32U buf_end;
OS_ENTER_CRITICAL();
/* 判断缓冲区输入是否被锁定 */
if (pbcb->BufLock & OS_BUF_INPUT_LOCK)
{
OS_EXIT_CRITICAL();
return 0;
}
/* 判断缓冲区是否有足够剩余内存 */
if (n > (pbcb->BufTotalSize - pbcb->BufSavedSize))
{
OS_EXIT_CRITICAL();
return 0;
}
/* 锁定输入 */
pbcb->BufLock |= OS_BUF_INPUT_LOCK;
in = pbcb->BufIn;
out= pbcb->BufOut;
OS_EXIT_CRITICAL();
buf_end = (INT32U) (pbcb->BufEnd);
/* 卷绕式将数据存入缓冲区 */
if (((INT32U)in >= (INT32U)out) && (n > (buf_end - (INT32U)in)))
{
i = n - (buf_end - (INT32U)in + 1);
while ((INT32U)in <= buf_end)
{
*in++ = *s++;
}
in = pbcb->BufStart;
while (i--)
{
*in++ = *s++;
}
goto __buf_wrap_copy_in_end;
}
/* 直线式将数据存入缓冲区 */
i = n;
while (i--)
{
*in++ = *s++;
}
/* in指向缓冲区尾部检查 */
if ((INT32U)in > buf_end)
{
in = pbcb->BufStart;
}
__buf_wrap_copy_in_end:
OS_ENTER_CRITICAL();
pbcb->BufIn = in; /* 更新输入指针,为下次缓冲区输入准备 */
pbcb->BufSavedSize += n; /* 更新缓冲区保存的字节数 */
pbcb->BufLock &= ~(OS_BUF_INPUT_LOCK); /* 解输入锁 */
OS_EXIT_CRITICAL();
return 1; /* 输入缓冲区成功 */
}
/*********************************************************************
*函 数 名:OS_GetChrBufNBytes
*描 述:字符缓冲区输出n个字节
*输入参数:pbcb: 字符缓冲区控制块指针
* s: 接收字符数据的内存指针
* n: 输出字符个数
*输出参数:
*返 回 值:0, 输出失败,缓冲区数据正被某个任务锁定了输出,或缓冲区数据不足
* 1, 输出成功
*注 意:
**********************************************************************/
INT32U OS_GetChrBufNBytes(OS_CHR_BCB *pbcb, INT8U *s, INT32U n)
{
register INT8U *in, *out;
register INT32U i;
register INT32U buf_end;
OS_ENTER_CRITICAL();
/* 判断缓冲区输出是否被锁定 */
if (pbcb->BufLock & OS_BUF_OUTPUT_LOCK)
{
OS_EXIT_CRITICAL();
return 0;
}
/* 判断缓冲区是否存有足够数据输出 */
if (n > pbcb->BufSavedSize)
{
OS_EXIT_CRITICAL();
return 0;
}
/* 锁定输出 */
pbcb->BufLock |= OS_BUF_OUTPUT_LOCK;
in = pbcb->BufIn;
out= pbcb->BufOut;
OS_EXIT_CRITICAL();
buf_end = (INT32U) (pbcb->BufEnd);
/* 卷绕式输出缓冲区数据 */
if (((INT32U)out >= (INT32U)in) && (n > (buf_end - (INT32U)out)))
{
i = n - (buf_end - (INT32U)out + 1);
while ((INT32U)out <= buf_end)
{
*s++ = *out++;
}
out = pbcb->BufStart;
while (i--)
{
*s++ = *out++;
}
goto __buf_wrap_copy_out_end;
}
/* 直线式输出缓冲区数据 */
i = n;
while (i--)
{
*s++ = *out++;
}
/* out指向缓冲区尾部检查 */
if ((INT32U)out > buf_end)
{
out = pbcb->BufStart;
}
__buf_wrap_copy_out_end:
OS_ENTER_CRITICAL();
pbcb->BufOut = out; /* 更新输出指针,为下次缓冲区输出准备 */
pbcb->BufSavedSize -= n; /* 更新缓冲区保存的字节数 */
pbcb->BufLock &= ~(OS_BUF_OUTPUT_LOCK); /* 解输出锁 */
OS_EXIT_CRITICAL();
return 1; /* 缓冲区输出成功 */
}
/*********************************************************************
*函 数 名:OS_GetChrBufByte
*描 述:从缓冲区获得一个字节
*输入参数:pbcb: 缓冲区控制块指针
* ch:接收字节指针
*输出参数:无
*返 回 值:0,接收无效。1,接收有效
*注 意:
**********************************************************************/
INT32U OS_GetChrBufByte(OS_CHR_BCB *pbcb, INT8U *ch)
{
OS_ENTER_CRITICAL();
/* 判断缓冲区输出是否被锁定 */
if (pbcb->BufLock & OS_BUF_OUTPUT_LOCK)
{
OS_EXIT_CRITICAL();
return 0;
}
/* 判断缓冲区是否存有数据 */
if (pbcb->BufSavedSize == 0)
{
OS_EXIT_CRITICAL();
return 0;
}
*ch = *(pbcb->BufOut);
if (pbcb->BufOut == pbcb->BufEnd)
{
pbcb->BufOut = pbcb->BufStart;
}
else
{
pbcb->BufOut++;
}
pbcb->BufSavedSize--;
OS_EXIT_CRITICAL();
return 1;
}
/*********************************************************************
*函 数 名:OS_PutChrBufByte
*描 述:向缓冲区输入一个字节
*输入参数:pbcb: 缓冲区控制块指针
* ch:输入字节
*输出参数:无
*返 回 值:0,输入无效。1,输入有效
*注 意:
**********************************************************************/
INT32U OS_PutChrBufByte(OS_CHR_BCB *pbcb, INT8U ch)
{
OS_ENTER_CRITICAL();
/* 判断缓冲区输入是否被锁定 */
if (pbcb->BufLock & OS_BUF_INPUT_LOCK)
{
OS_EXIT_CRITICAL();
return 0;
}
/* 判断缓冲区是否存有空余内存 */
if (pbcb->BufTotalSize == pbcb->BufSavedSize)
{
OS_EXIT_CRITICAL();
return 0;
}
*(pbcb->BufIn) = ch;
if (pbcb->BufIn == pbcb->BufEnd)
{
pbcb->BufIn = pbcb->BufStart;
}
else
{
pbcb->BufIn++;
}
pbcb->BufSavedSize++;
OS_EXIT_CRITICAL();
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -