This commit is contained in:
huxi
2025-12-03 11:12:34 +08:00
parent c23ae4f24c
commit bc195654bf
8163 changed files with 3799544 additions and 92 deletions
+199
View File
@@ -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
+606
View File
@@ -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;
}
+165
View File
@@ -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 *)&param, 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 *)&param, 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__;