加入状态机

This commit is contained in:
2026-06-05 23:18:54 +08:00
parent 2b6c701a6a
commit efffc5ec9c
6 changed files with 297 additions and 0 deletions
+1
View File
@@ -48,6 +48,7 @@ void fifo_clear(fifo_t* self){
self->read_idx = self->write_idx = 0; self->read_idx = self->write_idx = 0;
} }
OS_STATIC_FORCE_INLINE OS_STATIC_FORCE_INLINE
os_bool_t fifo_is_empty(fifo_t* self){ os_bool_t fifo_is_empty(fifo_t* self){
return (self->write_idx==self->read_idx); return (self->write_idx==self->read_idx);
+1
View File
@@ -0,0 +1 @@
#include <gai_action.h>
+81
View File
@@ -0,0 +1,81 @@
#ifndef INCLUDED_GAI_ACTION_H
#define INCLUDED_GAI_ACTION_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*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef struct gai_action_t gai_action_t;
typedef void (*gai_action_function_t)(gai_action_t* self);
typedef void (*gai_action_update_function_t)(gai_action_t* self, void* params);
typedef enum {
kGaiActionStatus_UnInitialized=0,
kGaiActionStatus_Running,
kGaiActionStatus_Terminated,
}gai_action_status_t;
struct gai_action_t{
gai_action_status_t status;
gai_action_function_t onInitialize;
gai_action_update_function_t onUpdate;
gai_action_function_t onCleanup;
void* userdata;
};
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
OS_STATIC_FORCE_INLINE
void gai_action_init(gai_action_t* self,
gai_action_function_t onInitialize,
gai_action_update_function_t onUpdate,
gai_action_function_t onCleanup, void* userdata){
self->status = kGaiActionStatus_UnInitialized;
self->onInitialize = onInitialize;
self->onUpdate = onUpdate;
self->onCleanup = onCleanup;
self->userdata = userdata;
}
OS_STATIC_FORCE_INLINE
void gai_action_Initialize(gai_action_t* self){
if(self->onInitialize){
self->onInitialize(self);
}
self->status = kGaiActionStatus_Running;
}
OS_STATIC_FORCE_INLINE
gai_action_status_t gai_action_Update(gai_action_t* self, void* userdata){
if(self->status==kGaiActionStatus_Terminated){
return kGaiActionStatus_Terminated;
}
if(self->onUpdate){
self->onUpdate(self, userdata);
}else{
self->status = kGaiActionStatus_Terminated;
}
return self->status;
}
OS_STATIC_FORCE_INLINE
void gai_action_Cleanup(gai_action_t* self){
if(self->status == kGaiActionStatus_Terminated){
if(self->onCleanup){
self->onCleanup(self);
}
}
self->status = kGaiActionStatus_UnInitialized;
}
#endif /*INCLUDED_GAI_ACTION_H*/
+31
View File
@@ -0,0 +1,31 @@
#include <gai_fsm.h>
static os_int_t FindNextState(gai_fsm_t* self, os_list_t* transitions, void* ud){
os_list_node_t * p_node = 0;
for(p_node = transitions->next; p_node!=transitions; p_node= p_node->next){
gai_fsm_transition_t* p_transition = os_list_member_of(p_node, gai_fsm_transition_t, node);
if(p_transition->evaluator(self, p_transition, ud)){
return p_transition->to_state_id;
}
}
return -1;
}
void gai_fsm_update(gai_fsm_t* self, void* userdata){
if(!self->current_state_p){
return;
}
gai_action_status_t status = gai_fsm_status(self);
if(status==kGaiActionStatus_Running){
gai_action_Update(&self->current_state_p->action, userdata);
}else if(status==kGaiActionStatus_Terminated){
os_int_t to_state_id = FindNextState(self, &self->current_state_p->transition_list, userdata);
gai_fsm_state_t* p_next_state = gai_fsm_find_state(self, to_state_id);
if(p_next_state){
gai_action_Cleanup(&self->current_state_p->action);
self->current_state_p = p_next_state;
gai_action_Initialize(&self->current_state_p->action);
}
}
}
+180
View File
@@ -0,0 +1,180 @@
#ifndef INCLUDED_GAI_FSM_H
#define INCLUDED_GAI_FSM_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_LIST_H
#include <os_list.h>
#endif /*INCLUDED_OS_LIST_H*/
#ifndef INCLUDED_GAI_ACTION_H
#include <gai_action.h>
#endif /*INCLUDED_GAI_ACTION_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef struct gai_fsm_state_t gai_fsm_state_t;
typedef struct gai_fsm_transition_t gai_fsm_transition_t;
typedef struct gai_fsm_t gai_fsm_t;
typedef os_bool_t (*gai_fsm_evaluator_t)(gai_fsm_t* self, gai_fsm_transition_t* transition, void* ud);
struct gai_fsm_state_t{
os_list_node_t node;
os_int_t id;
os_list_t transition_list;
gai_action_t action;
};
struct gai_fsm_transition_t{
os_list_node_t node;
os_int_t from_state_id;
os_int_t to_state_id;
gai_fsm_evaluator_t evaluator;
void* userdata;
};
struct gai_fsm_t{
gai_fsm_state_t* current_state_p;
os_list_t state_list;
void* userdata;
};
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
OS_STATIC_FORCE_INLINE
void gai_fsm_init(gai_fsm_t* self, void* userdata){
self->current_state_p = 0;
os_list_init(&self->state_list);
self->userdata = userdata;
}
OS_STATIC_FORCE_INLINE
void gai_fsm_add_state(gai_fsm_t* self, gai_fsm_state_t * state){
os_list_insert_after(&self->state_list, &state->node);
}
OS_STATIC_FORCE_INLINE
void gai_fsm_add_transition(gai_fsm_t* self, gai_fsm_transition_t* transition){
os_list_node_t* p_node;
for(p_node = self->state_list.next; p_node!=&self->state_list; p_node = p_node->next){
gai_fsm_state_t* p_state = os_list_member_of(p_node, gai_fsm_state_t, node);
if(transition->from_state_id != p_state->id){
continue;
}
os_list_insert_after(&p_state->transition_list, &transition->node);
break;
}
}
OS_STATIC_FORCE_INLINE
gai_action_status_t gai_fsm_status(gai_fsm_t* self){
if(self->current_state_p){
return self->current_state_p->action.status;
}
return kGaiActionStatus_UnInitialized;
}
OS_STATIC_FORCE_INLINE
gai_fsm_transition_t* gai_fsm_find_transition(gai_fsm_t* self, os_int_t from_state_id, os_int_t to_state_id){
gai_fsm_state_t * p_from_state = 0;
os_list_node_t* p_node;
for(p_node = self->state_list.next; p_node!=&self->state_list; p_node = p_node->next){
gai_fsm_state_t* p_state = os_list_member_of(p_node, gai_fsm_state_t, node);
if(p_state->id==from_state_id){
p_from_state = p_state;
break;
}
}
if(p_from_state==0){
return 0;
}
for(p_node = p_from_state->transition_list.next; p_node!=&p_from_state->transition_list; p_node= p_node->next){
gai_fsm_transition_t* p_transition = os_list_member_of(p_node, gai_fsm_transition_t, node);
if(p_transition->to_state_id == to_state_id){
return p_transition;
}
}
return 0;
}
OS_STATIC_FORCE_INLINE
gai_fsm_state_t* gai_fsm_find_state(gai_fsm_t* self, os_int_t state_id){
os_list_node_t* p_node;
for(p_node = self->state_list.next; p_node!=&self->state_list; p_node = p_node->next){
gai_fsm_state_t* p_state = os_list_member_of(p_node, gai_fsm_state_t, node);
if(p_state->id==state_id){
return p_state;
}
}
return 0;
}
OS_STATIC_FORCE_INLINE
os_bool_t gai_fsm_has_transition(gai_fsm_t* self, os_int_t from_state_id, os_int_t to_state_id){
return (gai_fsm_find_transition(self, from_state_id, to_state_id)!=0)?OS_TRUE:OS_FALSE;
}
OS_STATIC_FORCE_INLINE
os_bool_t gai_fsm_has_state(gai_fsm_t* self, os_int_t state_id){
return (gai_fsm_find_state(self, state_id)!=0)?OS_TRUE:OS_FALSE;
}
OS_STATIC_FORCE_INLINE
void gai_fsm_set_state(gai_fsm_t* self, os_int_t state_id){
gai_fsm_state_t* p_state = gai_fsm_find_state(self, state_id);
if(p_state==0){
return;
}
gai_action_Cleanup(&p_state->action);
self->current_state_p = p_state;
gai_action_Initialize(&p_state->action);
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
OS_STATIC_FORCE_INLINE
void gai_fsm_state_init(gai_fsm_state_t* self, os_int_t id,
gai_action_function_t onInitialize,
gai_action_update_function_t onUpdate,
gai_action_function_t onCleanup, void* userdata){
os_list_init(&self->node);
self->id = id;
os_list_init(&self->transition_list);
gai_action_init(&self->action, onInitialize, onUpdate, onCleanup, userdata);
}
OS_STATIC_FORCE_INLINE
void gai_fsm_transition_init(gai_fsm_transition_t* self,
os_int_t from_state_id,
os_int_t to_state_id,
gai_fsm_evaluator_t evaluator,
void* userdata){
self->evaluator = evaluator;
self->from_state_id = from_state_id;
self->to_state_id = to_state_id;
os_list_init(&self->node);
self->userdata = userdata;
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
void gai_fsm_update(gai_fsm_t* self, void* userdata);
#endif /*INCLUDED_GAI_FSM_H*/
+3
View File
@@ -69,10 +69,13 @@ void os_systick_tick(void){
OS_STATIC_FORCE_INLINE OS_STATIC_FORCE_INLINE
os_tick_t os_systick_get(void){ os_tick_t os_systick_get(void){
#if 0
os_critical_enter(); os_critical_enter();
os_tick_t ticks = g_os_systick_ticks; os_tick_t ticks = g_os_systick_ticks;
os_critical_leave(); os_critical_leave();
return ticks; return ticks;
#endif
return g_os_systick_ticks;
} }