import
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
#include <drv_device.h>
|
||||
#include <drv_rbtree.h>
|
||||
#include "os_align.h"
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
#define NODE_BLOCK_SIZE (DRV_RBTREE_NODE_SIZE * OS_CFG_DEVICE_MAX)
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
static volatile uint8_t s_drv_device_id_cnt;
|
||||
|
||||
OS_ALIGNED(OS_ALIGN_SIZE)
|
||||
static uint8_t s_drv_device_rbtree_node_block[NODE_BLOCK_SIZE];
|
||||
|
||||
static drv_rbtree_t s_drv_rbtree;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
|
||||
void drv_device_system_init(void){
|
||||
s_drv_device_id_cnt = 0;
|
||||
drv_rbtree_init(&s_drv_rbtree, s_drv_device_rbtree_node_block, NODE_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
void drv_device_register(drv_device_t* self,
|
||||
const char* name,
|
||||
void* handle,
|
||||
os_err_t (*init)(void* handle, void* args),
|
||||
os_err_t (*destroy)(void* handle, void* args),
|
||||
os_err_t (*open)(void* handle, void* args),
|
||||
os_err_t (*close)(void* handle, void* args),
|
||||
os_err_t (*read)(void* handle, uint8_t * buf, os_size_t buf_size, os_size_t * rd_size, void* args),
|
||||
os_err_t (*write)(void* handle, const uint8_t * data, os_size_t data_size, os_size_t * wr_size, void* args),
|
||||
void* args)
|
||||
{
|
||||
self->handle = handle;
|
||||
self->init = init;
|
||||
self->destroy = destroy;
|
||||
self->open = open;
|
||||
self->close = close;
|
||||
self->read = read;
|
||||
self->write = write;
|
||||
self->args = args;
|
||||
if(name){
|
||||
os_size_t name_len = strlen(name);
|
||||
name_len = OS_MIN(name_len, OS_ARRAY_SIZE(self->name)-1);
|
||||
strncpy(self->name, name, name_len);
|
||||
self->name[name_len] = '\0';
|
||||
}else{
|
||||
snprintf(self->name, OS_ARRAY_SIZE(self->name), "drv_%d", s_drv_device_id_cnt++);
|
||||
}
|
||||
|
||||
drv_rbtree_insert(&s_drv_rbtree, self);
|
||||
}
|
||||
|
||||
|
||||
void drv_device_unregister(drv_device_t* self){
|
||||
if(!self) return;
|
||||
drv_rbtree_remove(&s_drv_rbtree, self->name);
|
||||
}
|
||||
|
||||
drv_device_t* drv_device_find(const char* name){
|
||||
drv_rbtree_node_t* p = drv_rbtree_find(&s_drv_rbtree, name);
|
||||
if(p==NULL) return NULL;
|
||||
return &p->device;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#ifndef INCLUDED_DRV_DEVICE_H
|
||||
#define INCLUDED_DRV_DEVICE_H
|
||||
|
||||
#ifndef INCLUDED_OS_TYPES_H
|
||||
#include <os_types.h>
|
||||
#endif /*INCLUDED_OS_TYPES_H*/
|
||||
|
||||
#ifndef INCLUDED_OS_COMPILER_H
|
||||
#include <os_compiler.h>
|
||||
#endif /*INCLUDED_OS_COMPILER_H*/
|
||||
|
||||
#ifndef INCLUDED_OS_MACROS_H
|
||||
#include <os_macros.h>
|
||||
#endif /*INCLUDED_OS_MACROS_H*/
|
||||
|
||||
|
||||
#ifndef INCLUDED_OS_LIST_H
|
||||
#include <os_list.h>
|
||||
#endif /*INCLUDED_OS_LIST_H*/
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
typedef struct {
|
||||
void* handle;
|
||||
os_list_node_t node;
|
||||
os_err_t (*init)(void* handle, void* args);
|
||||
os_err_t (*destroy)(void* handle, void* args);
|
||||
os_err_t (*open)(void* handle, void* args);
|
||||
os_err_t (*close)(void* handle, void* args);
|
||||
os_err_t (*read)(void* handle, uint8_t * buf, os_size_t buf_size, os_size_t * rd_size, void* args);
|
||||
os_err_t (*write)(void* handle, const uint8_t * data, os_size_t data_size, os_size_t * wr_size, void* args);
|
||||
void* args;
|
||||
char name[OS_CFG_NAME_MAX];
|
||||
}drv_device_t;
|
||||
|
||||
#define drv_device_init(dev) (dev)->init((dev)->handle, (dev)->args)
|
||||
#define drv_device_destroy(dev) (dev)->destroy((dev)->handle, (dev)->args)
|
||||
#define drv_device_open(dev) (dev)->open((dev)->handle, (dev)->args)
|
||||
#define drv_device_close(dev) (dev)->close((dev)->handle, (dev)->args)
|
||||
#define drv_device_read(dev, buf, buf_sz, rd_sz) (dev)->read((dev)->handle, (uint8_t*)(buf), (os_size_t)(buf_sz), rd_sz, (dev)->args)
|
||||
#define drv_device_write(dev, buf, buf_sz, wr_sz) (dev)->write((dev)->handle, (const uint8_t*)(buf), (os_size_t)(buf_sz), wr_sz, (dev)->args)
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
void drv_device_system_init(void);
|
||||
|
||||
void drv_device_register(drv_device_t* self,
|
||||
const char* name,
|
||||
void* handle,
|
||||
os_err_t (*init)(void* handle, void* args),
|
||||
os_err_t (*destroy)(void* handle, void* args),
|
||||
os_err_t (*open)(void* handle, void* args),
|
||||
os_err_t (*close)(void* handle, void* args),
|
||||
os_err_t (*read)(void* handle, uint8_t * buf, os_size_t buf_size, os_size_t * rd_size, void* args),
|
||||
os_err_t (*write)(void* handle, const uint8_t * data, os_size_t data_size, os_size_t * wr_size, void* args),
|
||||
void* args);
|
||||
|
||||
void drv_device_unregister(drv_device_t* self);
|
||||
|
||||
drv_device_t* drv_device_find(const char* name);
|
||||
|
||||
#endif /*INCLUDED_DRV_DEVICE_H*/
|
||||
@@ -0,0 +1,490 @@
|
||||
#include <drv_rbtree.h>
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
typedef drv_rbtree_node_t rbtree_node_t;
|
||||
typedef drv_rbtree_t rbtree_t;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
#define RED 'R'
|
||||
#define BLACK 'B'
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
int node_cmp(const char* a, const char * b){
|
||||
os_size_t na_len = strlen(a);
|
||||
os_size_t nb_len = strlen(b);
|
||||
return strncmp(a, b, OS_MIN(na_len, nb_len));
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void node_init(rbtree_t* tree, rbtree_node_t * self, drv_device_t* val){
|
||||
self->left = self->right = self->parent = 0;
|
||||
self->color = RED;
|
||||
self->device = *val;
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void node_destroy(rbtree_t* tree, rbtree_node_t * x){
|
||||
pool_free(&tree->node_pool, x);
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void rotate_left(rbtree_t* self, rbtree_node_t * x){
|
||||
rbtree_node_t * y = x->right;
|
||||
x->right = y->left;
|
||||
if(y->left){
|
||||
y->left->parent = x;
|
||||
}
|
||||
y->parent = x->parent;
|
||||
if(!x->parent){
|
||||
self->root = y;
|
||||
} else{
|
||||
if(x->parent->left==x){
|
||||
x->parent->left = y;
|
||||
}else{
|
||||
x->parent->right = y;
|
||||
}
|
||||
}
|
||||
y->left = x;
|
||||
x->parent = y;
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void rotate_right(rbtree_t* self, rbtree_node_t * y){
|
||||
rbtree_node_t * x = y->left;
|
||||
y->left = x->right;
|
||||
if(x->right){
|
||||
x->right->parent = y;
|
||||
}
|
||||
x->parent = y->parent;
|
||||
if(!y->parent){
|
||||
self->root = x;
|
||||
}else{
|
||||
if(y==y->parent->left){
|
||||
y->parent->left = x;
|
||||
}else{
|
||||
y->parent->right = x;
|
||||
}
|
||||
}
|
||||
x->right = y;
|
||||
y->parent = x;
|
||||
}
|
||||
|
||||
static rbtree_node_t * find(rbtree_t* self, const char* key, rbtree_node_t * x){
|
||||
while(x){
|
||||
int cmp = node_cmp(x->device.name, key);
|
||||
if(cmp < 0){
|
||||
x = x->left;
|
||||
}else if(cmp > 0){
|
||||
x = x->right;
|
||||
}else{
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
rbtree_node_t * node_parent(rbtree_node_t * x){
|
||||
return (x!=NULL)?x->parent:NULL;
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
char node_color(rbtree_node_t * x){
|
||||
return (x!=NULL)?x->color:BLACK;
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
bool node_is_red(rbtree_node_t * x){
|
||||
return (node_color(x)==RED)?true:false;
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
bool node_is_black(rbtree_node_t * x){
|
||||
return !node_is_red(x);
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void node_set_black(rbtree_node_t * x){
|
||||
if(x){
|
||||
x->color = BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void node_set_red(rbtree_node_t * x){
|
||||
if(x){
|
||||
x->color = RED;
|
||||
}
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void node_set_color(rbtree_node_t * x, char color){
|
||||
if(x){
|
||||
x->color = color;
|
||||
}
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void node_set_parent(rbtree_node_t * x, rbtree_node_t * parent){
|
||||
if(x){
|
||||
x->parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void node_insert_fixup(rbtree_t* tree, rbtree_node_t * node){
|
||||
rbtree_node_t * parent=0;
|
||||
rbtree_node_t * gparent=0;
|
||||
|
||||
while(((parent = node->parent)!=NULL) && node_is_red(parent)){
|
||||
gparent = node_parent(parent);
|
||||
if(parent==gparent->left){
|
||||
rbtree_node_t * pUncle = gparent->right;
|
||||
if((pUncle!=NULL) && node_is_red(pUncle)){
|
||||
// Case 1条件:叔叔节点是红色
|
||||
node_set_black(pUncle);
|
||||
node_set_black(parent);
|
||||
node_set_red(gparent);
|
||||
node = gparent;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(parent->right==node){
|
||||
// Case 3条件:叔叔是黑色,且当前节点是右孩子
|
||||
rbtree_node_t * pTmp;
|
||||
rotate_left(tree, parent);
|
||||
pTmp = parent;
|
||||
parent = node;
|
||||
node = pTmp;
|
||||
}
|
||||
|
||||
// Case 2条件:叔叔是黑色,且当前节点是左孩子。
|
||||
node_set_black(parent);
|
||||
node_set_red(gparent);
|
||||
rotate_right(tree, gparent);
|
||||
}else{
|
||||
//若“z的父节点”是“z的祖父节点的右孩子”
|
||||
rbtree_node_t * pUncle = gparent->left;
|
||||
if((pUncle!=NULL) && node_is_red(pUncle)) {
|
||||
// Case 1条件:叔叔节点是红色
|
||||
node_set_black(pUncle);
|
||||
node_set_black(parent);
|
||||
node_set_red(gparent);
|
||||
node = gparent;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Case 2条件:叔叔是黑色,且当前节点是左孩子
|
||||
if(parent->left == node){
|
||||
rbtree_node_t * pTmp;
|
||||
rotate_right(tree, parent);
|
||||
pTmp = parent;
|
||||
parent = node;
|
||||
node = pTmp;
|
||||
}
|
||||
|
||||
// Case 3条件:叔叔是黑色,且当前节点是右孩子。
|
||||
node_set_black(parent);
|
||||
node_set_red(gparent);
|
||||
rotate_left(tree, gparent);
|
||||
}
|
||||
}
|
||||
node_set_black(tree->root);
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void node_insert(rbtree_t* tree, rbtree_node_t * node){
|
||||
int cmp = 0;
|
||||
rbtree_node_t * y = NULL;
|
||||
rbtree_node_t * x = tree->root;
|
||||
|
||||
// 1. 将红黑树当作一颗二叉查找树,将节点添加到二叉查找树中。
|
||||
while (x) {
|
||||
y = x;
|
||||
cmp = node_cmp(node->device.name, x->device.name);
|
||||
if (cmp < 0)
|
||||
x = x->left;
|
||||
else
|
||||
x = x->right;
|
||||
}
|
||||
// y 是要插入的父节点
|
||||
node->parent = y;
|
||||
if(!y){
|
||||
// 插入根节点
|
||||
tree->root = node;
|
||||
}else{
|
||||
// 判断插入父节点的左边还是右边
|
||||
cmp = node_cmp(node->device.name, y->device.name);
|
||||
if(cmp < 0){
|
||||
y->left = node;
|
||||
}else{
|
||||
y->right = node;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 设置节点的颜色为红色
|
||||
node->color = RED;
|
||||
|
||||
// 3. 将它重新修正为一颗二叉查找树
|
||||
node_insert_fixup(tree, node);
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void node_remove_fixeup(rbtree_t* tree, rbtree_node_t * node, rbtree_node_t * parent){
|
||||
rbtree_node_t * other;
|
||||
|
||||
while(parent!=NULL && (node==NULL || node_is_black(node)) && (node!=tree->root) ){
|
||||
if(parent->left == node){
|
||||
other= parent->right;
|
||||
if(node_is_red(other)){
|
||||
// Case 1: x的兄弟w是红色的
|
||||
node_set_black(other);
|
||||
node_set_red(parent);
|
||||
rotate_left(tree, parent);
|
||||
other = parent->right;
|
||||
}
|
||||
|
||||
if((other->left==NULL || node_is_black(other->left)) && (other->right==NULL ||
|
||||
node_is_black(other->right))){
|
||||
// Case 2: x的兄弟w是黑色,且w的俩个孩子也都是黑色的
|
||||
node_set_red(other);
|
||||
node = parent;
|
||||
parent = node_parent(node);
|
||||
}else{
|
||||
if(other->right==NULL || node_is_black(other->right)){
|
||||
// Case 4: x的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。
|
||||
node_set_black(other->left);
|
||||
node_set_red(other);
|
||||
rotate_right(tree, other);
|
||||
other = parent->right;
|
||||
}
|
||||
// Case 3: x的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。
|
||||
node_set_color(other, node_color(parent));
|
||||
node_set_black(parent);
|
||||
node_set_black(other->right);
|
||||
rotate_left(tree, parent);
|
||||
node = tree->root;
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
other= parent->left;
|
||||
if(node_is_red(other)){
|
||||
// Case 1: x的兄弟w是红色的
|
||||
node_set_black(other);
|
||||
node_set_red(parent);
|
||||
rotate_right(tree, parent);
|
||||
other = parent->left;
|
||||
}
|
||||
|
||||
if((other->left==NULL || node_is_black(other->left)) && (other->right==NULL ||
|
||||
node_is_black(other->right))){
|
||||
// Case 2: x的兄弟w是黑色,且w的俩个孩子也都是黑色的
|
||||
node_set_red(other);
|
||||
node = parent;
|
||||
parent = node_parent(node);
|
||||
}else{
|
||||
if(other->left==NULL || node_is_black(other->left)){
|
||||
// Case 4: x的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。
|
||||
node_set_black(other->right);
|
||||
node_set_red(other);
|
||||
rotate_left(tree, other);
|
||||
other= parent->left;
|
||||
}
|
||||
|
||||
// Case 3: x的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。
|
||||
node_set_color(other, node_color(parent));
|
||||
node_set_black(parent);
|
||||
node_set_black(other->left);
|
||||
rotate_right(tree, parent);
|
||||
node = tree->root;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(node){
|
||||
node_set_black(node);
|
||||
}
|
||||
}
|
||||
|
||||
OS_STATIC_FORCE_INLINE
|
||||
void node_remove(rbtree_t* tree, rbtree_node_t * node){
|
||||
rbtree_node_t * child=NULL;
|
||||
rbtree_node_t * parent=NULL;
|
||||
char color;
|
||||
|
||||
// 被删除节点的"左右孩子都不为空"的情况。
|
||||
if((node->left!=NULL) && (node->right!=NULL)){
|
||||
// 被删节点的后继节点。(称为"取代节点")
|
||||
// 用它来取代"被删节点"的位置,然后再将"被删节点"去掉。
|
||||
|
||||
rbtree_node_t * replace = node;
|
||||
|
||||
// 获取后继节点
|
||||
replace = replace->right;
|
||||
while(replace->left){
|
||||
replace = replace->left;
|
||||
}
|
||||
|
||||
// "node节点"不是根节点(只有根节点不存在父节点)
|
||||
if(node_parent(node)!=NULL){
|
||||
if(node->parent->left == node){
|
||||
node->parent->left = replace;
|
||||
}else{
|
||||
node->parent->right = replace;
|
||||
}
|
||||
}else{
|
||||
// "node节点"是根节点,更新根节点。
|
||||
tree->root = replace;
|
||||
}
|
||||
|
||||
// child是"取代节点"的右孩子,也是需要"调整的节点"。
|
||||
// "取代节点"肯定不存在左孩子!因为它是一个后继节点。
|
||||
|
||||
child = replace->right;
|
||||
parent= node_parent(replace);
|
||||
|
||||
// 保存"取代节点"的颜色
|
||||
color = node_color(replace);
|
||||
|
||||
// "被删除节点"是"它的后继节点的父节点"
|
||||
if(parent == node){
|
||||
parent = replace;
|
||||
}else {
|
||||
// child 不为空
|
||||
if(child!=NULL){
|
||||
node_set_parent(child, parent);
|
||||
}
|
||||
parent->left = child;
|
||||
|
||||
replace->right = node->right;
|
||||
node_set_parent(node->right, replace);
|
||||
}
|
||||
|
||||
replace->parent = node->parent;
|
||||
replace->color = node->color;
|
||||
replace->left= node->left;
|
||||
node->left->parent = replace;
|
||||
|
||||
if(color==BLACK){
|
||||
node_remove_fixeup(tree, child, parent);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(node->left!=NULL){
|
||||
child = node->left;
|
||||
}else{
|
||||
child= node->right;
|
||||
}
|
||||
|
||||
parent = node->parent;
|
||||
color = node->color;
|
||||
if(child!=NULL){
|
||||
child->parent = parent;
|
||||
}
|
||||
|
||||
// "node节点"不是根节点
|
||||
if(parent){
|
||||
if(parent->left==node){
|
||||
parent->left = child;
|
||||
}else{
|
||||
parent->right = child;
|
||||
}
|
||||
}else{
|
||||
tree->root = child;
|
||||
}
|
||||
|
||||
|
||||
if(color==BLACK){
|
||||
node_remove_fixeup(tree, child, parent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
|
||||
|
||||
void drv_rbtree_init(drv_rbtree_t* self, void* node_block, os_size_t node_block_size){
|
||||
pool_init(&self->node_pool, sizeof(rbtree_node_t));
|
||||
pool_add_block(&self->node_pool, node_block, node_block_size);
|
||||
self->root = 0;
|
||||
}
|
||||
|
||||
void drv_rbtree_add_node_pool(drv_rbtree_t* self, void* node_block, os_size_t node_block_size){
|
||||
pool_add_block(&self->node_pool, node_block, node_block_size);
|
||||
}
|
||||
|
||||
void drv_rbtree_destroy(drv_rbtree_t* self){
|
||||
while(self->root){
|
||||
rbtree_node_t* p = self->root;
|
||||
node_remove(self, self->root);
|
||||
node_destroy(self, p);
|
||||
}
|
||||
}
|
||||
|
||||
drv_rbtree_node_t* drv_rbtree_find(drv_rbtree_t* self, const char* key){
|
||||
if(key==NULL) return NULL;
|
||||
return find(self, key, self->root);
|
||||
}
|
||||
|
||||
drv_rbtree_node_t* drv_rbtree_custom_find(drv_rbtree_t* self, const char* key
|
||||
, drv_rbtree_node_t* (*custom_find)(rbtree_t* tree, const char* key, drv_rbtree_node_t* x, void* args)
|
||||
, void* args)
|
||||
{
|
||||
if(key==NULL) return NULL;
|
||||
return custom_find(self, key, self->root, args);
|
||||
}
|
||||
|
||||
os_err_t drv_rbtree_insert(drv_rbtree_t* self, drv_device_t* device){
|
||||
drv_rbtree_node_t* p = pool_alloc(&self->node_pool);
|
||||
if(!p){
|
||||
return OS_ERR_FAIL;
|
||||
}
|
||||
node_init(self, p, device);
|
||||
node_insert(self, p);
|
||||
return OS_ERR_OK;
|
||||
}
|
||||
|
||||
void drv_rbtree_remove(drv_rbtree_t* self, const char* key){
|
||||
drv_rbtree_node_t * pNode = drv_rbtree_find(self, key);
|
||||
if(pNode==NULL){
|
||||
return;
|
||||
}
|
||||
node_remove(self, pNode);
|
||||
node_destroy(self, pNode);
|
||||
}
|
||||
|
||||
void drv_rbtree_remove_node(drv_rbtree_t* self, drv_rbtree_node_t* x){
|
||||
if(x==NULL) return;
|
||||
node_remove(self, x);
|
||||
node_destroy(self, x);
|
||||
}
|
||||
|
||||
static void in_order(drv_rbtree_t* self, drv_rbtree_node_t* x,
|
||||
int (*apply)(drv_rbtree_t* tree, drv_rbtree_node_t* x, void* args), void* args){
|
||||
if(x){
|
||||
in_order(self, x->left, apply, args);
|
||||
if(apply(self, x, args)==0){
|
||||
return;
|
||||
}
|
||||
in_order(self, x->right, apply, args);
|
||||
}
|
||||
}
|
||||
|
||||
void drv_rbtree_inorder(drv_rbtree_t* self
|
||||
, int (*apply)(drv_rbtree_t* tree, drv_rbtree_node_t* x, void* args), void* args){
|
||||
in_order(self, self->root, apply, args);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#ifndef INCLUDED_DRV_RBTREE_H
|
||||
#define INCLUDED_DRV_RBTREE_H
|
||||
|
||||
#ifndef INCLUDED_OS_TYPES_H
|
||||
#include <os_types.h>
|
||||
#endif /*INCLUDED_OS_TYPES_H*/
|
||||
|
||||
#ifndef INCLUDED_OS_MACROS_H
|
||||
#include <os_macros.h>
|
||||
#endif /*INCLUDED_OS_MACROS_H*/
|
||||
|
||||
#ifndef INCLUDED_OS_COMPILER_H
|
||||
#include <os_compiler.h>
|
||||
#endif /*INCLUDED_OS_COMPILER_H*/
|
||||
|
||||
#ifndef INCLUDED_POOL_H
|
||||
#include <pool.h>
|
||||
#endif /*INCLUDED_POOL_H*/
|
||||
|
||||
#ifndef INCLUDED_DRV_DEVICE_H
|
||||
#include <drv_device.h>
|
||||
#endif /*INCLUDED_DRV_DEVICE_H*/
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
typedef struct drv_rbtree_node_s{
|
||||
struct drv_rbtree_node_s* left;
|
||||
struct drv_rbtree_node_s* right;
|
||||
struct drv_rbtree_node_s* parent;
|
||||
char color;
|
||||
drv_device_t device;
|
||||
}drv_rbtree_node_t;
|
||||
|
||||
typedef struct {
|
||||
drv_rbtree_node_t* root;
|
||||
pool_t node_pool;
|
||||
}drv_rbtree_t;
|
||||
|
||||
#define DRV_RBTREE_NODE_SIZE sizeof(drv_rbtree_node_t)
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
// 初始化时指定一个 node 的对象池,最大只能容纳这些 node
|
||||
void drv_rbtree_init(drv_rbtree_t* self, void* node_block, os_size_t node_block_size);
|
||||
void drv_rbtree_add_node_pool(drv_rbtree_t* self, void* node_block, os_size_t node_block_size);
|
||||
void drv_rbtree_destroy(drv_rbtree_t* self);
|
||||
drv_rbtree_node_t* drv_rbtree_find(drv_rbtree_t* self, const char* name);
|
||||
drv_rbtree_node_t* drv_rbtree_custom_find(drv_rbtree_t* self, const char* name
|
||||
, drv_rbtree_node_t* (*custom_find)(drv_rbtree_t* tree, const char* name, drv_rbtree_node_t* x, void* args)
|
||||
, void* args);
|
||||
os_err_t drv_rbtree_insert(drv_rbtree_t* self, drv_device_t* device);
|
||||
void drv_rbtree_remove(drv_rbtree_t* self, const char* name);
|
||||
void drv_rbtree_remove_node(drv_rbtree_t* self, drv_rbtree_node_t* x);
|
||||
void drv_rbtree_inorder(drv_rbtree_t* self
|
||||
, int (*apply)(drv_rbtree_t* tree, drv_rbtree_node_t* x, void* args), void* args);
|
||||
|
||||
|
||||
#endif /*INCLUDED_DRV_RBTREE_H*/
|
||||
@@ -0,0 +1 @@
|
||||
#include <drv_softi2c.h>
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef INCLUDED_DRV_SOFTI2C_H
|
||||
#define INCLUDED_DRV_SOFTI2C_H
|
||||
|
||||
#ifndef INCLUDED_DRV_DEVICE_H
|
||||
#include <drv_device.h>
|
||||
#endif /*INCLUDED_DRV_DEVICE_H*/
|
||||
|
||||
typedef struct drv_softi2c_t drv_softi2c_t;
|
||||
|
||||
struct drv_softi2c_t{
|
||||
drv_device_t root;
|
||||
os_uint_t scl_clock;
|
||||
void* scl_port;
|
||||
os_uint_t scl_pin;
|
||||
os_uint_t sda_clock;
|
||||
void* sda_port;
|
||||
os_uint_t sda_pin;
|
||||
os_err_t (*put)(drv_softi2c_t* self, const uint8_t data);
|
||||
os_err_t (*get)(drv_softi2c_t* self, uint8_t* data);
|
||||
};
|
||||
|
||||
#define drv_softi2c_start(dev) drv_device_open(dev)
|
||||
#define drv_softi2c_stop(dev) drv_device_close(dev)
|
||||
#define drv_softi2c_put(dev, data) (dev)->put((drv_softi2c_t*)(dev)->handle, data)
|
||||
#define drv_softi2c_get(dev, data) (dev)->get((drv_softi2c_t*)(dev)->handle, data)
|
||||
|
||||
|
||||
|
||||
#endif /*INCLUDED_DRV_SOFTI2C_H*/
|
||||
Reference in New Issue
Block a user