?? ring.c
字號:
//----------------------------------------------------
//Copyright (C), 2004-2009, lst.
//版權所有 (C), 2004-2009, lst.
//所屬模塊: 緩沖區
//作者:lst
//版本:V1.0.0
//文件描述: 提供環形緩沖區服務
//其他說明:
//修訂歷史:
// 2. ...
// 1. 日期:
// 作者:
// 新版本號:
// 修改說明:
//------------------------------------------------------
#include "inc_os.h"
#include <string.h>
//----建立環形緩沖區----------------------------------------------------------
//功能: 建立環形緩沖區并初始化,使用這個函數之前,用戶應該定義緩沖區內存塊和
// 緩沖區數據結構。
//參數: ring,目標環形緩沖區結構指針
// buf,緩沖區起始地址
// len,緩沖區長度.單位是字節數
//返回: 無
//-----------------------------------------------------------------------------
void ring_init(struct ring_buf *ring, uint8_t *buf, uint32_t len)
{
ring->buf = buf;
ring->max_len = len;
ring->offset_write = 0;
ring->offset_read = 0;
ring->len = 0;
}
//----檢查緩沖區容量-----------------------------------------------------------
//功能: 返回緩沖區容量
//參數: ring,目標線性緩沖區結構指針
//返回: 緩沖區容量,就是調用ring_init時使用的len參數。
//-----------------------------------------------------------------------------
uint32_t ring_capacity(struct ring_buf *ring)
{
return ring->max_len;
}
//----返回字節池地址-----------------------------------------------------------
//功能: 查詢緩沖區的字節池地址,這個地址是用戶調用ring_init時使用的緩沖區地址。
//參數: ring,目標線性緩沖區指針.
//返回: 環形緩沖區的字節池地址
//說明: 有兩種情況會產生獲得緩沖區地址的需求
// 1、要釋放緩沖區內存,應用程序可以使用調用ring_init時使用的指針,如果該
// 指針丟失,可用本函數取回該指針。
// 2、用戶想自己動手訪問該緩沖區,這不是一個明智的選擇,有破壞模塊獨立性
// 的嫌疑,這時候,使用者應該完全明白自己在干什么!
//-----------------------------------------------------------------------------
uint8_t *ring_get_buf(struct ring_buf *ring)
{
return ring->buf;
}
//----環形緩沖區寫入-----------------------------------------------------------
//功能: 環形緩沖區寫入若干個字節,返回實際寫入的數據量,并移動寫指針,如果環形
// 緩沖區沒有足夠的空間,按實際剩余空間寫入
//參數: ring,目標環形緩沖區結構指針
// buffer,待寫入的數據指針
// len,待寫入的數據長度.單位是字節數
//返回: 實際寫入的字節數,如果緩沖區有足夠的空間,=len
//-----------------------------------------------------------------------------
uint32_t ring_write(struct ring_buf *ring,uint8_t *buffer,uint32_t len)
{
uint32_t wr_len;
uint32_t partial;
wr_len = ring->max_len - ring->len;
if(wr_len == 0)
return 0;
if(wr_len > len)
wr_len = len;
if((ring->offset_write + wr_len) > ring->max_len)
{ //數據發生環繞
partial = ring->max_len - ring->offset_write;
memcpy(&ring->buf[ring->offset_write],buffer,partial); //寫第一部分
memcpy( ring->buf,&buffer[partial],wr_len - partial); //寫第二部分
ring->offset_write = wr_len - partial;
}else
{ //不發生環繞
memcpy( &ring->buf[ring->offset_write],buffer,wr_len);
ring->offset_write +=wr_len;
}
ring->len += wr_len;
return wr_len;
}
//----從環形緩沖區讀-----------------------------------------------------------
//功能: 從環形緩沖區讀出若干個字節,返回實際讀出的數據量,并且移動讀指針如果
// 緩沖區內數據不足,按實際數量讀取。
//參數: ring,目標環形緩沖區結構指針
// buffer,接收數據的緩沖區指針
// len,待讀出的數據長度.單位是字節數
//返回: 實際讀出的字節數,如果緩沖區有足夠的數據,=len
//------------------------------------------------------------------------------
uint32_t ring_read(struct ring_buf *ring,uint8_t *buffer,uint32_t len)
{
uint32_t wr_len;
wr_len = (ring->len < len)? ring->len : len;
if((ring->offset_read + wr_len) > ring->max_len)
{ //數據發生環繞
uint32_t partial;
partial =ring->max_len - ring->offset_read;
memcpy( buffer,&ring->buf[ring->offset_read],partial); //寫第一部分
memcpy( &buffer[partial],ring->buf,wr_len - partial); //寫第二部分
ring->offset_read = wr_len - partial;
}else
{ //不發生環繞
memcpy( buffer,&ring->buf[ring->offset_read],wr_len);
ring->offset_read += wr_len;
}
ring->len -= wr_len;
return wr_len;
}
//----檢查緩沖區數據量----------------------------------------------------------
//功能: 檢查指定的環形緩沖區中的數據量,返回字節數.
//參數: ring,目標環形緩沖區指針.
//返回: 緩沖區中的數據量
//------------------------------------------------------------------------------
uint32_t ring_check(struct ring_buf *ring)
{
return ring->len;
}
//----檢查緩沖區是否空-----------------------------------------------------------
//功能: 檢查指定的環形緩沖區中是否已經空.
//參數: ring,目標環形緩沖區指針.
//返回: 空則返回true,非空返回false
//------------------------------------------------------------------------------
bool_t ring_if_empty(struct ring_buf *ring)
{
return (ring->len ==0)? true:false;
}
//----檢查緩沖區是否滿-----------------------------------------------------------
//功能: 檢查指定的環形緩沖區中是否已經滿.
//參數: ring,目標環形緩沖區指針.
//返回: 滿則返回true,非滿返回false
//------------------------------------------------------------------------------
bool_t ring_if_full(struct ring_buf *ring)
{
return (ring->len == ring->max_len)? true:false;
}
//----清空環形緩沖區-------------------------------------------------------------
//功能: 清除緩沖區中所有數據
//參數: ring,目標環形緩沖區指針.
//返回: 無
//------------------------------------------------------------------------------
void ring_flush(struct ring_buf *ring)
{
ring->len = 0;
ring->offset_write = 0;
ring->offset_read = 0;
}
//----釋放若干數據---------------------------------------------------------------
//功能: 從讀指針開始,釋放掉指定大小的數據,相當于啞讀了len個字節
//參數: ring,目標環形緩沖區指針.
// len,釋放的數據數量
//返回: 實際釋放的數據量
//------------------------------------------------------------------------------
uint32_t ring_dumb_read(struct ring_buf *ring,uint32_t len)
{
uint32_t result;
result = (ring->len < len)? ring->len : len;
if((ring->offset_read + result) > ring->max_len)
{ //數據發生環繞
ring->offset_read = result + ring->offset_read - ring->max_len;
}else
{ //不發生環繞
ring->offset_read += result;
}
ring->len -= result;
return result;
}
//----退回若干數據-------------------------------------------------------------
//功能: 本函數與ring_dumb_read函數正好相反,把緩沖區指針退回len字節,如果退回的
// 長度超過緩沖區的空閑長度,則取緩沖區空閑長度。相當于把緩沖區中已經讀出
// 的數據返回緩沖區,好像沒有讀過的樣子。ring模塊并不校驗退回的部分是否包含
// 原來的數據。
//參數: ring,目標環形緩沖區指針.
// len,退回的數據數量
//返回: 實際退回的數據量
//-----------------------------------------------------------------------------
uint32_t ring_recede_read(struct ring_buf *ring,uint32_t len)
{
uint32_t result;
if((ring->max_len - ring->len) > len) //空閑長度大于欲退回的長度
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -