@@ -0,0 +1,125 @@
|
||||
// Copyright (2025) Beijing Volcano Engine Technology Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifndef AIOS_H_
|
||||
#define AIOS_H_
|
||||
|
||||
/* include ------------------------------------------------------------------ */
|
||||
#include "aios_config.h"
|
||||
#include "volc_list.h"
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* default configuration ---------------------------------------------------- */
|
||||
|
||||
#ifndef AIOS_MAX_ACTORS
|
||||
#define AIOS_MAX_ACTORS 8 // 默认最多8个Actor
|
||||
#endif
|
||||
|
||||
#ifndef AIOS_USE_ASSERT
|
||||
#define AIOS_USE_ASSERT 1 // 默认打开断言
|
||||
#endif
|
||||
|
||||
|
||||
#include "aios_def.h"
|
||||
|
||||
/* data struct -------------------------------------------------------------- */
|
||||
|
||||
// 状态返回值的定义
|
||||
typedef enum aios_ret {
|
||||
AIOS_Ret_Null = 0, // 无效值
|
||||
AIOS_Ret_Handled, // 已处理,不产生跳转
|
||||
AIOS_Ret_NotHandled, // 未处理,不产生跳转
|
||||
AIOS_Ret_Tran, // 跳转
|
||||
} aios_ret_t;
|
||||
|
||||
// 事件类
|
||||
struct aios_event;
|
||||
typedef void (*aios_event_free_handler)(const void *data);
|
||||
typedef struct aios_event {
|
||||
volc_list_head_t node;
|
||||
uint32_t sub; // 订阅者
|
||||
aios_event_id_t id; // 事件主题
|
||||
void *data; // 事件数据
|
||||
aios_event_free_handler free_handler; // 事件数据释放函数
|
||||
} aios_event_t;
|
||||
|
||||
// 数据结构 - 行为树相关 --------------------------------------------------------
|
||||
// 状态函数句柄的定义
|
||||
struct aios_session;
|
||||
typedef aios_ret_t (* aios_state_handler)(struct aios_session *const me, aios_event_t const * const e);
|
||||
|
||||
// 状态机类
|
||||
typedef struct aios_session {
|
||||
uint32_t priority : 5; // 优先级,0-31,数值越大优先级越高
|
||||
uint32_t enabled : 1; // 是否使能
|
||||
uint32_t reserve : 1; // 保留位
|
||||
volatile aios_state_handler state;
|
||||
} aios_session_t;
|
||||
|
||||
// api -------------------------------------------------------------------------
|
||||
// 对框架进行初始化,在各状态机初始化之前调用。
|
||||
void aios_init(int event_size);
|
||||
// 启动框架,放在main函数的末尾。
|
||||
void aios_run(void);
|
||||
// 停止框架的运行(不常用)
|
||||
// 停止框架后,框架会在执行完当前状态机的当前事件后,清空各状态机事件队列,清空事件池,
|
||||
// 不再执行任何功能,直至框架被再次启动。
|
||||
void aios_stop(void);
|
||||
|
||||
// 关于状态机 -----------------------------------------------
|
||||
// 状态机初始化函数
|
||||
void aios_session_init( aios_session_t * const me,
|
||||
uint8_t priority,
|
||||
void const * const parameter);
|
||||
void aios_session_start(aios_session_t * const me, aios_state_handler state_init);
|
||||
|
||||
aios_ret_t aios_tran(aios_session_t * const me, aios_state_handler state);
|
||||
|
||||
#define AIOS_TRAN(target) aios_tran((aios_session_t * )me, (aios_state_handler)target)
|
||||
#define AIOS_STATE_CAST(state) ((aios_state_handler)(state))
|
||||
|
||||
// 关于事件 -------------------------------------------------
|
||||
// 事件订阅
|
||||
void aios_event_sub(aios_session_t * const me, aios_event_id_t id);
|
||||
// 事件取消订阅
|
||||
void aios_event_unsub(aios_session_t * const me, aios_event_id_t id);
|
||||
// 事件订阅宏定义
|
||||
#define AIOS_EVENT_SUB(_evt) aios_event_sub(&(me->super), _evt)
|
||||
// 事件取消订阅宏定义
|
||||
#define AIOS_EVENT_UNSUB(_evt) aios_event_unsub(&(me->super), _evt)
|
||||
|
||||
// 发布事件(携带数据)
|
||||
int aios_event_pub(aios_event_id_t id, void *data, aios_event_free_handler free_handler);
|
||||
|
||||
// 发布周期性或延时事件
|
||||
void* aios_event_time_pub(aios_event_id_t id, uint32_t timeout_ms, uint32_t period_ms);
|
||||
|
||||
// 取消延时事件或者周期事件的发布
|
||||
void aios_event_time_cancel(void** timer);
|
||||
|
||||
/* port --------------------------------------------------------------------- */
|
||||
// void* aios_malloc(uint32_t size);
|
||||
// void aios_free(void* ptr);
|
||||
// void* aios_mutex_create(void);
|
||||
// void aios_mutex_lock(void* mutex);
|
||||
// void aios_mutex_unlock(void* mutex);
|
||||
// void aios_mutex_destroy(void** mutex);
|
||||
void aios_port_assert(uint32_t error_id);
|
||||
|
||||
/* hook --------------------------------------------------------------------- */
|
||||
|
||||
// 结束AIOS Nano的运行的时候,所调用的回调函数。
|
||||
void aios_hook_stop(void);
|
||||
|
||||
// 启动AIOS Nano的时候,所调用的回调函数
|
||||
void aios_hook_start(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright (2025) Beijing Volcano Engine Technology Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifndef AIOS_CONFIG_H__
|
||||
#define AIOS_CONFIG_H__
|
||||
|
||||
/* AIOS General Configuration --------------------------------------- */
|
||||
#define AIOS_MCU_TYPE 32
|
||||
#define AIOS_MAX_ACTORS 4
|
||||
#define AIOS_TEST_PLATFORM 64
|
||||
#define AIOS_USE_MAGIC 0
|
||||
|
||||
/* Assert Configuration ----------------------------------------------------- */
|
||||
#define AIOS_USE_ASSERT 1
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
// Copyright (2025) Beijing Volcano Engine Technology Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifndef AIOS_DEF_H__
|
||||
#define AIOS_DEF_H__
|
||||
|
||||
#include "aios_config.h"
|
||||
|
||||
#define AIOS_MAX_SLEEP_MS (1000 * 10)
|
||||
|
||||
typedef enum aios_event_id {
|
||||
// 系统事件
|
||||
Event_Null = 0,
|
||||
Event_Enter,
|
||||
Event_Exit,
|
||||
// 用户事件
|
||||
Event_User,
|
||||
} aios_event_id_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
/* Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UV_SRC_HEAP_H_
|
||||
#define UV_SRC_HEAP_H_
|
||||
|
||||
#include <stddef.h> /* NULL */
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define HEAP_EXPORT(declaration) __attribute__((unused)) static declaration
|
||||
#else
|
||||
# define HEAP_EXPORT(declaration) static declaration
|
||||
#endif
|
||||
|
||||
struct heap_node {
|
||||
struct heap_node* left;
|
||||
struct heap_node* right;
|
||||
struct heap_node* parent;
|
||||
};
|
||||
|
||||
/* A binary min heap. The usual properties hold: the root is the lowest
|
||||
* element in the set, the height of the tree is at most log2(nodes) and
|
||||
* it's always a complete binary tree.
|
||||
*
|
||||
* The heap function try hard to detect corrupted tree nodes at the cost
|
||||
* of a minor reduction in performance. Compile with -DNDEBUG to disable.
|
||||
*/
|
||||
struct heap {
|
||||
struct heap_node* min;
|
||||
unsigned int nelts;
|
||||
};
|
||||
|
||||
/* Return non-zero if a < b. */
|
||||
typedef int (*heap_compare_fn)(const struct heap_node* a,
|
||||
const struct heap_node* b);
|
||||
|
||||
/* Public functions. */
|
||||
HEAP_EXPORT(void heap_init(struct heap* heap));
|
||||
HEAP_EXPORT(struct heap_node* heap_min(const struct heap* heap));
|
||||
HEAP_EXPORT(void heap_insert(struct heap* heap,
|
||||
struct heap_node* newnode,
|
||||
heap_compare_fn less_than));
|
||||
HEAP_EXPORT(void heap_remove(struct heap* heap,
|
||||
struct heap_node* node,
|
||||
heap_compare_fn less_than));
|
||||
HEAP_EXPORT(void heap_dequeue(struct heap* heap, heap_compare_fn less_than));
|
||||
|
||||
/* Implementation follows. */
|
||||
|
||||
HEAP_EXPORT(void heap_init(struct heap* heap)) {
|
||||
heap->min = NULL;
|
||||
heap->nelts = 0;
|
||||
}
|
||||
|
||||
HEAP_EXPORT(void heap_node_init(struct heap_node* hnode)) {
|
||||
hnode->left = 0;
|
||||
hnode->parent = 0;
|
||||
hnode->right = 0;
|
||||
}
|
||||
|
||||
HEAP_EXPORT(int heap_node_is_empty(struct heap_node* hnode)) {
|
||||
return (hnode->left == 0 && hnode->parent == 0 && hnode->right == 0);
|
||||
}
|
||||
|
||||
HEAP_EXPORT(struct heap_node* heap_min(const struct heap* heap)) {
|
||||
return heap->min;
|
||||
}
|
||||
|
||||
/* Swap parent with child. Child moves closer to the root, parent moves away. */
|
||||
static void heap_node_swap(struct heap* heap,
|
||||
struct heap_node* parent,
|
||||
struct heap_node* child) {
|
||||
struct heap_node* sibling;
|
||||
struct heap_node t;
|
||||
|
||||
t = *parent;
|
||||
*parent = *child;
|
||||
*child = t;
|
||||
|
||||
parent->parent = child;
|
||||
if (child->left == child) {
|
||||
child->left = parent;
|
||||
sibling = child->right;
|
||||
} else {
|
||||
child->right = parent;
|
||||
sibling = child->left;
|
||||
}
|
||||
if (sibling != NULL)
|
||||
sibling->parent = child;
|
||||
|
||||
if (parent->left != NULL)
|
||||
parent->left->parent = parent;
|
||||
if (parent->right != NULL)
|
||||
parent->right->parent = parent;
|
||||
|
||||
if (child->parent == NULL)
|
||||
heap->min = child;
|
||||
else if (child->parent->left == parent)
|
||||
child->parent->left = child;
|
||||
else
|
||||
child->parent->right = child;
|
||||
}
|
||||
|
||||
HEAP_EXPORT(void heap_insert(struct heap* heap,
|
||||
struct heap_node* newnode,
|
||||
heap_compare_fn less_than)) {
|
||||
struct heap_node** parent;
|
||||
struct heap_node** child;
|
||||
unsigned int path;
|
||||
unsigned int n;
|
||||
unsigned int k;
|
||||
|
||||
newnode->left = NULL;
|
||||
newnode->right = NULL;
|
||||
newnode->parent = NULL;
|
||||
|
||||
/* Calculate the path from the root to the insertion point. This is a min
|
||||
* heap so we always insert at the left-most free node of the bottom row.
|
||||
*/
|
||||
path = 0;
|
||||
for (k = 0, n = 1 + heap->nelts; n >= 2; k += 1, n /= 2)
|
||||
path = (path << 1) | (n & 1);
|
||||
|
||||
/* Now traverse the heap using the path we calculated in the previous step. */
|
||||
parent = child = &heap->min;
|
||||
while (k > 0) {
|
||||
parent = child;
|
||||
if (path & 1)
|
||||
child = &(*child)->right;
|
||||
else
|
||||
child = &(*child)->left;
|
||||
path >>= 1;
|
||||
k -= 1;
|
||||
}
|
||||
|
||||
/* Insert the new node. */
|
||||
newnode->parent = *parent;
|
||||
*child = newnode;
|
||||
heap->nelts += 1;
|
||||
|
||||
/* Walk up the tree and check at each node if the heap property holds.
|
||||
* It's a min heap so parent < child must be true.
|
||||
*/
|
||||
while (newnode->parent != NULL && less_than(newnode, newnode->parent))
|
||||
heap_node_swap(heap, newnode->parent, newnode);
|
||||
}
|
||||
|
||||
HEAP_EXPORT(void heap_remove(struct heap* heap,
|
||||
struct heap_node* node,
|
||||
heap_compare_fn less_than)) {
|
||||
struct heap_node* smallest;
|
||||
struct heap_node** max;
|
||||
struct heap_node* child;
|
||||
unsigned int path;
|
||||
unsigned int k;
|
||||
unsigned int n;
|
||||
|
||||
if (heap->nelts == 0)
|
||||
return;
|
||||
|
||||
/* Calculate the path from the min (the root) to the max, the left-most node
|
||||
* of the bottom row.
|
||||
*/
|
||||
path = 0;
|
||||
for (k = 0, n = heap->nelts; n >= 2; k += 1, n /= 2)
|
||||
path = (path << 1) | (n & 1);
|
||||
|
||||
/* Now traverse the heap using the path we calculated in the previous step. */
|
||||
max = &heap->min;
|
||||
while (k > 0) {
|
||||
if (path & 1)
|
||||
max = &(*max)->right;
|
||||
else
|
||||
max = &(*max)->left;
|
||||
path >>= 1;
|
||||
k -= 1;
|
||||
}
|
||||
|
||||
heap->nelts -= 1;
|
||||
|
||||
/* Unlink the max node. */
|
||||
child = *max;
|
||||
*max = NULL;
|
||||
|
||||
if (child == node) {
|
||||
/* We're removing either the max or the last node in the tree. */
|
||||
if (child == heap->min) {
|
||||
heap->min = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Replace the to be deleted node with the max node. */
|
||||
child->left = node->left;
|
||||
child->right = node->right;
|
||||
child->parent = node->parent;
|
||||
|
||||
if (child->left != NULL) {
|
||||
child->left->parent = child;
|
||||
}
|
||||
|
||||
if (child->right != NULL) {
|
||||
child->right->parent = child;
|
||||
}
|
||||
|
||||
if (node->parent == NULL) {
|
||||
heap->min = child;
|
||||
} else if (node->parent->left == node) {
|
||||
node->parent->left = child;
|
||||
} else {
|
||||
node->parent->right = child;
|
||||
}
|
||||
|
||||
/* Walk down the subtree and check at each node if the heap property holds.
|
||||
* It's a min heap so parent < child must be true. If the parent is bigger,
|
||||
* swap it with the smallest child.
|
||||
*/
|
||||
for (;;) {
|
||||
smallest = child;
|
||||
if (child->left != NULL && less_than(child->left, smallest))
|
||||
smallest = child->left;
|
||||
if (child->right != NULL && less_than(child->right, smallest))
|
||||
smallest = child->right;
|
||||
if (smallest == child)
|
||||
break;
|
||||
heap_node_swap(heap, child, smallest);
|
||||
}
|
||||
|
||||
/* Walk up the subtree and check that each parent is less than the node
|
||||
* this is required, because `max` node is not guaranteed to be the
|
||||
* actual maximum in tree
|
||||
*/
|
||||
while (child->parent != NULL && less_than(child, child->parent))
|
||||
heap_node_swap(heap, child->parent, child);
|
||||
}
|
||||
|
||||
HEAP_EXPORT(void heap_dequeue(struct heap* heap, heap_compare_fn less_than)) {
|
||||
heap_remove(heap, heap->min, less_than);
|
||||
}
|
||||
|
||||
#undef HEAP_EXPORT
|
||||
|
||||
#endif /* UV_SRC_HEAP_H_ */
|
||||
@@ -0,0 +1,79 @@
|
||||
// Copyright (2025) Beijing Volcano Engine Technology Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifndef __CONV_AI_SRC_UTIL_VOLC_LIST_H__
|
||||
#define __CONV_AI_SRC_UTIL_VOLC_LIST_H__
|
||||
|
||||
// #include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef struct volc_list_head_t
|
||||
{
|
||||
struct volc_list_head_t *next, *prev;
|
||||
} volc_list_head_t;
|
||||
|
||||
#define __LIST_ADD(entry, before, after) \
|
||||
{ \
|
||||
volc_list_head_t *new_ = (entry), *prev = (before), *next = (after); \
|
||||
(next)->prev = (new_); \
|
||||
(new_)->next = (next); \
|
||||
(new_)->prev = (prev); \
|
||||
(prev)->next = (new_); \
|
||||
}
|
||||
#define volc_list_init(entry) \
|
||||
do \
|
||||
{ \
|
||||
(entry)->next = (entry); \
|
||||
(entry)->prev = (entry); \
|
||||
} while (0)
|
||||
#define volc_list_add(entry, base) \
|
||||
do \
|
||||
{ \
|
||||
__LIST_ADD((entry), (base), (base)->next); \
|
||||
} while (0)
|
||||
#define volc_list_add_after(entry, base) \
|
||||
do \
|
||||
{ \
|
||||
__LIST_ADD((entry), (base), (base)->next); \
|
||||
} while (0)
|
||||
#define volc_list_add_before(entry, base) \
|
||||
do \
|
||||
{ \
|
||||
__LIST_ADD((entry), (base)->prev, (base)); \
|
||||
} while (0)
|
||||
#define volc_list_add_head(entry, head) volc_list_add_after(entry, head)
|
||||
#define volc_list_add_tail(entry, head) volc_list_add_before(entry, head)
|
||||
#define volc_list_del(entry) \
|
||||
do \
|
||||
{ \
|
||||
(entry)->prev->next = (entry)->next; \
|
||||
(entry)->next->prev = (entry)->prev; \
|
||||
(entry)->next = (entry)->prev = (entry); \
|
||||
} while (0)
|
||||
#define volc_list_empty(head) ((head)->next == (head))
|
||||
#define volc_list_get_head(head) (volc_list_empty(head) ? (volc_list_head_t *)NULL : (head)->next)
|
||||
#define volc_list_get_tail(head) (volc_list_empty(head) ? (volc_list_head_t *)NULL : (head)->prev)
|
||||
#define volc_list_is_head(entry, head) ((entry)->prev == head)
|
||||
#define volc_list_is_tail(entry, head) ((entry)->next == head)
|
||||
#define volc_list_entry(ptr, type, member) ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
|
||||
#define volc_list_for_each(h, head) for (h = (head)->next; h != (head); h = h->next)
|
||||
#define volc_list_for_each_safe(h, n, head) for (h = (head)->next, n = h->next; h != (head); h = n, n = h->next)
|
||||
#define volc_list_for_each_entry(p, head, type, member) \
|
||||
for (p = volc_list_entry((head)->next, type, member); &p->member != (head); \
|
||||
p = volc_list_entry(p->member.next, type, member))
|
||||
#define volc_list_for_each_entry_safe(p, t, head, type, member) \
|
||||
for (p = volc_list_entry((head)->next, type, member), t = volc_list_entry(p->member.next, type, member); \
|
||||
&p->member != (head); p = t, t = volc_list_entry(t->member.next, type, member))
|
||||
#define volc_list_get_head_entry(head, type, member) \
|
||||
(volc_list_empty(head) ? (type *)NULL : volc_list_entry(((head)->next), type, member))
|
||||
#define volc_list_get_tail_entry(head, type, member) \
|
||||
(volc_list_empty(head) ? (type *)NULL : volc_list_entry(((head)->prev), type, member))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* #define __CONV_AI_SRC_UTIL_VOLC_LIST_H__ */
|
||||
Reference in New Issue
Block a user