This commit is contained in:
lmx
2025-10-29 13:10:02 +08:00
commit 49a07fa419
2284 changed files with 642060 additions and 0 deletions

View File

@ -0,0 +1,44 @@
#ifndef ASCII_LIB_H
#define ASCII_LIB_H
#ifdef __cplusplus
extern "C" {
#endif
#include "typedef.h"
void ASCII_ToLower(void *buf, u32 len);
void ASCII_ToUpper(void *buf, u32 len);
u32 ASCII_StrCmp(const char *src, const char *dst, u32 len);
int ASCII_StrCmpNoCase(const char *src, const char *dst, int len);
void ASCII_IntToStr(void *pStr, u32 intNum, u32 strLen, u32 bufLen);
u32 ASCII_StrToInt(const void *pStr, u32 *pRint, u32 strLen);
u32 ASCII_StrLen(void *str, u32 len);
u32 ASCII_WStrLen(void *str, u32 len);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,81 @@
#ifndef ATOMIC_H
#define ATOMIC_H
#include "cpu.h"
#include "irq.h"
typedef struct {
int counter;
} atomic_t;
static inline int atomic_add_return(int i, atomic_t *v)
{
int val;
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
val = v->counter;
v->counter = val += i;
CPU_CRITICAL_EXIT();
return val;
}
static inline int atomic_sub_return(int i, atomic_t *v)
{
int val;
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
val = v->counter;
v->counter = val -= i;
CPU_CRITICAL_EXIT();
return val;
}
static inline int atomic_set(atomic_t *v, int i)
{
int val = 0;
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
v->counter = i;
CPU_CRITICAL_EXIT();
return val;
}
#define DEFINE_ATOMIC(x) \
atomic_t x = {.counter = 0}
#define atomic_add(i, v) atomic_add_return(i, v)
#define atomic_sub(i, v) atomic_sub_return(i, v)
#define atomic_read(v) arch_atomic_read(v)
/*#define atomic_set(v,i) (((v)->counter) = (i))*/
#define atomic_inc(v) atomic_add(1, v)
#define atomic_dec(v) atomic_sub(1, v)
#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
#define atomic_inc_return(v) (atomic_add_return(1, v))
#define atomic_dec_return(v) (atomic_sub_return(1, v))
#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0)
#endif

View File

@ -0,0 +1,302 @@
#ifndef CIRCULAR_BUF_INTERFACE_H
#define CIRCULAR_BUF_INTERFACE_H
#include "typedef.h"
#include "system/spinlock.h"
#ifndef CONFIG_CBUF_IN_MASKROM
/* --------------------------------------------------------------------------*/
/**
* @brief cbuffer结构体
*/
/* ----------------------------------------------------------------------------*/
typedef struct _cbuffer {
u8 *begin;
u8 *end;
u8 *read_ptr;
u8 *write_ptr;
u8 *tmp_ptr ;
u32 tmp_len;
u32 data_len;
u32 total_len;
spinlock_t lock;
} cbuffer_t;
#else /* #ifndef CONFIG_CBUF_IN_MASKROM */
/* ---------------------------------------------------------------------------- */
/**
* @brief cbuffer结构体
* @note: 以下结构体成员不可修改
*/
/* ---------------------------------------------------------------------------- */
typedef struct _cbuffer {
u8 *begin;
u8 *end;
u8 *read_ptr;
u8 *write_ptr;
u8 *tmp_ptr ;
u32 tmp_len;
u32 data_len;
u32 total_len;
spinlock_t lock;
} cbuffer_t;
#endif /* #ifndef CONFIG_CBUF_IN_MASKROM */
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:全局
* @brief cbuffer初始化
*
* @param [in] cbuffer cbuffer 句柄
* @param [in] buf 缓存空间
* @param [in] size 缓存总大小
*/
/* ----------------------------------------------------------------------------*/
void cbuf_init(cbuffer_t *cbuffer, void *buf, u32 size);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:cb_memcpy管理
* @brief 把cbuffer_t结构体管理的内存空间的数据拷贝到buf数组
* @param [in] cbuffer cbuffer 句柄
* @param [out] buf 指向用于存储读取内容的目标数组
* @param [in] len 要读取的字节长度
*
* @return 成功读取的字节长度
*/
/* ----------------------------------------------------------------------------*/
u32 cbuf_read(cbuffer_t *cbuffer, void *buf, u32 len);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:cb_memcpy管理
* @brief 把buf数组数据拷贝cbuffer_t结构体管理的内存空间
*
* @param [in] cbuffer cbuffer 句柄
* @param [in] buf 指向用于存储写入内容的目标数组
* @param [in] len 要写入的字节长度
*
* @return 成功写入的字节长度
*/
/* ----------------------------------------------------------------------------*/
u32 cbuf_write(cbuffer_t *cbuffer, void *buf, u32 len);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:全局
* @brief 判断是否可写入len字节长度的数据
*
* @param [in] cbuffer cbuffer 句柄
* @param [in] len len字节长度的数据
*
* @return 返回可以写入的len字节长度
*/
/* ----------------------------------------------------------------------------*/
u32 cbuf_is_write_able(cbuffer_t *cbuffer, u32 len);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:外部内存管理
* @brief 预分配待写入数据的空间要和cbuf_write_updata()配套使用,更新cbuf管理handle数据。
*
* @param [in] cbuffer cbuffer句柄
* @param [in] len 回传可以最多写入len字节长度的数据
*
* @return 当前写指针的地址
*/
/* ----------------------------------------------------------------------------*/
void *cbuf_write_alloc(cbuffer_t *cbuffer, u32 *len);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:外部内存管理
* @brief 更新cbuf管理handle的写指针位置和数据长度
*
* @param [in] cbuffer cbuffer句柄
* @param [in] len 在非cbuffer_t结构体包含的内存空间中写入的数据的实际字节长度
*
* @return 当前写指针的地址
*/
/* ----------------------------------------------------------------------------*/
void cbuf_write_updata(cbuffer_t *cbuffer, u32 len);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:外部内存管理
* @brief 预分配待读取数据的空间,需要和cbuf_read_updata()配套使用,更新cbuf管理handle数据
*
* @param [in] cbuffer cbuffer 句柄
* @param [in] len 回传可以最多读取len字节长度的数据
*
* @return 当前读指针的地址
*/
/* ----------------------------------------------------------------------------*/
void *cbuf_read_alloc(cbuffer_t *cbuffer, u32 *len);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:外部内存管理
* @brief 更新cbuf管理handle的读指针位置和数据长度
*
* @param [in] cbuffer cbuffer 句柄
* @param [in] len 在非cbuffer_t结构体包含的内存空间中读取的数据的实际字节长度
*/
/* ----------------------------------------------------------------------------*/
void cbuf_read_updata(cbuffer_t *cbuffer, u32 len);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:外部内存管理
* @brief 清空cbuffer空间
*
* @param [in] cbuffer cbuffer 句柄
*/
/* ----------------------------------------------------------------------------*/
void cbuf_clear(cbuffer_t *cbuffer);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:cb_memcpy管理。
* @brief 指定位置进行数据重写
*
* @param [in] cbuffer cbuffer 句柄
* @param [in] begin 指向需要重写内容的开始地址
* @param [out] buf 指向用于存储重写内容的目标数组
* @param [in] len 待重写内容的长度
*
* @return 成功重写的字节长度
*/
/* ----------------------------------------------------------------------------*/
u32 cbuf_rewrite(cbuffer_t *cbuffer, void *begin, void *buf, u32 len);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:cb_memcpy管理
* @brief 更新指向上一次操作的指针为当前指针,并刷新数据长度
*
* @param [in] cbuffer cbuffer 句柄
*/
/* ----------------------------------------------------------------------------*/
void cbuf_discard_prewrite(cbuffer_t *cbuffer);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:cb_memcpy管理
* @brief 操作指针回退到上一次的操作位置,并刷新数据长度
*
* @param [in] cbuffer cbuffer 句柄
*/
/* ----------------------------------------------------------------------------*/
void cbuf_updata_prewrite(cbuffer_t *cbuffer);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:cb_memcpy管理
* @brief 回退写入内容,从上一次的操作的指针处进行覆盖填充
*
* @param [in] cbuffer cbuffer 句柄
* @param [out] buf 指向用于覆盖写入内容的目标数组
* @param [in] len 填充数据的字节长度
*
* @return 成功填充数据的字节长度
*/
/* ----------------------------------------------------------------------------*/
u32 cbuf_prewrite(cbuffer_t *cbuffer, void *buf, u32 len);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:全局
* @brief 获取指向写指针的地址
*
* @param [in] cbuffer cbuffer 句柄
*
* @return 写指针的地址
*/
/* ----------------------------------------------------------------------------*/
void *cbuf_get_writeptr(cbuffer_t *cbuffer);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:全局
* @brief 获取cbuffer存储的数据的字节长度
*
* @param [in] cbuffer cbuffer句柄
*
* @return 获取cbuffer存储的数据的字节长度
*/
/* ----------------------------------------------------------------------------*/
u32 cbuf_get_data_size(cbuffer_t *cbuffer);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:全局
* @brief 获取指向读指针的地址
*
* @param [in] cbuffer cbuffer句柄
*
* @return 读指针的地址
*/
/* ----------------------------------------------------------------------------*/
void *cbuf_get_readptr(cbuffer_t *cbuffer);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:全局
* @brief 读指针向后回退
*
* @param [in] cbuffer cbuffer 句柄
* @param [in] len 要回退的字节长度
*
* @return 成功回退的字节长度
*/
/* ----------------------------------------------------------------------------*/
u32 cbuf_read_goback(cbuffer_t *cbuffer, u32 len);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:全局
* @brief 获取存储数据的字节长度
*
* @param [in] cbuffer cbuffer 句柄
*
* @return 存储数据的字节长度
*/
/* ----------------------------------------------------------------------------*/
u32 cbuf_get_data_len(cbuffer_t *cbuffer);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:memcpy管理+cbuf_read_alloc系列管理函数
* @brief 预分配待读取数据的空间,并把读取到的数据存入buf数组
*
* @param [in] cbuffer cbuffer 句柄
* @param [out] buf 存储读取的数据的目标buf数组
* @param [in] len 要读取的数据的字节长度
*
* @return
*/
/* ----------------------------------------------------------------------------*/
u32 cbuf_read_alloc_len(cbuffer_t *cbuffer, void *buf, u32 len);
/* --------------------------------------------------------------------------*/
/**
* @brief 适用范围:memcpy管理+cbuf_read_alloc系列管理函数
* @brief 更新cbuf管理handle的读指针位置和数据长度
*
* @param [in] cbuffer cbuffer 句柄
* @param [in] len 要更新的数据的字节长度
*/
/* ----------------------------------------------------------------------------*/
void cbuf_read_alloc_len_updata(cbuffer_t *cbuffer, u32 len);
#endif

View File

@ -0,0 +1,22 @@
#ifndef GENERIC_CPU_H
#define GENERIC_CPU_H
#include <asm/cpu.h>
#endif

View File

@ -0,0 +1,10 @@
#ifndef _LITE_DEBUG_H_
#define _LITE_DEBUG_H_
extern void puts_lite(const char *out);
extern void put_buf_lite(void *_buf, u32 len);
extern int printf_lite(const char *format, ...);
#endif /* #ifdef _LITE_DEBUG_H_ */

View File

@ -0,0 +1,40 @@
#ifndef _ASM_GENERIC_ERRNO_BASE_H
#define _ASM_GENERIC_ERRNO_BASE_H
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define ETIMEDOUT 35 /* Connection timed out */
#endif

View File

@ -0,0 +1,44 @@
#ifndef ASM_GPIO_H
#define ASM_GPIO_H
#include "asm/gpio.h"
#define GPIO2PORT(gpio) (gpio / IO_GROUP_NUM)
void gpio_port_lock(unsigned int port);
void gpio_port_unlock(unsigned int port);
int __gpio_direction_input(unsigned int gpio);
int gpio_direction_input(unsigned int gpio);
int __gpio_direction_output(unsigned int gpio, int value);
int gpio_direction_output(unsigned int gpio, int value);
int __gpio_set_pull_up(unsigned int gpio, int value);
int gpio_set_pull_up(unsigned int gpio, int value);
int __gpio_set_pull_down(unsigned int gpio, int value);
int gpio_set_pull_down(unsigned int gpio, int value);
int __gpio_set_hd(unsigned int gpio, int value);
int gpio_set_hd(unsigned int gpio, int value);
int __gpio_set_die(unsigned int gpio, int value);
int gpio_set_die(unsigned int gpio, int value);
int __gpio_set_output_clk(unsigned int gpio, int clk);
int gpio_set_output_clk(unsigned int gpio, int clk);
int __gpio_read(unsigned int gpio);
int gpio_read(unsigned int gpio);
#endif

View File

@ -0,0 +1,36 @@
#ifndef GENERIC_INCLUDES_H
#define GENERIC_INCLUDES_H
#include "errno-base.h"
#include "typedef.h"
#include "ascii.h"
#include "atomic.h"
#include "ioctl.h"
#include "cpu.h"
#include "gpio.h"
#include "irq.h"
#include "jiffies.h"
#include "list.h"
#include "printf.h"
#include "rect.h"
#include "version.h"
#include "lbuf.h"
#include "lbuf_lite.h"
#include "circular_buf.h"
#include "index.h"
#include "debug_lite.h"
#endif

View File

@ -0,0 +1,22 @@
#ifndef INDEX_H
#define INDEX_H
#include "typedef.h"
#define TABLE(t) t, ARRAY_SIZE(t)
int index_of_table8(u8 value, const u8 *table, int table_size);
int index_of_table16(u16 value, const u16 *table, int table_size);
int index_of_table32(u32 value, const u32 *table, int table_size);
#endif

View File

@ -0,0 +1,106 @@
#ifndef _ASM_GENERIC_IOCTL_H
#define _ASM_GENERIC_IOCTL_H
/* ioctl command encoding: 32 bits total, command in lower 16 bits,
* size of the parameter structure in the lower 14 bits of the
* upper 16 bits.
* Encoding the size of the parameter structure in the ioctl request
* is useful for catching programs compiled with old versions
* and to avoid overwriting user space outside the user buffer area.
* The highest 2 bits are reserved for indicating the ``access mode''.
* NOTE: This limits the max parameter size to 16kB -1 !
*/
/*
* The following is for compatibility across the various Linux
* platforms. The generic ioctl numbering scheme doesn't really enforce
* a type field. De facto, however, the top 8 bits of the lower 16
* bits are indeed used as a type field, so we might just as well make
* this explicit here. Please be sure to use the decoding macros
* below from now on.
*/
#define _IOC_NRBITS 8
#define _IOC_TYPEBITS 8
/*
* Let any architecture override either of the following before
* including this file.
*/
#ifndef _IOC_SIZEBITS
# define _IOC_SIZEBITS 14
#endif
#ifndef _IOC_DIRBITS
# define _IOC_DIRBITS 2
#endif
#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
#define _IOC_NRSHIFT 0
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
/*
* Direction bits, which any architecture can choose to override
* before including this file.
*/
#ifndef _IOC_NONE
# define _IOC_NONE 0U
#endif
#ifndef _IOC_WRITE
# define _IOC_WRITE 1U
#endif
#ifndef _IOC_READ
# define _IOC_READ 2U
#endif
#define _IOC(dir,type,nr,size) \
(((dir) << _IOC_DIRSHIFT) | \
((type) << _IOC_TYPESHIFT) | \
((nr) << _IOC_NRSHIFT) | \
((size) << _IOC_SIZESHIFT))
#ifdef __KERNEL__
/* provoke compile error for invalid uses of size argument */
extern unsigned int __invalid_size_argument_for_IOC;
#define _IOC_TYPECHECK(t) \
((sizeof(t) == sizeof(t[1]) && \
sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
sizeof(t) : __invalid_size_argument_for_IOC)
#else
#define _IOC_TYPECHECK(t) (sizeof(t))
#endif
/* used to create numbers */
#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
/* used to decode ioctl numbers.. */
#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
/* ...and for the drivers/sound files... */
#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
#endif /* _ASM_GENERIC_IOCTL_H */

View File

@ -0,0 +1,23 @@
#ifndef __IRQ_H_
#define __IRQ_H_
#include "asm/irq.h"
#endif

View File

@ -0,0 +1,35 @@
#ifndef JIFFIES_H
#define JIFFIES_H
/* timer interface */
/* Parameters used to convert the timespec values: */
#define HZ 100L
#define MSEC_PER_SEC 1000L
#define USEC_PER_MSEC 1000L
#define NSEC_PER_USEC 1000L
#define NSEC_PER_MSEC 1000000L
#define USEC_PER_SEC 1000000L
#define NSEC_PER_SEC 1000000000L
#define FSEC_PER_SEC 1000000000000000LL
#ifndef __ASSEMBLY__
extern volatile unsigned long jiffies;
extern unsigned long jiffies_msec();
extern unsigned long jiffies_half_msec();
#endif
#define JIFFIES_CIRCLE 0x7FFFFFF
#define time_after(a,b) ((long)(b) - (long)(a) < 0)
#define time_before(a,b) time_after(b,a)
extern unsigned char jiffies_unit;
#define msecs_to_jiffies(msec) ((msec)/jiffies_unit)
#define jiffies_to_msecs(j) ((j)*jiffies_unit)
#endif

View File

@ -0,0 +1,262 @@
#ifndef LBUF_H
#define LBUF_H
#include "typedef.h"
#include "list.h"
#include "system/spinlock.h"
#ifndef CONFIG_LBUF_IN_MASKROM
#define LBUF_DEBUG 0
struct lbuff_head {
#if LBUF_DEBUG
int magic_a; /*!< 测试验证变量*/
#endif
struct list_head head; /*!< 指向hentry链表*/
struct list_head free; /*!< 指向hfree链表*/
spinlock_t lock; /*!< 混合自旋锁,单核是为开关临界区,多核是自旋锁.*/
u8 align; /*!< 数据包字节对齐*/
u16 priv_len; /*!< 数据包结构体的最小长度*/
u32 total_size; /*!< 总大小*/
u32 last_addr; /*!< 指向free链表中找到的足够长度的hfree结构体地址*/
void *priv;
#if LBUF_DEBUG
int magic_b; /*!< 测试验证变量*/
#endif
};
struct lbuff_state {
u32 avaliable; /*!< 剩余空间的字节长度*/
u32 fragment; /*!< lbuf内存碎片块数量*/
u32 max_continue_len; /*!< 最大的剩余内存块的字节长度*/
int num; /*!< 剩余内存块数量*/
};
#else /* #ifndef CONFIG_LBUF_IN_MASKROM */
/* ---------------------------------------------------------------------------- */
/**
* @brief:
* @note: 以下结构体成员不可修改
*/
/* ---------------------------------------------------------------------------- */
struct lbuff_head {
#if 0 //LBUF_DEBUG
int magic_a; /*!< 测试验证变量*/
#endif
struct list_head head; /*!< 指向hentry链表*/
struct list_head free; /*!< 指向hfree链表*/
spinlock_t lock; /*!< 混合自旋锁,单核是为开关临界区,多核是自旋锁.*/
u8 align; /*!< 数据包字节对齐*/
u16 priv_len; /*!< 数据包结构体的最小长度*/
u32 total_size; /*!< 总大小*/
u32 last_addr; /*!< 指向free链表中找到的足够长度的hfree结构体地址*/
void *priv;
#if 0 //LBUF_DEBUG
int magic_b; /*!< 测试验证变量*/
#endif
};
struct lbuff_state {
u32 avaliable; /*!< 剩余空间的字节长度*/
u32 fragment; /*!< lbuf内存碎片块数量*/
u32 max_continue_len; /*!< 最大的剩余内存块的字节长度*/
int num; /*!< 剩余内存块数量*/
};
#endif /* #ifndef CONFIG_LBUF_IN_MASKROM */
/* --------------------------------------------------------------------------*/
/**
* @brief 链表buf初始化
*
* @param [in] buf 需要lbuf进行管理的内存
* @param [in] len 内存长度
* @param [in] align 输入对管理的内存进行对齐的参数,避免后续使用因地址不对齐产生碎片
* @param [in] priv_head_len 要管理的一个数据包结构体的最小的长度
*
* @return lbuf操作句柄
*/
/* --------------------------------------------------------------------------*/
struct lbuff_head *lbuf_init(void *buf, u32 len, int align, int priv_head_len);
/* --------------------------------------------------------------------------*/
/**
* @brief 分配内存空间进行存储数据包
*
* @param [in] head lbuf操作句柄
* @param [in] len 需要存入的数据包的长度
*
* @return 成功则返回进行存储数据包的地址,调用时候需要用户把该块内存的类型初始化为数据包结构体的类型。失败则返回NULL。
*/
/* --------------------------------------------------------------------------*/
void *lbuf_alloc(struct lbuff_head *head, u32 len);
/* --------------------------------------------------------------------------*/
/**
* @brief 重新分配lbuf_alloc()返回用于存储数据包的lbuf空间
*
* @param [in] lbuf lbuf_alloc()返回用于存储数据包的地址
* @param [in] size 需重新分配的空间的字节长度.注:size的大小只能比lbuf_alloc()中的len小,即只能重新分配更小的lbuf空间,不能扩大空间.
*
* @return 重新分配后用于存储数据包的地址。失败则返回空指针。注:重新分配最好使用lbuf_real_size()获取lbuf空间的长度确认是否分配成功
*/
/* --------------------------------------------------------------------------*/
void *lbuf_realloc(void *lbuf, int size);
/* --------------------------------------------------------------------------*/
/**
* @brief 判断lbuf空间内的内容是否为空
*
* @param [in] head lbuf操作句柄
*
* @return 返回1则为空,0则不为空
*/
/* --------------------------------------------------------------------------*/
int lbuf_empty(struct lbuff_head *head);
/* --------------------------------------------------------------------------*/
/**
* @brief 清空lbuf空间内进行已经分配给数据包的空间
*
* @param [in] head lbuf操作句柄
*/
/* --------------------------------------------------------------------------*/
void lbuf_clear(struct lbuff_head *head);
/* --------------------------------------------------------------------------*/
/**
* @brief 把数据包写入分配好的lbuf区域
*
* @param [in] lbuf lbuf_alloc()返回用于存储数据包的地址
* @param [in] channel_map 选择映射到哪个通道,最多8个通道,使用位映射的方式进行通道对应.
*/
/* --------------------------------------------------------------------------*/
void lbuf_push(void *lbuf, u8 channel_map);
/* --------------------------------------------------------------------------*/
/**
* @brief 读取对应的通道映射的lbuf区域存储的内容
*
* @param [in] head lbuf操作句柄
* @param [in] channel 需要读取的通道值,一般使用BIT(n),n为需要读取的通道
*
* @return 成功则返回存储对应的通道映射的数据包的地址
*/
/* --------------------------------------------------------------------------*/
void *lbuf_pop(struct lbuff_head *head, u8 channel);
/* --------------------------------------------------------------------------*/
/**
* @brief 释放存储数据包的lbuf空间
*
* @param [in] lbuf lbuf_alloc()返回用于存储数据包的地址
*
* @return 0则释放失败存在地址越界操作或者通道还没有被读完ref-1,读完后才能完全释放。1则释放成功。
*/
/* --------------------------------------------------------------------------*/
int lbuf_free(void *lbuf);
/* --------------------------------------------------------------------------*/
/**
* @brief 用于调试,检查是否可以释放存储数据包的lbuf空间
*
* @param [in] lbuf lbuf_alloc()返回用于存储数据包的地址
* @param [in] rets 调用lbuf_free_check()函数的返回地址rets,取值可参考lbuf_free()
*/
/* --------------------------------------------------------------------------*/
void lbuf_free_check(void *lbuf, u32 rets);
/* --------------------------------------------------------------------------*/
/**
* @brief 返回可分配的用来存储数据包的最大lbuf内存空间
*
* @param [in] head lbuf操作句柄
*
* @return 可分配的最大lbuf内存空间的字节长度
*/
/* --------------------------------------------------------------------------*/
u32 lbuf_free_space(struct lbuff_head *head);
/* --------------------------------------------------------------------------*/
/**
* @brief 获取lbuf空间的状态
*
* @param [in] head lbuf操作句柄
* @param [out] state lbuff_state结构体
*/
/* --------------------------------------------------------------------------*/
void lbuf_state(struct lbuff_head *head, struct lbuff_state *state);
/* --------------------------------------------------------------------------*/
/**
* @brief lbuf信息打印
*
* @param [in] head lbuf操作句柄
*/
/* --------------------------------------------------------------------------*/
void lbuf_dump(struct lbuff_head *head);
/* --------------------------------------------------------------------------*/
/**
* @brief 获取已经存入lbuf空间的数据包的数量
*
* @param [in] head lbuf操作句柄
*
* @return lbuf存储的数据包的数量
*/
/* --------------------------------------------------------------------------*/
int lbuf_traversal(struct lbuff_head *head);
/* --------------------------------------------------------------------------*/
/**
* @brief 返回lbuf空间还可以被写入size大小数据包的数量
*
* @param [in] head lbuf操作句柄
* @param [in] size 欲检测写入数据包的大小
*
* @return 可以写入的数量
*/
/* --------------------------------------------------------------------------*/
int lbuf_avaliable(struct lbuff_head *head, int size);
/* --------------------------------------------------------------------------*/
/**
* @brief 返回给数据包分配的内存空间的大小
*
* @param [in] lbuf lbuf_alloc()返回用于存储数据包的地址
*
* @return 实际占用空间的字节长度
*/
/* --------------------------------------------------------------------------*/
int lbuf_real_size(void *lbuf);
/* --------------------------------------------------------------------------*/
/**
* @brief 计算lbuf空间剩下多少剩余空间
*
* @param [in] head lbuf操作句柄
*
* @return 剩余空间的字节长度
*/
/* --------------------------------------------------------------------------*/
int lbuf_remain_space(struct lbuff_head *head);
/* --------------------------------------------------------------------------*/
/**
* @brief 需要被重复释放的次数+1
*
* @param [in] lbuf lbuf_alloc()返回用于存储数据包的地址
*/
/* --------------------------------------------------------------------------*/
void lbuf_inc_ref(void *lbuf);
#endif

View File

@ -0,0 +1,50 @@
#ifndef LBUF_LITE_H
#define LBUF_LITE_H
#include "typedef.h"
#include "list.h"
#include "system/spinlock.h"
struct lbuff_lite_head {
int magic_a;
struct list_head head;
struct list_head free;
spinlock_t lock;
u8 align;
u16 priv_len;
u32 total_size;
u32 last_addr;
void *priv;
int magic_b;
};
struct lbuff_lite_state {
u32 avaliable;
u32 fragment;
u32 max_continue_len;
int num;
};
struct lbuff_lite_head *lbuf_lite_init(void *buf, u32 len, int align, int priv_head_len);
void *lbuf_lite_alloc(struct lbuff_lite_head *head, u32 len);
void *lbuf_lite_realloc(void *lbuf, int size);
void lbuf_lite_free(void *lbuf);
u32 lbuf_lite_free_space(struct lbuff_lite_head *head);
void lbuf_lite_state(struct lbuff_lite_head *head, struct lbuff_lite_state *state);
void lbuf_lite_dump(struct lbuff_lite_head *head);
int lbuf_lite_avaliable(struct lbuff_lite_head *head, int size);
#endif

View File

@ -0,0 +1,291 @@
#ifndef LIST_H
#define LIST_H
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#ifdef list_offsetof
#undef list_offsetof
#endif
#ifdef container_of
#undef container_of
#endif
#define list_offsetof(type, memb) \
((unsigned long)(&((type *)0)->memb))
#define container_of(ptr, type, memb) \
((type *)((char *)(ptr) - list_offsetof(type, memb)))
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* list_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*
* Note, that list is expected to be not empty.
*/
/* REF_LIST: spi.c */
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); \
pos = pos->next)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop counter.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
#define list_for_each_entry_reverse_safe(pos, n, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member), \
n = list_entry(pos->member.prev, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
/* REF_LIST: spi.c */
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *_new,
struct list_head *prev,
struct list_head *next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
/* REF_LIST: spi.c */
static inline void list_add_tail(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head->prev, head);
}
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
static inline void __list_del_entry(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
}
/* REF_LIST: spi.c */
static inline void list_del(struct list_head *entry) //修改过的list_del这里与list_del_init一样
{
__list_del(entry->prev, entry->next);
entry->next = entry;
entry->prev = entry;
}
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
static inline void list_del_init(struct list_head *entry)
{
__list_del_entry(entry);
INIT_LIST_HEAD(entry);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
static inline int list_is_head(struct list_head *head, struct list_head *member)
{
return head->next == member;
}
#if 0
static inline void __list_splice(const struct list_head *list,
struct list_head *prev,
struct list_head *next)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
first->prev = prev;
prev->next = first;
last->next = next;
next->prev = last;
}
/**
* list_splice_tail_init - join two lists and reinitialise the emptied list
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* Each of the lists is a queue.
* The list at @list is reinitialised
*/
static inline void list_splice_tail_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head->prev, head);
INIT_LIST_HEAD(list);
}
}
/**
* list_is_singular - tests whether a list has just one entry.
* @head: the list to test.
*/
static inline int list_is_singular(const struct list_head *head)
{
return !list_empty(head) && (head->next == head->prev);
}
/**
* list_splice_tail - join two lists, each list being a queue
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice_tail(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head->prev, head);
}
}
#endif
#define list_for_each_entry_from(pos, head, member) \
for (; &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
#define list_for_each_entry_from_reverse(pos, head, member) \
for (; &pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
#endif

View File

@ -0,0 +1,127 @@
#ifndef __LOG_H
#define __LOG_H
#include "system/generic/printf.h"
#define __LOG_VERB 0
#define __LOG_DEBUG 1
#define __LOG_INFO 2
#define __LOG_WARN 3
#define __LOG_ERROR 4
#define __LOG_CHAR 5
struct logbuf {
u16 len;
u16 buf_len;
char buf[0];
};
#define __LOG_ENABLE
#ifndef __LOG_LEVEL
#define __LOG_LEVEL 0
#endif
#ifdef CONFIG_RELEASE_ENABLE
#undef __LOG_LEVEL
#define __LOG_LEVEL 0xff
#endif
#if __LOG_LEVEL > __LOG_VERB
#define log_v(...) do {} while (0)
#elif defined __LOG_ENABLE
#define log_v(...) log_print(__LOG_VERB, NULL, __VA_ARGS__)
#else
#define log_v(...) printf(__VA_ARGS__)
#endif
#if __LOG_LEVEL > __LOG_DEBUG
#define log_d(...) do {} while (0)
#elif defined __LOG_ENABLE
#define log_d(...) log_print(__LOG_DEBUG, NULL, __VA_ARGS__);
#else
#define log_d(...) printf(__VA_ARGS__)
#endif
#if __LOG_LEVEL > __LOG_INFO
#define log_i(...) do {} while (0)
#elif defined __LOG_ENABLE
#define log_i(...) log_print(__LOG_INFO, NULL, __VA_ARGS__);
#else
#define log_i(...) printf(__VA_ARGS__)
#endif
#if __LOG_LEVEL > __LOG_WARN
#define log_w(...) do {} while (0)
#elif defined __LOG_ENABLE
#define log_w(...) log_print(__LOG_WARN, NULL, __VA_ARGS__);
#else
#define log_w(...) printf(__VA_ARGS__)
#endif
#if __LOG_LEVEL > __LOG_ERROR
#define log_e(...) do {} while (0)
#elif defined __LOG_ENABLE
#define log_e(...) log_print(__LOG_ERROR, NULL, __VA_ARGS__);
#else
#define log_e(...) printf(__VA_ARGS__)
#endif
#if __LOG_LEVEL > __LOG_CHAR
#define log_c(x) do {} while (0)
#elif defined __LOG_ENABLE
#define log_c(x) putchar(x)
#else
#define log_c(x)
#endif
#define r_printf(x, ...) log_i("\e[31m\e[1m" x "\e[0m", ## __VA_ARGS__)
#define g_printf(x, ...) log_i("\e[32m\e[1m" x "\e[0m", ## __VA_ARGS__)
#define y_printf(x, ...) log_i("\e[33m\e[1m" x "\e[0m", ## __VA_ARGS__)
#define r_f_printf(x, ...) log_i("\e[31m\e[5m\e[1m" x "\e[0m", ## __VA_ARGS__)
#define g_f_printf(x, ...) log_i("\e[32m\e[5m\e[1m" x "\e[0m", ## __VA_ARGS__)
#define y_f_printf(x, ...) log_i("\e[33m\e[5m\e[1m" x "\e[0m", ## __VA_ARGS__)
#ifndef __LOG_ENABLE
#define log_dump(a, b) do {} while(0)
#define log_putchar() do {} while(0)
#define log_early_init(a) do {} while(0)
#define log_level(a) do {} while(0)
#else
int log_output_lock();
void log_output_unlock();
void log_print_time();
void log_early_init(int buf_size);
void log_level(int level);
void log_print(int level, const char *tag, const char *format, ...);
void log_dump(const u8 *buf, int len);
struct logbuf *log_output_start(int len);
void log_output_end(struct logbuf *);
void log_putchar(struct logbuf *lb, char c);
void log_put_u8hex(struct logbuf *lb, unsigned char dat);
void log_putbyte(char);
void log_set_time_offset(int offset);
int log_get_time_offset();
#endif
void log_flush();
#endif

View File

@ -0,0 +1,28 @@
#ifndef _PRINTF_H_
#define _PRINTF_H_
#define line_inf printf("%s %s %d \r\n" ,__FILE__, __func__ , __LINE__) ;
#include <stdarg.h>
#include "typedef.h"
//#define NOFLOAT
extern int putchar(int a);
extern int puts(const char *out);
void put_u4hex(unsigned char dat);
void put_u8hex(unsigned char dat);
void put_u16hex(unsigned short dat);
void put_u32hex(unsigned int dat);
void put_buf(const u8 *buf, int len);
int printf(const char *format, ...);
int assert_printf(const char *format, ...);
int sprintf(char *out, const char *format, ...);
int vprintf(const char *fmt, __builtin_va_list va);
int vsnprintf(char *, unsigned long, const char *, __builtin_va_list);
int snprintf(char *buf, unsigned long size, const char *fmt, ...);
int print(char **out, char *end, const char *format, va_list args);
//int snprintf(char *, unsigned long, const char *, ...);
int sscanf(const char *buf, const char *fmt, ...); //BUG: 多个参数? 最后又空格?
//int perror(const char *fmt, ...);
#endif

View File

@ -0,0 +1,134 @@
#ifndef RECT_H
#define RECT_H
#include "typedef.h"
#define AT_UI_RAM AT(.ui_ram)
struct position {
int x;
int y;
};
struct rect {
int left;
int top;
int width;
int height;
};
#define rect_left(r) ((r)->left)
#define rect_top(r) ((r)->top)
#define rect_right(r) ((r)->left + (r)->width)
#define rect_bottom(r) ((r)->top + (r)->height)
//#define rect_height(v) ((v)->bottom - (v)->top)
//#define rect_width(v) ((v)->right - (v)->left)
static inline int in_rect(const struct rect *rect, struct position *pos)
{
if (rect->left <= pos->x && rect_right(rect) > pos->x) {
if (rect->top <= pos->y && rect_bottom(rect) > pos->y) {
return true;
}
}
return false;
}
AT_UI_RAM
static inline bool get_rect_cover(const struct rect *a, const struct rect *b, struct rect *c)
{
int right, bottom;
c->top = MAX(a->top, b->top);
c->left = MAX(a->left, b->left);
right = MIN(rect_right(a), rect_right(b));
bottom = MIN(rect_bottom(a), rect_bottom(b));
if ((c->top < bottom) && (c->left < right)) {
c->width = right - c->left;
c->height = bottom - c->top;
return true;
}
return false;
}
static inline bool get_rect_nocover_l(const struct rect *a, const struct rect *b, struct rect *c)
{
int right, bottom;
c->left = MIN(rect_left(a), rect_left(b));
c->top = MIN(rect_top(a), rect_top(b));
right = MAX(rect_left(a), rect_left(b));
bottom = MAX(rect_bottom(a), rect_bottom(b));
if ((c->top < bottom) && (c->left < right)) {
c->width = right - c->left;
c->height = bottom - c->top;
return true;
}
return false;
}
static inline bool get_rect_nocover_r(const struct rect *a, const struct rect *b, struct rect *c)
{
int right, bottom;
c->left = MIN(rect_right(a), rect_right(b));
c->top = MIN(rect_top(a), rect_top(b));
right = MAX(rect_right(a), rect_right(b));
bottom = MAX(rect_bottom(a), rect_bottom(b));
if ((c->top < bottom) && (c->left < right)) {
c->width = right - c->left;
c->height = bottom - c->top;
return true;
}
return false;
}
static inline bool get_rect_nocover_t(const struct rect *a, const struct rect *b, struct rect *c)
{
int right, bottom;
c->left = MIN(rect_left(a), rect_left(b));
c->top = MIN(rect_top(a), rect_top(b));
right = MAX(rect_right(a), rect_right(b));
bottom = MAX(rect_top(a), rect_top(b));
if ((c->top < bottom) && (c->left < right)) {
c->width = right - c->left;
c->height = bottom - c->top;
return true;
}
return false;
}
static inline bool get_rect_nocover_b(const struct rect *a, const struct rect *b, struct rect *c)
{
int right, bottom;
c->left = MIN(rect_left(a), rect_left(b));
c->top = MIN(rect_bottom(a), rect_bottom(b));
right = MAX(rect_right(a), rect_right(b));
bottom = MAX(rect_bottom(a), rect_bottom(b));
if ((c->top < bottom) && (c->left < right)) {
c->width = right - c->left;
c->height = bottom - c->top;
return true;
}
return false;
}
#endif

View File

@ -0,0 +1,167 @@
/*************************************************************
File: typedef.h
Author:Juntham
Discriptor:
数据类型重定义
Version:
Date
*************************************************************/
#ifndef _typedef_h_
#define _typedef_h_
#include "asm/cpu.h"
#if defined(__GNUC__)
///<locate code to x segment ever exist
#define SEC_USED(x) __attribute__((section(#x),used))
///<locate code to x segment optimized by dependency
#define SEC(x) __attribute__((section(#x)))
#define sec(x) __attribute__((section(#x),used))
///<locate data to x segment
#define AT(x) __attribute__((section(#x)))
#define SET(x) __attribute__((x))
#define ALIGNED(x) __attribute__((aligned(x)))
#define _GNU_PACKED_ __attribute__((packed))
#define _NOINLINE_ __attribute__((noinline))
#define _INLINE_ __attribute__((always_inline))
#define _WEAK_ __attribute__((weak))
#define _WEAKREF_ __attribute__((weakref))
#define _NORETURN_ __attribute__((noreturn))
#define _NAKED_ __attribute__((naked))
#else
#define SEC_USED(x)
#define SEC(x)
#define AT(x)
#define SET(x)
#define ALIGNED(x)
#define _GNU_PACKED_
#define _NOINLINE_
#define _INLINE_
#define _WEAK_
#define _WEAKREF_
#define _NORETURN_
#define _NAKED_
#endif
#if CPU_ENDIAN == LITTLE_ENDIAN
//#define ntohl(x) (u32)((x>>24)|((x>>8)&0xff00)|(x<<24)|((x&0xff00)<<8))
//#define ntoh(x) (u16)((x>>8&0x00ff)|x<<8&0xff00)
//#define ntohl(x) (u32)((((u32)(x))>>24) | ((((u32)(x))>>8)&0xff00) | (((u32)(x))<<24) | ((((u32)(x))&0xff00)<<8))
//#define ntoh(x) (u16)((((u32)(x))>>8&0x00ff) | (((u32)(x))<<8&0xff00))
//#define NTOH(x) (x) = ntoh(x)
//#define NTOHL(x) (x) = ntohl(x)
#define LD_WORD(ptr) (u16)(*(u16*)(u8*)(ptr))
#define LD_DWORD(ptr) (u32)(*(u32*)(u8*)(ptr))
#define ST_WORD(ptr,val) *(u16*)(u8*)(ptr)=(u16)(val)
#define ST_DWORD(ptr,val) *(u32*)(u8*)(ptr)=(u32)(val)
#else
#define ntohl(x) (x)
#define ntoh(x) (x)
#define NTOH(x) (x) = ntoh(x)
#define NTOHL(x) (x) = ntohl(x)
#endif
#undef FALSE
#define FALSE 0
#undef TRUE
#define TRUE 1
#define false 0
#define true 1
#ifndef NULL
#define NULL (void *)0
#endif
#define BIT(n) (1UL << (n))
#define BitSET(REG,POS) ((REG) |= (1L << (POS)))
#define BitCLR(REG,POS) ((REG) &= (~(1L<< (POS))))
#define BitXOR(REG,POS) ((REG) ^= (~(1L << (POS))))
#define BitCHK_1(REG,POS) (((REG) & (1L << (POS))) == (1L << (POS)))
#define BitCHK_0(REG,POS) (((REG) & (1L << (POS))) == 0x00)
#define testBit(REG,POS) ((REG) & (1L << (POS)))
#define clrBit(x,y) (x) &= ~(1L << (y))
#define setBit(x,y) (x) |= (1L << (y))
#define readb(addr) *((volatile unsigned char*)(addr))
#define readw(addr) *((volatile unsigned short *)(addr))
#define readl(addr) *((volatile unsigned long*)(addr))
#define writeb(addr, val) *((volatile unsigned char*)(addr)) = (u8)(val)
#define writew(addr, val) *((volatile unsigned short *)(addr)) = (u16)(val)
#define writel(addr, val) *((volatile unsigned long*)(addr)) = (u32)(val)
#define ALIGN_4BYTE(size) ((size+3)&0xfffffffc)
#if CPU_ENDIAN == BIG_ENDIAN
#define __cpu_u16(lo, hi) ((lo)|((hi)<<8))
#elif CPU_ENDIAN == LITTLE_ENDIAN
#define __cpu_u16(lo, hi) ((hi)|((lo)<<8))
#else
#error "undefine cpu eadin"
#endif
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define SFR(sfr, start, len, dat) \
(sfr = (sfr & ~((~(0xffffffff << (len))) << (start))) | \
(((dat) & (~(0xffffffff << (len)))) << (start)))
#include "generic/errno-base.h"
#include "string.h"
#include "strings.h"
#include "system/malloc.h"
#ifdef offsetof
#undef offsetof
#endif
#ifdef container_of
#undef container_of
#endif
#define offsetof(type, memb) \
((unsigned long)(&((type *)0)->memb))
#define container_of(ptr, type, memb) \
((type *)((char *)(ptr) - offsetof(type, memb)))
void delay(unsigned int);
void delay_us(unsigned int);
#endif

