初版
This commit is contained in:
@@ -0,0 +1,400 @@
|
||||
#include "asm/cpu.h"
|
||||
#include "asm/power_interface.h"
|
||||
#include "system/includes.h"
|
||||
#include "os/os_api.h"
|
||||
#include "power/p11_cbuf.h"
|
||||
|
||||
#ifdef SUPPORT_MS_EXTENSIONS
|
||||
#pragma bss_seg(".p11_cbuf.data.bss")
|
||||
#pragma data_seg(".p11_cbuf.data")
|
||||
#pragma const_seg(".p11_cbuf.text.const")
|
||||
#pragma code_seg(".p11_cbuf.text")
|
||||
#endif
|
||||
|
||||
static spinlock_t cbuf_lock;
|
||||
|
||||
#define p11_cbuf_spin_lock() spin_lock(&cbuf_lock)
|
||||
#define p11_cbuf_spin_unlock() spin_unlock(&cbuf_lock)
|
||||
|
||||
|
||||
|
||||
#define CBUF_ENTER_CRITICAL() \
|
||||
do{ \
|
||||
p11_cbuf_spin_lock(); \
|
||||
ipc_spin_lock(IPC_SPIN_LOCK_EVENT_CBUF);\
|
||||
}while(0)
|
||||
|
||||
|
||||
|
||||
#define CBUF_EXIT_CRITICAL() \
|
||||
do{ \
|
||||
ipc_spin_unlock(IPC_SPIN_LOCK_EVENT_CBUF);\
|
||||
p11_cbuf_spin_unlock(); \
|
||||
}while(0)
|
||||
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief 适用范围:全局
|
||||
* @brief cbuffer 通道开关
|
||||
*
|
||||
* @param [in] cbuffer cbuffer 句柄
|
||||
* @param [in] index 通道索引
|
||||
* @param [in] enable 通道开关
|
||||
*/
|
||||
/* ----------------------------------------------------------------------------*/
|
||||
void p11cbuf_mult_entry_enable(p11_cbuffer_t *cbuffer, int index, int enable)
|
||||
{
|
||||
if (!cbuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
cbuffer = (p11_cbuffer_t *)(((int)(cbuffer)) + P11_RAM_BASE);
|
||||
|
||||
if ((!cbuffer->child_count) || index >= cbuffer->child_count) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cbuffer->child) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
cbuffer_child_t *child;
|
||||
child = (cbuffer_child_t *)((int)cbuffer->child + P11_RAM_BASE);
|
||||
|
||||
|
||||
CBUF_ENTER_CRITICAL();
|
||||
if (!enable) { //关操作时候需要释放空间
|
||||
child[index].en = !!enable;
|
||||
child[index].offset = 0;
|
||||
u32 min_offset = (u32) - 1;
|
||||
for (int i = 0; i < cbuffer->child_count; i++) {
|
||||
if (child[i].en && child[i].offset < min_offset) {
|
||||
min_offset = child[i].offset;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < cbuffer->child_count; i++) {
|
||||
if (child[i].en) {
|
||||
child[i].offset -= min_offset;
|
||||
}
|
||||
}
|
||||
|
||||
if (min_offset > cbuffer->data_len) {
|
||||
min_offset = cbuffer->data_len;
|
||||
}
|
||||
|
||||
|
||||
cbuffer->tmp_len = cbuffer->data_len -= min_offset;
|
||||
cbuffer->read_ptr += min_offset;
|
||||
|
||||
if ((u32)cbuffer->read_ptr >= (u32)cbuffer->end) {
|
||||
cbuffer->read_ptr = (u8 *)cbuffer->begin + ((u32)cbuffer->read_ptr - (u32)cbuffer->end);
|
||||
}
|
||||
} else {
|
||||
child[index].en = !!enable;
|
||||
child[index].offset = 0;
|
||||
}
|
||||
CBUF_EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief 适用范围:全局
|
||||
* @brief 获取存储数据的字节长度
|
||||
*
|
||||
* @param [in] cbuffer cbuffer 句柄
|
||||
*
|
||||
* @return 存储数据的字节长度
|
||||
*/
|
||||
/* ----------------------------------------------------------------------------*/
|
||||
u32 p11_cbuf_get_data_len(p11_cbuffer_t *cbuffer)
|
||||
{
|
||||
if (!cbuffer) {
|
||||
return 0;
|
||||
}
|
||||
cbuffer = (p11_cbuffer_t *)(((int)(cbuffer)) + P11_RAM_BASE);
|
||||
return cbuffer->data_len;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief 适用范围:全局
|
||||
* @brief 获取存储数据的字节长度
|
||||
*
|
||||
* @param [in] cbuffer cbuffer 句柄
|
||||
* @param [in] index 当前通道的索引
|
||||
* @return 存储数据的字节长度
|
||||
*/
|
||||
/* ----------------------------------------------------------------------------*/
|
||||
u32 p11_cbuf_mult_read_get_data_len(p11_cbuffer_t *cbuffer, int index)
|
||||
{
|
||||
|
||||
u32 len;
|
||||
if (!cbuffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cbuffer = (p11_cbuffer_t *)(((int)(cbuffer)) + P11_RAM_BASE);
|
||||
|
||||
if (index >= cbuffer->child_count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CBUF_ENTER_CRITICAL();
|
||||
cbuffer_child_t *child;
|
||||
child = (cbuffer_child_t *)((int)cbuffer->child + P11_RAM_BASE);
|
||||
|
||||
if (child[index].en) {
|
||||
len = cbuffer->data_len - child[index].offset;
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
CBUF_EXIT_CRITICAL();
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief 适用范围:memcpy管理+cbuf_read_alloc系列管理函数
|
||||
* @brief 预分配待读取数据的空间,并把读取到的数据存入buf数组
|
||||
*
|
||||
* @param [in] cbuffer cbuffer 句柄
|
||||
* @param [in] index 当前通道的索引
|
||||
* @param [out] buf 存储读取的数据的目标buf数组
|
||||
* @param [in] len 要读取的数据的字节长度
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/* ----------------------------------------------------------------------------*/
|
||||
u32 p11_cbuf_mult_read_alloc_len(p11_cbuffer_t *cbuffer, int index, void *buf, u32 len)
|
||||
{
|
||||
u32 r_len = len;
|
||||
u32 copy_len;
|
||||
u8 *read_ptr;
|
||||
|
||||
if (!cbuffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (buf == NULL) {
|
||||
printf("ERROR :%s %d buff is NULL!!!\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cbuffer = (p11_cbuffer_t *)(((int)(cbuffer)) + P11_RAM_BASE);
|
||||
|
||||
if ((!cbuffer->child_count) || index >= cbuffer->child_count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (!cbuffer->child) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CBUF_ENTER_CRITICAL();
|
||||
cbuffer_child_t *child;
|
||||
child = (cbuffer_child_t *)((int)cbuffer->child + P11_RAM_BASE);
|
||||
|
||||
if (!child[index].en) {
|
||||
CBUF_EXIT_CRITICAL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
read_ptr = cbuffer->read_ptr + child[index].offset;
|
||||
|
||||
if ((u32) read_ptr >= (u32)cbuffer->end) {
|
||||
read_ptr = (u8 *)cbuffer->begin + ((u32)read_ptr - (u32)cbuffer->end);
|
||||
}
|
||||
|
||||
if (cbuffer->data_len - child[index].offset < len) {
|
||||
memset(buf, 0, len);
|
||||
CBUF_EXIT_CRITICAL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
copy_len = (u32)cbuffer->end - (u32)read_ptr;
|
||||
|
||||
if (copy_len > len) {
|
||||
copy_len = len;
|
||||
}
|
||||
len -= copy_len;
|
||||
|
||||
memcpy(buf, read_ptr + P11_RAM_BASE, copy_len);
|
||||
if (len == 0) {
|
||||
/* cbuffer->read_ptr += copy_len; */
|
||||
} else {
|
||||
memcpy((u8 *)buf + copy_len, cbuffer->begin + P11_RAM_BASE, len);
|
||||
}
|
||||
CBUF_EXIT_CRITICAL();
|
||||
return r_len;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief 适用范围:memcpy管理+cbuf_read_alloc系列管理函数
|
||||
* @brief 更新cbuf管理handle的读指针位置和数据长度
|
||||
*
|
||||
* @param [in] cbuffer cbuffer 句柄
|
||||
* @param [in] index 当前通道的索引
|
||||
* @param [in] len 要更新的数据的字节长度
|
||||
*/
|
||||
/* ----------------------------------------------------------------------------*/
|
||||
void p11_cbuf_mult_read_alloc_len_updata(p11_cbuffer_t *cbuffer, int index, u32 len)
|
||||
{
|
||||
if (!cbuffer) {
|
||||
return ;
|
||||
}
|
||||
|
||||
cbuffer = (p11_cbuffer_t *)(((int)(cbuffer)) + P11_RAM_BASE);
|
||||
|
||||
|
||||
if ((!cbuffer->child_count) || index >= cbuffer->child_count) {
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!cbuffer->child) {
|
||||
return ;
|
||||
}
|
||||
|
||||
CBUF_ENTER_CRITICAL();
|
||||
|
||||
cbuffer_child_t *child;
|
||||
child = (cbuffer_child_t *)((int)cbuffer->child + P11_RAM_BASE);
|
||||
|
||||
if (!child[index].en) {
|
||||
CBUF_EXIT_CRITICAL();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (len + child[index].offset > cbuffer->data_len) {
|
||||
len = cbuffer->data_len - child[index].offset;
|
||||
}
|
||||
|
||||
child[index].offset += len;
|
||||
u32 min_offset = (u32) - 1;
|
||||
|
||||
for (int i = 0; i < cbuffer->child_count; i++) {
|
||||
if (child[i].en && child[i].offset < min_offset) {
|
||||
min_offset = child[i].offset;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < cbuffer->child_count; i++) {
|
||||
if (child[i].en) {
|
||||
child[i].offset -= min_offset;
|
||||
}
|
||||
}
|
||||
|
||||
if (min_offset > cbuffer->data_len) {
|
||||
ASSERT(0);
|
||||
/* min_offset = cbuffer->data_len; */
|
||||
}
|
||||
|
||||
|
||||
cbuffer->tmp_len = cbuffer->data_len -= min_offset;
|
||||
cbuffer->read_ptr += min_offset;
|
||||
|
||||
|
||||
if ((u32)cbuffer->read_ptr >= (u32)cbuffer->end) {
|
||||
cbuffer->read_ptr = (u8 *)cbuffer->begin + ((u32)cbuffer->read_ptr - (u32)cbuffer->end);
|
||||
}
|
||||
|
||||
|
||||
CBUF_EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
|
||||
#define P11_CBUF_TEST 0
|
||||
|
||||
#include "p11_app_msg.h"
|
||||
|
||||
#if P11_CBUF_TEST
|
||||
|
||||
|
||||
static p11_cbuffer_t *cbuffer;
|
||||
static void master_read_p11(void *p)
|
||||
{
|
||||
static int index_1;
|
||||
static int index_2;
|
||||
static int index_3;
|
||||
|
||||
u8 test[50];
|
||||
int len = p11_cbuf_mult_read_alloc_len(cbuffer, 0, test, 10);
|
||||
if (len) {
|
||||
p11_cbuf_mult_read_alloc_len_updata(cbuffer, 0, len);
|
||||
printf("index 0 read len %d ,left %d,total %d\n", len, p11_cbuf_mult_read_get_data_len(cbuffer, 0), p11_cbuf_get_data_len(cbuffer));
|
||||
put_buf(test, len);
|
||||
index_1 += len;
|
||||
if (index_1 == 50) {
|
||||
p11cbuf_mult_entry_enable(cbuffer, 1, 0);
|
||||
printf("stop index 1\n");
|
||||
}
|
||||
if (index_1 == 100) {
|
||||
p11cbuf_mult_entry_enable(cbuffer, 1, 1);
|
||||
printf("open index 1\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printf("%s %d %x\n", __func__, __LINE__, (int)cbuffer);
|
||||
|
||||
len = p11_cbuf_mult_read_alloc_len(cbuffer, 1, test, 25);
|
||||
if (len) {
|
||||
p11_cbuf_mult_read_alloc_len_updata(cbuffer, 1, len);
|
||||
printf("index 1 read len %d ,left %d,total %d\n", len, p11_cbuf_mult_read_get_data_len(cbuffer, 1), p11_cbuf_get_data_len(cbuffer));
|
||||
put_buf(test, len);
|
||||
|
||||
}
|
||||
|
||||
len = p11_cbuf_mult_read_alloc_len(cbuffer, 2, test, 5);
|
||||
if (len) {
|
||||
p11_cbuf_mult_read_alloc_len_updata(cbuffer, 2, len);
|
||||
printf("index 2 read len %d ,left %d,total %d\n", len, p11_cbuf_mult_read_get_data_len(cbuffer, 2), p11_cbuf_get_data_len(cbuffer));
|
||||
put_buf(test, len);
|
||||
}
|
||||
|
||||
task_post_msg2p11(NULL, 1, MSG_P11_SYS_KICK);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void test_handler(void *priv, u8 *buf, u32 len)
|
||||
{
|
||||
if (buf == NULL) {
|
||||
printf("ERROR :%s %d buff is NULL!!!\n", __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
int msg[16];
|
||||
printf("msg: %d, len: %d\n", msg[0], len);
|
||||
ASSERT(len < sizeof(msg));
|
||||
memcpy(msg, buf, len);
|
||||
switch (msg[0]) {
|
||||
case MSG_P11_SYS_RAM_INIT:
|
||||
printf("MSG_P11_SYS_RAM_INIT %x\n", msg[1]);
|
||||
cbuffer = (p11_cbuffer_t *)msg[1];
|
||||
sys_timer_add(NULL, master_read_p11, 1000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_P2M_MSG_HANDLER(NULL, MSG_APP, test_handler);
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user