初版
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS_APP
|
||||
#pragma bss_seg(".cbuf.data.bss")
|
||||
#pragma data_seg(".cbuf.data")
|
||||
#pragma const_seg(".cbuf.text.const")
|
||||
#pragma code_seg(".cbuf.text")
|
||||
#endif
|
||||
#include "lib_include.h"
|
||||
#include "circular_buf.h"
|
||||
#if 1
|
||||
#define CPU_SR_ALLOC()
|
||||
|
||||
//#pragma code_seg(".cbuf_code")
|
||||
|
||||
u32 cbuf_read(cbuffer_t *cbuffer, void *buf, u32 len)
|
||||
{
|
||||
CPU_SR_ALLOC();
|
||||
u32 r_len = len;
|
||||
u32 copy_len;
|
||||
|
||||
if (!cbuffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((u32)cbuffer->read_ptr >= (u32)cbuffer->end) {
|
||||
cbuffer->read_ptr = (u8 *)cbuffer->begin;
|
||||
}
|
||||
|
||||
if (cbuffer->data_len < len) {
|
||||
/* memset(buf, 0, len); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
copy_len = (u32)cbuffer->end - (u32)cbuffer->read_ptr;
|
||||
if (copy_len > len) {
|
||||
copy_len = len;
|
||||
}
|
||||
len -= copy_len;
|
||||
|
||||
memcpy(buf, cbuffer->read_ptr, copy_len);
|
||||
//printf_data(cbuffer->read_ptr,copy_len) ;
|
||||
|
||||
if (len == 0) {
|
||||
cbuffer->read_ptr += copy_len;
|
||||
} else {
|
||||
memcpy((u8 *)buf + copy_len, cbuffer->begin, len);
|
||||
//printf_data(cbuffer->begin,len);
|
||||
cbuffer->read_ptr = cbuffer->begin + len;
|
||||
}
|
||||
|
||||
local_irq_disable();
|
||||
cbuffer->tmp_len = cbuffer->data_len -= r_len;
|
||||
|
||||
cbuffer->tmp_len = cbuffer->data_len;
|
||||
|
||||
local_irq_enable();
|
||||
|
||||
return r_len;
|
||||
}
|
||||
|
||||
u32 cbuf_is_write_able(cbuffer_t *cbuffer, u32 len)
|
||||
{
|
||||
u32 w_len;
|
||||
|
||||
if (!cbuffer) {
|
||||
return 0;
|
||||
}
|
||||
w_len = cbuffer->total_len - cbuffer->data_len;
|
||||
if (w_len < len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return w_len;
|
||||
}
|
||||
|
||||
|
||||
u32 cbuf_write(cbuffer_t *cbuffer, void *buf, u32 len)
|
||||
{
|
||||
CPU_SR_ALLOC();
|
||||
u32 length;
|
||||
u32 remain_len;
|
||||
|
||||
if (!cbuffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((cbuffer->total_len - cbuffer->data_len) < len) {
|
||||
len = cbuffer->total_len - cbuffer->data_len ;
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
length = (u32)cbuffer->end - (u32)cbuffer->write_ptr;
|
||||
if (length >= len) {
|
||||
memcpy(cbuffer->write_ptr, buf, len);
|
||||
cbuffer->write_ptr += len;
|
||||
} else {
|
||||
remain_len = len - length;
|
||||
memcpy(cbuffer->write_ptr, buf, length);
|
||||
memcpy(cbuffer->begin, ((u8 *)buf) + length, remain_len);
|
||||
cbuffer->write_ptr = (u8 *)cbuffer->begin + remain_len;
|
||||
}
|
||||
|
||||
local_irq_disable();
|
||||
cbuffer->data_len += len;
|
||||
cbuffer->tmp_len = cbuffer->data_len ;
|
||||
cbuffer->tmp_ptr = cbuffer->write_ptr ;
|
||||
local_irq_enable();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void cbuf_init(cbuffer_t *cbuffer, void *buf, u32 size)
|
||||
{
|
||||
cbuffer->data_len = 0;
|
||||
cbuffer->tmp_len = 0 ;
|
||||
cbuffer->begin = buf;
|
||||
cbuffer->read_ptr = buf;
|
||||
cbuffer->write_ptr = buf;
|
||||
cbuffer->tmp_ptr = buf;
|
||||
cbuffer->end = (u8 *)buf + size;
|
||||
cbuffer->total_len = size;
|
||||
}
|
||||
|
||||
void cbuf_clear(cbuffer_t *cbuffer)
|
||||
{
|
||||
CPU_SR_ALLOC();
|
||||
local_irq_disable();
|
||||
cbuffer->read_ptr = cbuffer->begin;
|
||||
cbuffer->tmp_ptr = cbuffer->write_ptr = cbuffer->begin;
|
||||
cbuffer->data_len = 0;
|
||||
cbuffer->tmp_len = 0 ;
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
u32 cbuf_get_data_size(cbuffer_t *cbuffer)
|
||||
{
|
||||
//printf(">>cbuf_dat_len:%x\n",cbuffer->data_len);
|
||||
return cbuffer->data_len;
|
||||
}
|
||||
|
||||
#define CBUF_ENTER_CRITICAL local_irq_disable
|
||||
#define CBUF_EXIT_CRITICAL local_irq_enable
|
||||
|
||||
void cbuf_read_alloc_len_updata(cbuffer_t *cbuffer, u32 len)
|
||||
{
|
||||
CBUF_ENTER_CRITICAL();
|
||||
|
||||
cbuffer->read_ptr += len;
|
||||
if ((u32)cbuffer->read_ptr >= (u32)cbuffer->end) {
|
||||
cbuffer->read_ptr = (u8 *)cbuffer->begin + ((u32)cbuffer->read_ptr - (u32)cbuffer->end);
|
||||
}
|
||||
|
||||
cbuffer->tmp_len = cbuffer->data_len -= len;
|
||||
|
||||
CBUF_EXIT_CRITICAL();
|
||||
}
|
||||
u32 cbuf_read_alloc_len(cbuffer_t *cbuffer, void *buf, u32 len)
|
||||
{
|
||||
u32 r_len = len;
|
||||
u32 copy_len;
|
||||
|
||||
if (!cbuffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((u32)cbuffer->read_ptr >= (u32)cbuffer->end) {
|
||||
cbuffer->read_ptr = (u8 *)cbuffer->begin;
|
||||
}
|
||||
|
||||
if (cbuffer->data_len < len) {
|
||||
/* memset(buf, 0, len); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
copy_len = (u32)cbuffer->end - (u32)cbuffer->read_ptr;
|
||||
if (copy_len > len) {
|
||||
copy_len = len;
|
||||
}
|
||||
len -= copy_len;
|
||||
|
||||
memcpy(buf, cbuffer->read_ptr, copy_len);
|
||||
//printf_data(cbuffer->read_ptr,copy_len) ;
|
||||
|
||||
if (len == 0) {
|
||||
/* cbuffer->read_ptr += copy_len; */
|
||||
} else {
|
||||
memcpy((u8 *)buf + copy_len, cbuffer->begin, len);
|
||||
//printf_data(cbuffer->begin,len);
|
||||
/* cbuffer->read_ptr = cbuffer->begin + len; */
|
||||
}
|
||||
|
||||
return r_len;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,606 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS_APP
|
||||
#pragma bss_seg(".lbuf.data.bss")
|
||||
#pragma data_seg(".lbuf.data")
|
||||
#pragma const_seg(".lbuf.text.const")
|
||||
#pragma code_seg(".lbuf.text")
|
||||
#endif
|
||||
/* ******************************************
|
||||
*
|
||||
* |offset| hentry | priv | data|
|
||||
* | ret |
|
||||
* | |
|
||||
* |---------align--------|
|
||||
*
|
||||
* *****************************************/
|
||||
|
||||
#include "lbuf.h"
|
||||
#include "common.h"
|
||||
|
||||
#define LOG_TAG_CONST LBUF
|
||||
#define LOG_TAG "[LBUF]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
/* #define LOG_DUMP_ENABLE */
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#ifdef ALIGN
|
||||
#undef ALIGN
|
||||
#endif
|
||||
|
||||
#define ALIGN(a, b) \
|
||||
({ \
|
||||
int m = (u32)(a) & ((b)-1); \
|
||||
int ret = (u32)(a) + (m?((b)-m):0); \
|
||||
ret;\
|
||||
})
|
||||
|
||||
//计算数据包的最小长度和hentry管理结构体放一起后要对齐的偏移,lbuf管理结构体的默认对齐是4,但数据包的对齐可以任意指定所以需要进行对齐偏移计算
|
||||
#define LBUF_OFFSET(head) \
|
||||
({ \
|
||||
int m = (sizeof(struct hentry)+head->priv_len) & (head->align-1); \
|
||||
m?(head->align-m):0;\
|
||||
})
|
||||
|
||||
|
||||
//根据hentry结构体大小得到hentry结构体地址
|
||||
#define __get_entry(lbuf) \
|
||||
(struct hentry *)((u8 *)lbuf - sizeof(struct hentry))
|
||||
|
||||
#if LBUF_DEBUG
|
||||
|
||||
#define lbuf_entry_check0(head, entry,rets) \
|
||||
do { \
|
||||
ASSERT(entry->magic_a == 0x12345678 && entry->magic_b == 0x23456789, \
|
||||
"%d,%x,%x,%x\n", __LINE__, entry->magic_a, entry->magic_b,rets); \
|
||||
ASSERT(head->magic_a == 0x87654321 && head->magic_b == 0x98765432, \
|
||||
"%d,%p,%x,%x,%x,%x\n", __LINE__, head, head->total_size, head->magic_a, head->magic_b,rets); \
|
||||
} while(0)
|
||||
|
||||
#define lbuf_entry_check(head, entry) \
|
||||
do { \
|
||||
ASSERT(entry->magic_a == 0x12345678 && entry->magic_b == 0x23456789, \
|
||||
"%d,%x,%x\n", __LINE__, entry->magic_a, entry->magic_b); \
|
||||
ASSERT(head->magic_a == 0x87654321 && head->magic_b == 0x98765432, \
|
||||
"%d,%p,%x,%x,%x\n", __LINE__, head, head->total_size, head->magic_a, head->magic_b); \
|
||||
} while(0)
|
||||
|
||||
#else
|
||||
|
||||
#define lbuf_entry_check0(head, entry,rets) do { } while (0)
|
||||
#define lbuf_entry_check(head, entry) do { } while (0)
|
||||
|
||||
#endif
|
||||
|
||||
struct hfree {
|
||||
struct list_head entry;
|
||||
u32 len;
|
||||
};
|
||||
|
||||
struct hentry {
|
||||
#if LBUF_DEBUG
|
||||
int magic_a;
|
||||
#endif
|
||||
struct list_head entry;
|
||||
#ifdef LBUFF_MALLOC_LARGE_MEM
|
||||
u32 len;
|
||||
///hentry结构体与lbuf_head结构体的头地址的偏移
|
||||
u32 offset;
|
||||
#else
|
||||
u16 len;
|
||||
///hentry结构体与lbuf_head结构体的头地址的偏移
|
||||
u16 offset;
|
||||
#endif
|
||||
///需要被读的次数
|
||||
u8 ref;
|
||||
///需要映射的通道
|
||||
u8 channel_map;
|
||||
#if LBUF_DEBUG
|
||||
int magic_b;
|
||||
#endif
|
||||
int rets;
|
||||
};
|
||||
|
||||
|
||||
struct lbuff_head *lbuf_init(void *buf, u32 len, int align, int priv_head_len)
|
||||
{
|
||||
struct hfree *free;
|
||||
//首地址4对齐
|
||||
struct lbuff_head *head = (struct lbuff_head *)ALIGN(buf, 4);
|
||||
//用户使用的地址按照用户的需求进行对齐
|
||||
free = (struct hfree *)ALIGN(head + 1, align);
|
||||
free->len = len - ((u8 *)free - (u8 *)buf);
|
||||
|
||||
head->align = align;
|
||||
head->priv_len = priv_head_len;
|
||||
head->last_addr = 0;
|
||||
#if LBUF_DEBUG
|
||||
head->magic_a = 0x87654321;
|
||||
head->magic_b = 0x98765432;
|
||||
#endif
|
||||
head->total_size = len;
|
||||
|
||||
spin_lock_init(&head->lock);
|
||||
INIT_LIST_HEAD(&head->head);
|
||||
INIT_LIST_HEAD(&head->free);
|
||||
|
||||
list_add_tail(&free->entry, &head->free);
|
||||
|
||||
//log_info("0000000000000000lbuf_init: %p,%x\n", head, (u32)head + len);
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
int lbuf_avaliable(struct lbuff_head *head, int size)
|
||||
{
|
||||
struct hfree *p;
|
||||
int avaliable = 0;
|
||||
|
||||
spin_lock(&head->lock);
|
||||
|
||||
int offset = LBUF_OFFSET(head);
|
||||
size = ALIGN(sizeof(struct hentry) + head->priv_len + offset + size, head->align);
|
||||
|
||||
list_for_each_entry(p, &head->free, entry) {
|
||||
avaliable += p->len / size;
|
||||
}
|
||||
|
||||
spin_unlock(&head->lock);
|
||||
|
||||
return avaliable;
|
||||
}
|
||||
|
||||
void lbuf_state(struct lbuff_head *head, struct lbuff_state *state)
|
||||
{
|
||||
struct hfree *p, *max = NULL;
|
||||
|
||||
state->num = 0;
|
||||
state->fragment = 0;
|
||||
state->avaliable = 0 ;
|
||||
|
||||
spin_lock(&head->lock);
|
||||
|
||||
list_for_each_entry(p, &head->free, entry) {
|
||||
state->fragment ++;
|
||||
state->avaliable += p->len;
|
||||
state->num++;
|
||||
// log_info("lbuf_state: %x, %x\n", p, p->len);
|
||||
if (!max || max->len < p->len) {
|
||||
max = p;
|
||||
}
|
||||
}
|
||||
|
||||
if (!max) {
|
||||
state->max_continue_len = 0;
|
||||
} else {
|
||||
int offset = LBUF_OFFSET(head);
|
||||
state->max_continue_len = max->len -
|
||||
sizeof(struct hentry) - head->priv_len - offset;
|
||||
}
|
||||
spin_unlock(&head->lock);
|
||||
}
|
||||
|
||||
|
||||
void lbuf_dump(struct lbuff_head *head)
|
||||
{
|
||||
int total_size = 0;
|
||||
struct hfree *p, *n;
|
||||
struct hentry *h;
|
||||
|
||||
spin_lock(&head->lock);
|
||||
|
||||
list_for_each_entry_safe(p, n, &head->free, entry) {
|
||||
/* log_info("fragment: %x, %x\n", (u32)p, p->len); */
|
||||
total_size += p->len;
|
||||
}
|
||||
|
||||
list_for_each_entry(h, &head->head, entry) {
|
||||
/* log_info("alloc: %x, %x, call_from: %x\n", h, h->len, h->rets); */
|
||||
}
|
||||
|
||||
log_info("lbuf_state:%x,%x\n", head->total_size, total_size);
|
||||
|
||||
spin_unlock(&head->lock);
|
||||
}
|
||||
|
||||
u32 lbuf_free_space(struct lbuff_head *head)
|
||||
{
|
||||
int max_len = 0;
|
||||
struct hfree *p;
|
||||
|
||||
spin_lock(&head->lock);
|
||||
|
||||
///找到最大的内存块
|
||||
list_for_each_entry(p, &head->free, entry) {
|
||||
if (max_len < p->len) {
|
||||
max_len = p->len;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&head->lock);
|
||||
|
||||
int len = sizeof(struct hentry) + LBUF_OFFSET(head) + head->priv_len;
|
||||
if (max_len >= len) {
|
||||
max_len -= len;
|
||||
max_len &= ~(head->align - 1);
|
||||
return max_len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *lbuf_alloc(struct lbuff_head *head, u32 len)
|
||||
{
|
||||
int offset;
|
||||
int max_len = 0;
|
||||
void *ret = NULL;
|
||||
struct hfree *p;
|
||||
struct hfree *new;
|
||||
struct hfree *free = NULL, *free_0 = NULL;
|
||||
struct hentry *entry;
|
||||
u32 rets_addr;
|
||||
__asm__ volatile("%0 = rets ;" : "=r"(rets_addr));
|
||||
/* printf("lbuf_alloc:0x%x %d\n", rets_addr, len); */
|
||||
|
||||
//计算数据包的最小长度和hentry管理结构体放一起后要对齐的偏移
|
||||
offset = LBUF_OFFSET(head);
|
||||
//申请的内存需要对齐的长度
|
||||
len = ALIGN(sizeof(*entry) + head->priv_len + offset + len, head->align);
|
||||
|
||||
spin_lock(&head->lock);
|
||||
|
||||
list_for_each_entry(p, &head->free, entry) {
|
||||
//长度越界检查
|
||||
if ((u8 *)p <= (u8 *)head || (u8 *)p > (u8 *)head + head->total_size) {
|
||||
asm("trigger");
|
||||
log_info("alloc-er1: %x, %x, %x\n", (u32)head->free.next, (u32)p, p->len);
|
||||
}
|
||||
//在hfree管理块中寻找一块足够长度的内存块
|
||||
if (p->len < len) {
|
||||
continue;
|
||||
}
|
||||
//找到了
|
||||
if (!free || free->len > p->len) {
|
||||
free = p;
|
||||
}
|
||||
//尽量找一块是在上一次内存分割后面的内存块,避免内存碎片
|
||||
if ((u32)p > head->last_addr && !free_0) {
|
||||
free_0 = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p = free_0 ? free_0 : free;
|
||||
|
||||
if (p) {
|
||||
head->last_addr = (u32)p;
|
||||
|
||||
//剩余的长度可以进行hfree结构体管理的内存分配
|
||||
if (p->len > len + sizeof(struct hfree)) {
|
||||
new = (struct hfree *)((u8 *)p + len);
|
||||
new->len = p->len - len;
|
||||
//hfree管理的内存进行分割
|
||||
__list_add(&new->entry, p->entry.prev, p->entry.next);
|
||||
} else {
|
||||
len = p->len;
|
||||
__list_del_entry(&p->entry);
|
||||
}
|
||||
|
||||
//进行hentry结构体管理的内存分配
|
||||
entry = (struct hentry *)((u8 *)p + offset);
|
||||
entry->len = len;
|
||||
entry->offset = (u8 *)entry - (u8 *)head;
|
||||
entry->channel_map = 0;
|
||||
entry->ref = 1;
|
||||
#if LBUF_DEBUG
|
||||
entry->magic_a = 0x12345678;
|
||||
entry->magic_b = 0x23456789;
|
||||
#endif
|
||||
INIT_LIST_HEAD(&entry->entry);
|
||||
|
||||
//返回hentry结构体后面的地址进行存储数据包
|
||||
ret = entry + 1;
|
||||
}
|
||||
|
||||
spin_unlock(&head->lock);
|
||||
|
||||
if (ret == NULL) {
|
||||
/*log_info("alloc-err: %x\n", len);*/
|
||||
/*putchar('#');*/
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lbuf_remain_space(struct lbuff_head *head)
|
||||
{
|
||||
int max_len = 0;
|
||||
struct hfree *p;
|
||||
|
||||
spin_lock(&head->lock);
|
||||
|
||||
list_for_each_entry(p, &head->free, entry) {
|
||||
max_len += p->len;
|
||||
}
|
||||
|
||||
spin_unlock(&head->lock);
|
||||
|
||||
return max_len;
|
||||
}
|
||||
|
||||
void *lbuf_realloc(void *lbuf, int size)
|
||||
{
|
||||
int len;
|
||||
int offset;
|
||||
int head_len;
|
||||
struct hentry *new;
|
||||
struct hentry *entry = __get_entry(lbuf);
|
||||
struct lbuff_head *head = (struct lbuff_head *)((u8 *)entry - entry->offset);
|
||||
|
||||
lbuf_entry_check(head, entry);
|
||||
// log_info("realloc: %x, %x\n", entry->len, size);
|
||||
|
||||
///把size变成align的倍数
|
||||
size = ALIGN(size, head->align);
|
||||
|
||||
ASSERT(size <= entry->len);
|
||||
///不能大于原来的len
|
||||
if (size >= entry->len) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
offset = LBUF_OFFSET(head);
|
||||
|
||||
|
||||
///计算一个数据包的头结构的偏移长度
|
||||
head_len = offset + sizeof(*entry) + head->priv_len;
|
||||
|
||||
///是否能放下两个最小的数据头
|
||||
if (entry->len - size < 2 * head_len) {
|
||||
return lbuf;
|
||||
}
|
||||
///是否能够放下hfree结构体
|
||||
if (entry->len - size < sizeof(struct hfree)) {
|
||||
return lbuf;
|
||||
}
|
||||
|
||||
len = entry->len;
|
||||
///实际的长度为数据头长度+分配的长度
|
||||
entry->len = head_len + size;
|
||||
|
||||
new = (struct hentry *)((u8 *)lbuf + head->priv_len + size + offset);
|
||||
new->channel_map = 0;
|
||||
new->ref = 1;
|
||||
new->len = len - entry->len;
|
||||
new->offset = (u8 *)new - (u8 *)head;
|
||||
#if LBUF_DEBUG
|
||||
new->magic_a = 0x12345678;
|
||||
new->magic_b = 0x23456789;
|
||||
#endif
|
||||
//初始化hentry的内核链表结构体
|
||||
INIT_LIST_HEAD(&new->entry);
|
||||
|
||||
///释放new指向的内存空间,即释放重新分配size大小空间后的剩余的空间
|
||||
lbuf_free(new + 1);
|
||||
|
||||
return lbuf;
|
||||
}
|
||||
|
||||
|
||||
int lbuf_empty(struct lbuff_head *head)
|
||||
{
|
||||
if (list_empty(&head->head)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void lbuf_clear(struct lbuff_head *head)
|
||||
{
|
||||
struct hentry *p, *n;
|
||||
|
||||
spin_lock(&head->lock);
|
||||
|
||||
list_for_each_entry_safe(p, n, &head->head, entry) {
|
||||
lbuf_free(p + 1);
|
||||
}
|
||||
|
||||
spin_unlock(&head->lock);
|
||||
}
|
||||
|
||||
int lbuf_real_size(void *lbuf)
|
||||
{
|
||||
struct hentry *entry = __get_entry(lbuf);
|
||||
|
||||
return entry->len;
|
||||
}
|
||||
|
||||
void lbuf_inc_ref(void *lbuf)
|
||||
{
|
||||
struct hentry *entry = __get_entry(lbuf);
|
||||
|
||||
entry->ref++;
|
||||
}
|
||||
|
||||
void lbuf_push(void *lbuf, u8 channel_map)
|
||||
{
|
||||
int i;
|
||||
//根据hentry结构体大小得到hentry结构体地址
|
||||
struct hentry *p = __get_entry(lbuf);
|
||||
//根据offset得到head结构体地址
|
||||
struct lbuff_head *head = (struct lbuff_head *)((u8 *)p - p->offset);
|
||||
|
||||
lbuf_entry_check(head, p);
|
||||
ASSERT(channel_map != 0);
|
||||
|
||||
spin_lock(&head->lock);
|
||||
|
||||
///检测需要被读的次数
|
||||
p->ref = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (channel_map & BIT(i)) {
|
||||
p->ref++;
|
||||
}
|
||||
}
|
||||
p->channel_map = channel_map;
|
||||
///检测hentry管理结构体的内存是否被破坏
|
||||
if (list_empty(&p->entry)) {
|
||||
lbuf_entry_check(head, p);
|
||||
|
||||
ASSERT(((u32)p->entry.next & 0x03) == 0, "%p,%p", head, p->entry.next);
|
||||
ASSERT(((u32)p->entry.prev & 0x03) == 0, "%p,%p", head, p->entry.prev);
|
||||
ASSERT(((u32)head->head.prev & 0x03) == 0, "%p,%x,%p", head, head->total_size, head->head.prev);
|
||||
ASSERT(((u32)head->head.next & 0x03) == 0, "%p,%x,%p", head, head->total_size, head->head.next);
|
||||
///把hentry链表添加到lbuf_head结构体
|
||||
list_add_tail(&p->entry, &head->head);
|
||||
}
|
||||
lbuf_entry_check(head, p);
|
||||
|
||||
spin_unlock(&head->lock);
|
||||
}
|
||||
|
||||
int lbuf_traversal(struct lbuff_head *head)
|
||||
{
|
||||
struct hentry *p;
|
||||
int num = 0;
|
||||
|
||||
spin_lock(&head->lock);
|
||||
list_for_each_entry(p, &head->head, entry) {
|
||||
num++;
|
||||
}
|
||||
spin_unlock(&head->lock);
|
||||
return num;
|
||||
}
|
||||
|
||||
void *lbuf_pop(struct lbuff_head *head, u8 channel)
|
||||
{
|
||||
struct hentry *p;
|
||||
|
||||
spin_lock(&head->lock);
|
||||
|
||||
//从头进行查找符合通道映射值的hentry内存块
|
||||
list_for_each_entry(p, &head->head, entry) {
|
||||
if (p->channel_map & channel) {
|
||||
//对应的通道映射值置0
|
||||
p->channel_map &= ~channel;
|
||||
spin_unlock(&head->lock);
|
||||
lbuf_entry_check(head, p);
|
||||
return p + 1;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&head->lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void lbuf_free_check(void *lbuf, u32 rets)
|
||||
{
|
||||
struct hentry *entry;
|
||||
struct lbuff_head *head;
|
||||
|
||||
if (lbuf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
entry = __get_entry(lbuf);
|
||||
head = (struct lbuff_head *)((u8 *)entry - entry->offset);
|
||||
|
||||
lbuf_entry_check0(head, entry, rets);
|
||||
}
|
||||
|
||||
|
||||
int lbuf_free(void *lbuf)
|
||||
{
|
||||
int ret = 0;
|
||||
int offset;
|
||||
struct hfree *p;
|
||||
struct hfree *new;
|
||||
struct hfree *prev = NULL;
|
||||
struct hfree *next;
|
||||
struct hentry *entry;
|
||||
struct lbuff_head *head;
|
||||
u32 rets_addr;
|
||||
__asm__ volatile("%0 = rets ;" : "=r"(rets_addr));
|
||||
|
||||
if (lbuf == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
///得到hentry
|
||||
entry = __get_entry(lbuf);
|
||||
///得到lbuf_head
|
||||
head = (struct lbuff_head *)((u8 *)entry - entry->offset);
|
||||
|
||||
lbuf_entry_check0(head, entry, rets_addr);
|
||||
|
||||
offset = LBUF_OFFSET(head);
|
||||
///得到hfree入口地址并初始化
|
||||
new = (struct hfree *)((u8 *)entry - offset);
|
||||
int len = entry->len;
|
||||
|
||||
spin_lock(&head->lock);
|
||||
|
||||
///异常!该数据包的通道映射还没有被读完,ref--后返回
|
||||
if (--entry->ref > 0) {
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
#if LBUF_DEBUG
|
||||
entry->magic_a = 0x01234567;
|
||||
#endif
|
||||
|
||||
///删除lbuf_head的hentry
|
||||
__list_del_entry(&entry->entry);
|
||||
new->len = len;
|
||||
|
||||
///hfree轮询
|
||||
list_for_each_entry(p, &head->free, entry) {
|
||||
///地址越界检查
|
||||
if ((u8 *)p <= (u8 *)head || (u8 *)p > (u8 *)head + head->total_size) {
|
||||
asm("trigger");
|
||||
log_info("free-err1: %x, %x, %x, %x, %x, %x %x\n", rets_addr, (u32)lbuf, new->len, head, head->free.next, (u32)p, p->len, rets_addr);
|
||||
goto _exit;
|
||||
}
|
||||
if ((p <= new) && ((u8 *)p + p->len > (u8 *)new)) {
|
||||
asm("trigger");
|
||||
log_info("free-err: %x, %x, %x, %x %x\n", (u32)lbuf, new->len, (u32)p, p->len, rets_addr);
|
||||
goto _exit;
|
||||
}
|
||||
//按地址高低进行排序,把释放的内存块放入hfree链表
|
||||
if (p > new) {
|
||||
__list_add(&new->entry, p->entry.prev, &p->entry);
|
||||
goto __free;
|
||||
}
|
||||
}
|
||||
///加入hfree链表尾部
|
||||
list_add_tail(&new->entry, &head->free);
|
||||
|
||||
__free:
|
||||
///得到hfree结构体
|
||||
prev = list_entry(new->entry.prev, struct hfree, entry);
|
||||
next = list_entry(new->entry.next, struct hfree, entry);
|
||||
///两块紧挨的内存块进行合并
|
||||
if ((u32)prev + prev->len == (u32)new) {
|
||||
prev->len += new->len;
|
||||
__list_del_entry(&new->entry);
|
||||
new = prev;
|
||||
}
|
||||
if ((u32)new + new->len == (u32)next) {
|
||||
new->len += next->len;
|
||||
__list_del_entry(&next->entry);
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
_exit:
|
||||
spin_unlock(&head->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS_APP
|
||||
#pragma bss_seg(".msg.data.bss")
|
||||
#pragma data_seg(".msg.data")
|
||||
#pragma const_seg(".msg.text.const")
|
||||
#pragma code_seg(".msg.text")
|
||||
#endif
|
||||
#include "msg.h"
|
||||
#include "circular_buf.h"
|
||||
#include "common.h"
|
||||
#include "printf.h"
|
||||
#include "os/os_cpu.h"
|
||||
#include "wdt.h"
|
||||
|
||||
static cbuffer_t msg_cbuf;
|
||||
static u32 msg_pool[MAX_POOL];
|
||||
|
||||
void sys_nop_delay(void)
|
||||
{
|
||||
//__builtin_pi32v2_nop();
|
||||
__asm__ volatile("nop");
|
||||
}
|
||||
|
||||
int task_get_msg(u16 timeout, int len, int *msg)
|
||||
{
|
||||
int msg_value = 0;
|
||||
u8 param_len = 0;
|
||||
int i = 0;
|
||||
int param;
|
||||
u32 event, event_to_msg;
|
||||
//debug
|
||||
for (i = 0; i < len; i++) {
|
||||
msg[i] = 0xffff;
|
||||
}
|
||||
|
||||
//get_msg
|
||||
wdt_clear();
|
||||
CPU_SR_ALLOC();
|
||||
OS_ENTER_CRITICAL();
|
||||
#if USE_EVENT_EN
|
||||
event = get_event();
|
||||
if (event != NO_EVENT) {
|
||||
clear_one_event(event);
|
||||
event_to_msg = evnet2msg[event];
|
||||
msg[0] = event_to_msg;
|
||||
//printf("event_mag %d\n ", event_to_msg);
|
||||
OS_EXIT_CRITICAL();
|
||||
return MSG_NO_ERROR;
|
||||
}
|
||||
#endif
|
||||
if (2 != cbuf_read(&msg_cbuf, (void *)&msg_value, 2)) {
|
||||
/* memset(msg, NO_MSG, len); */
|
||||
OS_EXIT_CRITICAL();
|
||||
|
||||
/*get no msg,cpu enter idle*/
|
||||
sys_nop_delay();
|
||||
|
||||
return MSG_NO_ERROR;
|
||||
}
|
||||
//msg[0] = msg_value;
|
||||
//param_len = msg_value >> 12;
|
||||
param_len = msg_value;
|
||||
for (i = 0 ; i < param_len; i++) {
|
||||
cbuf_read(&msg_cbuf, (void *)¶m, 4);
|
||||
if (i < len) {
|
||||
msg[i] = param;
|
||||
}
|
||||
}
|
||||
if (i >= len) {
|
||||
puts("msg_buf_not_enc\n");
|
||||
OS_EXIT_CRITICAL();
|
||||
return MSG_BUF_NOT_ENOUGH;
|
||||
}
|
||||
OS_EXIT_CRITICAL();
|
||||
return MSG_NO_ERROR;
|
||||
}
|
||||
|
||||
#if USB_HID_MODULE_CONTROL
|
||||
extern void rcsp_hid_loop_resume(void);
|
||||
#else
|
||||
extern void stack_run_loop_resume();
|
||||
#endif
|
||||
int task_post_msg_base(const char *name, int argc, int cmd, int *argv)
|
||||
{
|
||||
u16 msg_value = 0x0fff;
|
||||
int i = 0;
|
||||
int param_len = 0;
|
||||
int param = 0;
|
||||
|
||||
if (0xff == cmd) {
|
||||
printf("cmd == 0xff\n");
|
||||
#if USB_HID_MODULE_CONTROL
|
||||
rcsp_hid_loop_resume();
|
||||
#else
|
||||
stack_run_loop_resume();
|
||||
#endif
|
||||
return MSG_NO_ERROR;
|
||||
}
|
||||
|
||||
CPU_SR_ALLOC();
|
||||
OS_ENTER_CRITICAL();
|
||||
//va_list argptr;
|
||||
//va_start(argptr, argc);
|
||||
/* printf("msg:cnt:%x\n", argc); */
|
||||
for (i = 0; i < argc + 1; ++i) {
|
||||
if (i == 0) {
|
||||
param_len = argc;
|
||||
msg_value = param_len & 0xffff;
|
||||
/* printf("msg[0]:%x\n",msg_value); */
|
||||
if (cbuf_write(&msg_cbuf, (void *)&msg_value, 2) != 2) {
|
||||
ASSERT(0, "stack message full! %d\n", __LINE__);
|
||||
}
|
||||
|
||||
} else {
|
||||
//param = va_arg(argptr, int);
|
||||
if (i == 1) {
|
||||
param = cmd;
|
||||
} else {
|
||||
param = argv[i - 2];
|
||||
}
|
||||
/* printf("msg[%d]:%x\n", i, param); */
|
||||
if (cbuf_write(&msg_cbuf, (void *)¶m, 4) != 4) {
|
||||
ASSERT(0, "stack message full! %d\n", __LINE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
//va_end(argptr);
|
||||
OS_EXIT_CRITICAL();
|
||||
#if USB_HID_MODULE_CONTROL
|
||||
rcsp_hid_loop_resume();
|
||||
#else
|
||||
stack_run_loop_resume();
|
||||
#endif
|
||||
return MSG_NO_ERROR;
|
||||
}
|
||||
int task_post_msg(char *name, int argc, ...)
|
||||
{
|
||||
int argv[8];
|
||||
va_list argptr;
|
||||
|
||||
ASSERT(argc <= 8);
|
||||
|
||||
va_start(argptr, argc);
|
||||
|
||||
u8 i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
argv[i] = va_arg(argptr, int);
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
|
||||
//puts("msg_push:\n");
|
||||
//put_buf((u8 *)argv,argc*4);
|
||||
return task_post_msg_base(name, argc, argv[0], &argv[1]);
|
||||
}
|
||||
void task_clear_all_message(void)
|
||||
{
|
||||
cbuf_clear(&msg_cbuf);
|
||||
}
|
||||
|
||||
void task_message_init(void)
|
||||
{
|
||||
cbuf_init(&msg_cbuf, msg_pool, sizeof(msg_pool));
|
||||
cbuf_clear(&msg_cbuf);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,475 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS_APP
|
||||
#pragma bss_seg(".sys_timer.data.bss")
|
||||
#pragma data_seg(".sys_timer.data")
|
||||
#pragma const_seg(".sys_timer.text.const")
|
||||
#pragma code_seg(".sys_timer.text")
|
||||
#endif
|
||||
#include "sys_timer.h"
|
||||
#include "timer.h"
|
||||
#include "jiffies.h"
|
||||
#include "spinlock.h"
|
||||
//#include "cpu.h"
|
||||
|
||||
#define TIMER_US_ENABLE 0
|
||||
|
||||
void (*sys_timer_delay_handler)();
|
||||
struct list_head timer_head;
|
||||
struct list_head timer_us_head;
|
||||
/* volatile unsigned long jiffies; */
|
||||
volatile unsigned long jiffies_us;
|
||||
|
||||
|
||||
void *get_sys_timer_head()
|
||||
{
|
||||
return &timer_head;
|
||||
}
|
||||
|
||||
u32 get_jiffies(u8 mode, u32 timer_ms)
|
||||
{
|
||||
if (mode == 1) {
|
||||
jiffies += timer_ms / 10;
|
||||
|
||||
}
|
||||
return jiffies;
|
||||
}
|
||||
|
||||
bool __timer_find(struct sys_timer *timer)
|
||||
{
|
||||
struct sys_timer *p;
|
||||
|
||||
list_for_each_entry(p, &timer_head, entry) {
|
||||
if (p == timer) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if TIMER_US_ENABLE
|
||||
bool __timer_us_find(struct sys_timer *timer)
|
||||
{
|
||||
struct sys_timer *p;
|
||||
|
||||
list_for_each_entry(p, &timer_us_head, entry) {
|
||||
if (p == timer) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
void __timer_insert(struct sys_timer *timer)
|
||||
{
|
||||
struct sys_timer *p;
|
||||
list_for_each_entry(p, &timer_head, entry) {
|
||||
if (p == timer) {
|
||||
list_del(&p->entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(p, &timer_head, entry) {
|
||||
if (p->jiffies > timer->jiffies) {
|
||||
__list_add(&timer->entry, p->entry.prev, &p->entry);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
list_add_tail((struct list_head *)&timer->entry, (struct list_head *)&timer_head);
|
||||
}
|
||||
|
||||
#if TIMER_US_ENABLE
|
||||
void __timer_us_insert(struct sys_timer *timer)
|
||||
{
|
||||
struct sys_timer *p;
|
||||
list_for_each_entry(p, &timer_us_head, entry) {
|
||||
if (p == timer) {
|
||||
list_del(&p->entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(p, &timer_us_head, entry) {
|
||||
if (p->jiffies > timer->jiffies) {
|
||||
__list_add(&timer->entry, p->entry.prev, &p->entry);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
list_add_tail((struct list_head *)&timer->entry, (struct list_head *)&timer_us_head);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TIMER_US_ENABLE
|
||||
void sys_timer_us_register(struct sys_timer *timer, u32 us_sec,
|
||||
void (*fun)(struct sys_timer *timer), u8 delay_do)
|
||||
{
|
||||
local_irq_disable();
|
||||
|
||||
timer->loop = 0;
|
||||
timer->delay_do = delay_do;
|
||||
timer->fun = fun;
|
||||
timer->jiffies = jiffies_us + msecs_to_jiffies_10(us_sec);
|
||||
//printf("timer->jiffies=%d,%d\n", jiffies_us, timer->jiffies);
|
||||
__timer_us_insert(timer);
|
||||
|
||||
local_irq_enable();
|
||||
}
|
||||
#endif
|
||||
|
||||
void sys_hi_timer_schedule()
|
||||
{
|
||||
struct sys_timer *p, *n;
|
||||
|
||||
local_irq_disable();
|
||||
|
||||
/* jiffies++; */
|
||||
list_for_each_entry_safe(p, n, &timer_head, entry) {
|
||||
if (time_before(jiffies, p->jiffies)) {
|
||||
break;
|
||||
}
|
||||
//putchar('s');
|
||||
if (sys_timer_delay_handler) {
|
||||
sys_timer_delay_handler();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
#if TIMER_US_ENABLE
|
||||
static void sys_timer_us_schedule()
|
||||
{
|
||||
struct sys_timer *p, *n;
|
||||
u8 do_fun_flag = 0;
|
||||
|
||||
local_irq_disable();
|
||||
|
||||
jiffies_us++;
|
||||
list_for_each_entry_safe(p, n, &timer_us_head, entry) {
|
||||
if (time_before(jiffies_us, p->jiffies)) {
|
||||
break;
|
||||
}
|
||||
if (sys_timer_delay_handler) {
|
||||
sys_timer_delay_handler();
|
||||
}
|
||||
}
|
||||
local_irq_enable();
|
||||
}
|
||||
void loop_timer_us_schedule()
|
||||
{
|
||||
struct sys_timer *p, *n;
|
||||
u8 do_fun_flag = 0;
|
||||
|
||||
local_irq_disable();
|
||||
|
||||
list_for_each_entry_safe(p, n, &timer_us_head, entry) {
|
||||
if (time_before(jiffies_us, p->jiffies)) {
|
||||
break;
|
||||
}
|
||||
sys_timer_us_remove(p);
|
||||
do_fun_flag = 0xaa;
|
||||
break;
|
||||
}
|
||||
|
||||
local_irq_enable();
|
||||
if (do_fun_flag == 0xaa) {
|
||||
ASSERT(p->fun != NULL);
|
||||
p->fun(p);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static DEFINE_SPINLOCK(lock);
|
||||
#if (defined(CONFIG_CPU_BD47) || defined(CONFIG_CPU_BR29)) && defined(BLE_APP_LOW_RAM_USED) // bd47 内存紧缺
|
||||
#define TIMER_POOL_NUM_CONFIG 5
|
||||
#else
|
||||
#define TIMER_POOL_NUM_CONFIG 10
|
||||
#endif
|
||||
static struct sys_timer timer_pool[TIMER_POOL_NUM_CONFIG] = {0};
|
||||
static u16 global_id = 0;
|
||||
|
||||
|
||||
static struct sys_timer *__sys_timer_get(void *priv, void (*func)(void *priv),
|
||||
u32 msec, int timeout)
|
||||
{
|
||||
struct sys_timer *t = NULL;
|
||||
|
||||
spin_lock(&lock);
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(timer_pool); i++) {
|
||||
if (timer_pool[i].used == 0) {
|
||||
timer_pool[i].used = 1;
|
||||
t = &timer_pool[i];
|
||||
spin_unlock(&lock);
|
||||
goto __next;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&lock);
|
||||
if (i == ARRAY_SIZE(timer_pool)) {
|
||||
/* puts("<<<tiemr pool full>>>\n"); */
|
||||
}
|
||||
|
||||
__next:
|
||||
t->priv = priv;
|
||||
t->func = func;
|
||||
t->msec = msec;
|
||||
t->del = 0;
|
||||
//t->posting = 0;
|
||||
t->timeout = timeout;
|
||||
t->jiffies = jiffies + msecs_to_jiffies(msec);
|
||||
|
||||
t->id = ++global_id;
|
||||
if (t->id == 0) {
|
||||
t->id = (u16)func;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static int __timer_put(struct sys_timer *timer)
|
||||
{
|
||||
if (timer >= timer_pool && timer < timer_pool + ARRAY_SIZE(timer_pool)) {
|
||||
timer->used = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __id_check(struct sys_timer *t, struct list_head *head)
|
||||
{
|
||||
struct sys_timer *p;
|
||||
|
||||
__again:
|
||||
list_for_each_entry(p, head, entry) {
|
||||
if (t->id == p->id) {
|
||||
t->id++;
|
||||
goto __again;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static u16 __sys_timer_add(void *priv, void (*func)(void *priv), u32 msec, int timeout)
|
||||
{
|
||||
struct sys_timer *t;
|
||||
|
||||
t = __sys_timer_get(priv, func, msec, timeout);
|
||||
if (!t) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
spin_lock(&lock);
|
||||
|
||||
__id_check(t, &timer_head);
|
||||
|
||||
struct sys_timer *p;
|
||||
list_for_each_entry(p, &timer_head, entry) {
|
||||
//printf("p->jiffies:%x t->jiffies:%x\n",p-jiffies,t->jiffies);
|
||||
if (p->jiffies > t->jiffies) {
|
||||
__list_add(&t->entry, p->entry.prev, &p->entry);
|
||||
goto _LOOP_RET;
|
||||
}
|
||||
}
|
||||
|
||||
list_add_tail(&t->entry, &timer_head);
|
||||
_LOOP_RET:
|
||||
spin_unlock(&lock);
|
||||
|
||||
/* if(func == lmp_connection_timeout){ */
|
||||
/* mpu_set(0, (u32)t + sizeof(struct list_head), (u32)t + sizeof(struct list_head) + 4 - 1, 0, "Cxr"); */
|
||||
/* } */
|
||||
//log_debug("add id : %d", t->id);
|
||||
|
||||
//os_sem_post(&sys_timer_sem);
|
||||
|
||||
return t->id;
|
||||
}
|
||||
static void __timer_del(struct sys_timer *timer)
|
||||
{
|
||||
spin_lock(&lock);
|
||||
|
||||
__list_del_entry(&timer->entry);
|
||||
|
||||
int ret = __timer_put(timer);
|
||||
|
||||
spin_unlock(&lock);
|
||||
|
||||
/* if (!ret) {
|
||||
free(timer);
|
||||
} */
|
||||
}
|
||||
|
||||
static void __sys_timer_del(struct list_head *head, u16 id)
|
||||
{
|
||||
const char *task;
|
||||
struct sys_timer *p;
|
||||
|
||||
spin_lock(&lock);
|
||||
|
||||
list_for_each_entry(p, head, entry) {
|
||||
if (p->id == id) {
|
||||
__list_del_entry(&p->entry);
|
||||
__timer_put(p);
|
||||
//p->del = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&lock);
|
||||
}
|
||||
|
||||
u16 sys_timer_add(void *priv, void (*func)(void *priv), u32 msec)
|
||||
{
|
||||
int rets;
|
||||
__asm__ volatile("%0 = rets" :"=r"(rets));
|
||||
/* printf("add rts : 0x%x / %d", rets, msec); */
|
||||
return __sys_timer_add(priv, func, msec, 0);
|
||||
}
|
||||
|
||||
u16 sys_timeout_add(void *priv, void (*func)(void *priv), u32 msec)
|
||||
{
|
||||
int rets;
|
||||
__asm__ volatile("%0 = rets" :"=r"(rets));
|
||||
/* printf("add ot rts : 0x%x / %d", rets, msec); */
|
||||
return __sys_timer_add(priv, func, msec, 1);
|
||||
}
|
||||
|
||||
void sys_timer_del(u16 t)
|
||||
{
|
||||
__sys_timer_del(&timer_head, t);
|
||||
}
|
||||
|
||||
void sys_timeout_del(u16 t)
|
||||
{
|
||||
__sys_timer_del(&timer_head, t);
|
||||
}
|
||||
|
||||
int sys_timer_modify(u16 id, u32 msec)
|
||||
{
|
||||
struct sys_timer *p;
|
||||
|
||||
spin_lock(&lock);
|
||||
|
||||
list_for_each_entry(p, &timer_head, entry) {
|
||||
if (p->id == id) {
|
||||
p->msec = msec;
|
||||
p->jiffies = jiffies + msecs_to_jiffies(msec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&lock);
|
||||
|
||||
//os_sem_post(&sys_timer_sem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
void sys_timer_set_user_data(u16 id, void *priv)
|
||||
{
|
||||
struct sys_timer *p;
|
||||
|
||||
spin_lock(&lock);
|
||||
|
||||
list_for_each_entry(p, &timer_head, entry) {
|
||||
if (p->id == id) {
|
||||
p->priv = priv;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&lock);
|
||||
}
|
||||
|
||||
sys_timer sys_timer_register(u32 msec, void (*callback)(void *))
|
||||
{
|
||||
return sys_timeout_add(NULL, callback, msec);
|
||||
}
|
||||
|
||||
void sys_timer_change_period(sys_timer timer, u32 msec)
|
||||
{
|
||||
sys_timer_modify(timer, msec);
|
||||
}
|
||||
|
||||
void sys_timer_set_context(sys_timer timer, void *context)
|
||||
{
|
||||
sys_timer_set_user_data(timer, context);
|
||||
}
|
||||
|
||||
sys_timer sys_timer_register_periodic(u32 msec, void (*callback)(void *))
|
||||
{
|
||||
return sys_timer_add(NULL, callback, msec);
|
||||
}
|
||||
|
||||
void sys_timer_re_run(u16 id)
|
||||
{
|
||||
struct sys_timer *p;
|
||||
|
||||
spin_lock(&lock);
|
||||
|
||||
list_for_each_entry(p, &timer_head, entry) {
|
||||
if (p->id == id) {
|
||||
p->jiffies = jiffies + msecs_to_jiffies(p->msec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&lock);
|
||||
|
||||
//os_sem_post(&sys_timer_sem);
|
||||
}
|
||||
|
||||
void sys_timer_reset(sys_timer timer)
|
||||
{
|
||||
sys_timer_re_run(timer);
|
||||
}
|
||||
|
||||
void sys_timer_remove(sys_timer timer)
|
||||
{
|
||||
sys_timeout_del(timer);
|
||||
}
|
||||
|
||||
|
||||
void sys_timer_schedule()
|
||||
{
|
||||
struct sys_timer *p, *n;
|
||||
u8 do_fun_flag = 0;
|
||||
|
||||
#if TIMER_US_ENABLE
|
||||
loop_timer_us_schedule();
|
||||
#endif
|
||||
|
||||
/* jiffies++; */
|
||||
spin_lock(&lock);
|
||||
list_for_each_entry_safe(p, n, &timer_head, entry) {
|
||||
if (time_after(jiffies, p->jiffies)) {
|
||||
spin_unlock(&lock);
|
||||
if (p->func) {
|
||||
p->func(p->priv);
|
||||
}
|
||||
|
||||
spin_lock(&lock);
|
||||
if (p->timeout) {
|
||||
spin_unlock(&lock);
|
||||
__timer_del(p);
|
||||
spin_lock(&lock);
|
||||
} else {
|
||||
p->jiffies = jiffies + msecs_to_jiffies(p->msec);
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock(&lock);
|
||||
}
|
||||
|
||||
void sys_timer_init()
|
||||
{
|
||||
INIT_LIST_HEAD(&timer_head);
|
||||
#if TIMER_US_ENABLE
|
||||
INIT_LIST_HEAD(&timer_us_head);
|
||||
#endif
|
||||
|
||||
sys_tmr_init(sys_timer_schedule);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
#ifdef SUPPORT_MS_EXTENSIONS_APP
|
||||
#pragma bss_seg(".version.data.bss")
|
||||
#pragma data_seg(".version.data")
|
||||
#pragma const_seg(".version.text.const")
|
||||
#pragma code_seg(".version.text")
|
||||
#endif
|
||||
#include "lib_include.h"
|
||||
|
||||
__attribute__((section(".version_tag1"), used))
|
||||
#if defined(EDR_UPDATA_SUPPORT_CONNECT)
|
||||
static const char version_type_tag[] = "edr_ota2";
|
||||
#elif defined(BLE_UPDATA_SUPPORT_CONNECT)
|
||||
static const char version_type_tag[] = "ble_ota";
|
||||
#elif (1 == USB_HOST_MODULE_CONTROL)
|
||||
|
||||
//二级loader修改
|
||||
#if defined(CONFIG_CPU_BR25) || defined(CONFIG_CPU_BR27)
|
||||
static const char version_type_tag[] = "usb_update2/usb_sec_ota";
|
||||
#else
|
||||
static const char version_type_tag[] = "usb_update2";
|
||||
#endif
|
||||
|
||||
#elif (1 == SD_MODULE_CONTROL)
|
||||
//二级loader修改
|
||||
#if defined(CONFIG_CPU_BR25) || defined(CONFIG_CPU_BR27)
|
||||
static const char version_type_tag[] = "sd_update2/sd_sec_ota";
|
||||
#else
|
||||
static const char version_type_tag[] = "sd_update2";
|
||||
#endif
|
||||
|
||||
#elif (1 == BLE_GATT_UPDATA_MODULE_CONTROL)
|
||||
static const char version_type_tag[] = "ble_app_ota";
|
||||
#elif (1 == SPP_UPDATA_MODULE_CONTROL)
|
||||
static const char version_type_tag[] = "spp_app_ota";
|
||||
#elif (1 == UART_UPDATA_MODULE_CONTROL)
|
||||
static const char version_type_tag[] = "uart_update";
|
||||
#elif (1 == UART_UPDATA_USER_MODULE_CONTROL)
|
||||
static const char version_type_tag[] = "user_uart_update";
|
||||
#elif defined(EX_FLASH_UPDATE_SUPPORT_EN)
|
||||
static const char version_type_tag[] = "nor_ota";
|
||||
#elif (1 == USER_LC_FLASH_UPDATA_MODULE_CONTROL)
|
||||
static const char version_type_tag[] = "lcflash_ota";
|
||||
#elif (1 == USB_HID_MODULE_CONTROL)
|
||||
static const char version_type_tag[] = "usb_hid_ota";
|
||||
#elif (1 == DEV_NORFLASH_UPDATA_MODULE_CONTROL)
|
||||
static const char version_type_tag[] = "dev_nor_ota";
|
||||
#elif (1 == NET_UPDATA_MODULE_CONTROL)
|
||||
static const char version_type_tag[] = "net_ota";
|
||||
#elif (1 == USB_HID_MODULE_CONTROL)
|
||||
static const char version_type_tag[] = "usb_hid_ota";
|
||||
#endif
|
||||
|
||||
__attribute__((section(".version_tag2"), used))
|
||||
static const char version_date_tag[] = __DATE__;
|
||||
|
||||
__attribute__((section(".version_tag3"), used))
|
||||
static const char version_time_tag[] = __TIME__;
|
||||
|
||||
Reference in New Issue
Block a user