View File

@ -0,0 +1,133 @@
#ifndef VERSION_H
#define VERSION_H
#include "typedef.h"
typedef int (*version_t)(int);
//定义模块的版本号,由主版本号和次版本号组成
//如果两个模块的主版本号相同即表示兼容
#define VERSION(major, minor) (((major)<<8) | (minor))
#define MAJOR(v) ((v) >> 16)
#define MINOR(v) (((v) >> 8) & 0xff)
#define version_match(module_a, module_b) \
({ \
extern int module_a##_version(int ); \
extern int module_b##_version(int ); \
int version_a = module_a##_version(0); \
int version_b = module_b##_version(0); \
MAJOR(version_a) == MAJOR(version_b);\
})
#define __MODULE_VERSION_EXPORT_BEGIN(module, version) \
int module##_version(int prt) \
{ \
if (prt) { \
log_i(#module": %d.%d.%d build at: %s\n", (version)>>16, \
((version) >> 8) & 0xff, (version) & 0xff, __DATE__); \
} \
#define __MODULE_VERSION_EXPORT_END(module, version) \
return version; \
} \
const version_t __version_##module \
__attribute__((section(".lib_version"),used)) = module##_version
#define __MODULE_VERSION_EXPORT(module, version) \
__MODULE_VERSION_EXPORT_BEGIN(module, version) \
__MODULE_VERSION_EXPORT_END(module, version);
#define __MODULE_VERSION_EXPORT_SECTION(module, version, section) \
__MODULE_VERSION_EXPORT_BEGIN(module, version) \
(void *)&section; \
__MODULE_VERSION_EXPORT_END(module, version)
#define __MODULE_DEPEND_BEGIN(module) \
int module##_version_check() \
{ \
#define _MODULE_DEPEND_BEGIN(module) \
__MODULE_DEPEND_BEGIN(module)
#define __VERSION_CHECK(module, version) \
do { \
int module##_version(int prt); \
int v = module##_version(0); \
if (MAJOR(version) != MAJOR(v) || MINOR(version) > MINOR(v)) { \
log_i("=======version not match=======\n"); \
module##_version(1); \
log_i("==================================\n"); \
while(1); \
} \
} while(0)
/*-------------------上面的宏请勿调用------------------------------------*/
//定义当前模块的版本检测函数
#define MODULE_VERSION_EXPORT(module, version) \
__MODULE_VERSION_EXPORT(module, version)
#define MODULE_VERSION_EXPORT_SECTION(module, version, section) \
__MODULE_VERSION_EXPORT_SECTION(module, version, section)
#define MODULE_VERSION_EXPORT_BEGIN(module, version) \
__MODULE_VERSION_EXPORT_BEGIN(module, version)
#define MODULE_VERSION_EXPORT_END(module, version) \
__MODULE_VERSION_EXPORT_END(module, version)
//以下3个宏定义当前模块依赖的其它模块列表
#define MODULE_DEPEND_BEGIN() \
_MODULE_DEPEND_BEGIN(THIS_MODULE)
#define MODULE_DEPEND(module_d, version) \
__VERSION_CHECK(module_d, version)
#define MODULE_DEPEND_END() \
return 0; \
}
#define VERSION_CHECK(module, version) \
__VERSION_CHECK(module, version)
//通过调用版本检测函数使的模块的代码能够被链接
#define load_module(module) \
({ \
int ret; \
extern int module##_version_check(); \
ret = module##_version_check();\
ret; \
})
extern version_t lib_version_begin[], lib_version_end[];
#define lib_version_check() \
do { \
version_t *version; \
log_i("=========version check===========\n"); \
for (version = lib_version_begin; version < lib_version_end; version++) { \
(*version)(1); \
}; \
log_i("==================================\n\n"); \
} while (0)
#endif