⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chr_buf.c

📁 Rabbit 32Bit RTOS源代码
💻 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 + -