add event-driven framework
see examples/event_driven_at_module and examples/event_driven_hello_world, demo project: TencentOS-tiny\board\TencentOS_tiny_EVB_MX\KEIL\event_driven_hello_world
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
#define __PURE__ __attribute__((__pure__))
|
||||
#define __CONST__ __attribute__((__const__))
|
||||
#define __NO_RETURN__ __attribute__((__noreturn__))
|
||||
#define __WEAK__ __attribute__((weak))
|
||||
|
||||
/*------------------ ARM Compiler V6 -------------------*/
|
||||
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
@@ -61,7 +62,7 @@
|
||||
#define __CONST__ __attribute__((__const__))
|
||||
#define __NO_RETURN__ __attribute__((__noreturn__))
|
||||
#define __NAKED__ __attribute__((naked))
|
||||
|
||||
#define __WEAK__ __attribute__((weak))
|
||||
/*------------------ ICC Compiler ----------------------*/
|
||||
#elif defined(__ICCARM__)
|
||||
|
||||
@@ -82,6 +83,8 @@
|
||||
#define __CONST__
|
||||
#define __NO_RETURN__
|
||||
#define __NAKED__
|
||||
#define __WEAK__ __weak
|
||||
|
||||
|
||||
/*------------------ GNU Compiler ----------------------*/
|
||||
#elif defined(__GNUC__)
|
||||
@@ -103,6 +106,7 @@
|
||||
#define __CONST__ __attribute__((__const__))
|
||||
#define __NO_RETURN__ __attribute__((__noreturn__))
|
||||
#define __NAKED__ __attribute__((naked))
|
||||
#define __WEAK__ __attribute__((weak))
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -1,6 +1,18 @@
|
||||
#ifndef _TOS_CONFIG_CHECK_H_
|
||||
#define _TOS_CONFIG_CHECK_H_
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN == 0u
|
||||
#error "INVALID config, must enable tos_mmheap to use event-driven"
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_TICKLESS_EN == 1u
|
||||
#error "INVALID config, tickless not supported in event-driven yet"
|
||||
#endif
|
||||
|
||||
#else /* TOS_CFG_EVENT_DRIVEN_EN */
|
||||
|
||||
#if TOS_CFG_TASK_PRIO_MAX < 8u
|
||||
#error "INVALID config, TOS_CFG_TASK_PRIO_MAX must be >= 8"
|
||||
#endif
|
||||
@@ -57,5 +69,7 @@
|
||||
#error "INVALID config, TOS_CFG_CPU_DATA_SIZE"
|
||||
#endif
|
||||
|
||||
#endif /* _TOS_CHECK_CONFIG_H_ */
|
||||
#endif /* TOS_CFG_EVENT_DRIVEN_EN */
|
||||
|
||||
#endif /* _TOS_CONFIG_CHECK_H_ */
|
||||
|
||||
|
@@ -1,6 +1,136 @@
|
||||
#ifndef _TOS_CONFIG_DEFAULT_H_
|
||||
#define _TOS_CONFIG_DEFAULT_H_
|
||||
|
||||
#ifndef TOS_CFG_EVENT_DRIVEN_EN
|
||||
#define TOS_CFG_EVENT_DRIVEN_EN 0u
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
/////////////////////////////////////////
|
||||
// disable round robin
|
||||
#ifdef TOS_CFG_ROUND_ROBIN_EN
|
||||
#undef TOS_CFG_ROUND_ROBIN_EN
|
||||
#endif
|
||||
#define TOS_CFG_ROUND_ROBIN_EN 0u
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// disable event
|
||||
#ifdef TOS_CFG_EVENT_EN
|
||||
#undef TOS_CFG_EVENT_EN
|
||||
#endif
|
||||
#define TOS_CFG_EVENT_EN 0u
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// disable mutex
|
||||
#ifdef TOS_CFG_MUTEX_EN
|
||||
#undef TOS_CFG_MUTEX_EN
|
||||
#endif
|
||||
#define TOS_CFG_MUTEX_EN 0u
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// disable queue
|
||||
#ifdef TOS_CFG_QUEUE_EN
|
||||
#undef TOS_CFG_QUEUE_EN
|
||||
#endif
|
||||
#define TOS_CFG_QUEUE_EN 0u
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// disable semaphore
|
||||
#ifdef TOS_CFG_SEM_EN
|
||||
#undef TOS_CFG_SEM_EN
|
||||
#endif
|
||||
#define TOS_CFG_SEM_EN 0u
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// disable the "traditional" timer
|
||||
#ifdef TOS_CFG_TIMER_EN
|
||||
#undef TOS_CFG_TIMER_EN
|
||||
#endif
|
||||
#define TOS_CFG_TIMER_EN 0u
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// disable stack draught depth detact
|
||||
#ifdef TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN
|
||||
#undef TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN
|
||||
#endif
|
||||
#define TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN 0u
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// enable mmheap
|
||||
#ifndef TOS_CFG_MMHEAP_EN
|
||||
#define TOS_CFG_MMHEAP_EN 1u
|
||||
#endif
|
||||
|
||||
#if (TOS_CFG_MMHEAP_EN > 0u) && !defined(TOS_CFG_MMHEAP_POOL_SIZE)
|
||||
#define TOS_CFG_MMHEAP_POOL_SIZE 0x1000
|
||||
#endif
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// disable default
|
||||
#ifndef TOS_CFG_MMBLK_EN
|
||||
#define TOS_CFG_MMBLK_EN 0u
|
||||
#endif
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// disable default
|
||||
#ifndef TOS_CFG_FAULT_BACKTRACE_EN
|
||||
#define TOS_CFG_FAULT_BACKTRACE_EN 0u
|
||||
#endif
|
||||
/////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////
|
||||
#ifndef TOS_CFG_CPU_SYSTICK_PRIO
|
||||
#define TOS_CFG_CPU_SYSTICK_PRIO 0u
|
||||
#endif
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// disable default
|
||||
#ifndef TOS_CFG_PWR_MGR_EN
|
||||
#define TOS_CFG_PWR_MGR_EN 0u
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_TICKLESS_EN
|
||||
#define TOS_CFG_TICKLESS_EN 0u
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// we donot really need these, it's a compromise to the compiler.
|
||||
#ifndef TOS_CFG_TASK_PRIO_MAX
|
||||
#define TOS_CFG_TASK_PRIO_MAX 8u
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_IDLE_TASK_STK_SIZE
|
||||
#define TOS_CFG_IDLE_TASK_STK_SIZE 128u
|
||||
#endif
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
|
||||
#else /* TOS_CFG_EVENT_DRIVEN_EN */
|
||||
|
||||
#ifndef TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN
|
||||
#define TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN 0u
|
||||
#endif
|
||||
@@ -13,10 +143,6 @@
|
||||
#define TOS_CFG_EVENT_EN 0u
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_MMHEAP_EN
|
||||
#define TOS_CFG_MMHEAP_EN 0u
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_MUTEX_EN
|
||||
#define TOS_CFG_MUTEX_EN 0u
|
||||
#endif
|
||||
@@ -29,6 +155,10 @@
|
||||
#define TOS_CFG_SEM_EN 0u
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_MMHEAP_EN
|
||||
#define TOS_CFG_MMHEAP_EN 0u
|
||||
#endif
|
||||
|
||||
#if (TOS_CFG_QUEUE_EN > 0u) && !defined(TOS_CFG_MSG_EN)
|
||||
#define TOS_CFG_MSG_EN 1u
|
||||
#elif (TOS_CFG_QUEUE_EN == 0u) && !defined(TOS_CFG_MSG_EN)
|
||||
@@ -76,7 +206,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_TASK_PRIO_MAX
|
||||
#define TOS_CFG_TASK_PRIO_MAX 10u
|
||||
#define TOS_CFG_TASK_PRIO_MAX 8u
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_MMBLK_EN
|
||||
@@ -110,5 +240,7 @@
|
||||
#define TOS_CFG_FAULT_BACKTRACE_EN 0u
|
||||
#endif
|
||||
|
||||
#endif /* TOS_CFG_EVENT_DRIVEN_EN */
|
||||
|
||||
#endif /* _TOS_CONFIG_DEFAULT_H_ */
|
||||
|
||||
|
16
kernel/evtdrv/include/tos_evtdrv.h
Normal file
16
kernel/evtdrv/include/tos_evtdrv.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef _TOS_EVTDRV_H_
|
||||
#define _TOS_EVTDRV_H_
|
||||
|
||||
#include "tos.h"
|
||||
#include "tos_evtdrv_err.h"
|
||||
#include "tos_evtdrv_types.h"
|
||||
#include "tos_evtdrv_event.h"
|
||||
#include "tos_evtdrv_msg.h"
|
||||
#include "tos_evtdrv_timer.h"
|
||||
#include "tos_evtdrv_task.h"
|
||||
#include "tos_evtdrv_tick.h"
|
||||
#include "tos_evtdrv_sys.h"
|
||||
#include "tos_evtdrv_global.h"
|
||||
|
||||
#endif
|
||||
|
20
kernel/evtdrv/include/tos_evtdrv_err.h
Normal file
20
kernel/evtdrv/include/tos_evtdrv_err.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef _TOS_EVTDRV_ERR_H_
|
||||
#define _TOS_EVTDRV_ERR_H_
|
||||
|
||||
typedef enum evtdrv_err_en {
|
||||
EVTDRV_ERR_NONE = 0x0u,
|
||||
EVTDRV_ERR_MEM_ALLOC_FAILED = 0x1u,
|
||||
EVTDRV_ERR_PTR_NULL = 0x2u,
|
||||
EVTDRV_ERR_MSG_BUSY = 0x3u,
|
||||
EVTDRV_ERR_TASK_INVALID = 0x4u,
|
||||
EVTDRV_ERR_MMHEAP_NOT_ENABLED = 0x5u,
|
||||
|
||||
EVTDRV_ERR_EVENT_INVALID = 0x10u,
|
||||
EVTDRV_ERR_EVENT_OVERFLOW = 0x11u,
|
||||
|
||||
EVTDRV_ERR_TIMER_ALREADY_EXIST = 0x20u,
|
||||
EVTDRV_ERR_TIMER_INACTIVE = 0x21u,
|
||||
} evtdrv_err_t;
|
||||
|
||||
#endif
|
||||
|
71
kernel/evtdrv/include/tos_evtdrv_event.h
Normal file
71
kernel/evtdrv/include/tos_evtdrv_event.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#ifndef _TOS_EVTDRV_EVENT_H_
|
||||
#define _TOS_EVTDRV_EVENT_H_
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
typedef uint16_t evtdrv_event_flag_t;
|
||||
typedef uint16_t evtdrv_event_nesting_t;
|
||||
|
||||
#define EVTDRV_SYS_EVENT_MASK (evtdrv_event_flag_t)(0x3 << (sizeof(evtdrv_event_flag_t) * 8 - 2))
|
||||
#define EVTDRV_USR_EVENT_MASK (evtdrv_event_flag_t)(~(EVTDRV_SYS_EVENT_MASK))
|
||||
|
||||
/* highest two bits are reserved for system event
|
||||
0x8000 init all tasks
|
||||
0x4000 msg received
|
||||
*/
|
||||
#define TOS_EVTDRV_EVENT_NONE (evtdrv_event_flag_t)0x0u
|
||||
#define TOS_EVTDRV_SYS_EVENT_INIT (evtdrv_event_flag_t)(0x2 << (sizeof(evtdrv_event_flag_t) * 8 - 2))
|
||||
#define TOS_EVTDRV_SYS_EVENT_MSG (evtdrv_event_flag_t)(0x1 << (sizeof(evtdrv_event_flag_t) * 8 - 2))
|
||||
|
||||
typedef struct evtdrv_event_st {
|
||||
evtdrv_event_flag_t flags;
|
||||
evtdrv_event_nesting_t nesting[sizeof(evtdrv_event_flag_t) * 8];
|
||||
} evtdrv_event_t;
|
||||
|
||||
/**
|
||||
* @brief Set event to the target task.
|
||||
* Set event to the target task, next time the target task is "scheduled", the task will handle the event.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] task_id id of the target task.
|
||||
* @param[in] event_flags the event flags set to the task
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #EVTDRV_ERR_TASK_INVALID task id is invalid.
|
||||
* @retval #EVTDRV_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ evtdrv_err_t tos_evtdrv_event_set(evtdrv_task_id_t task_id, evtdrv_event_flag_t event_flags);
|
||||
|
||||
/**
|
||||
* @brief Reset the event of the target task.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] task_id id of the target task.
|
||||
* @param[in] event_flags the event flags reset of the task
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #EVTDRV_ERR_TASK_INVALID task id is invalid.
|
||||
* @retval #EVTDRV_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ evtdrv_err_t tos_evtdrv_event_reset(evtdrv_task_id_t task_id, evtdrv_event_flag_t event_flags);
|
||||
|
||||
__KERNEL__ evtdrv_err_t evtdrv_event_init(void);
|
||||
|
||||
__KERNEL__ evtdrv_event_flag_t evtdrv_event_fetch(evtdrv_task_id_t *task_id);
|
||||
|
||||
__STATIC_INLINE__ evtdrv_bool_t evtdrv_event_is_usr(evtdrv_event_flag_t event_flag)
|
||||
{
|
||||
return event_flag & EVTDRV_USR_EVENT_MASK;
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ evtdrv_bool_t evtdrv_event_is_sys(evtdrv_event_flag_t event_flag)
|
||||
{
|
||||
return event_flag & EVTDRV_SYS_EVENT_MASK;
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_EVENT_DRIVEN_EN */
|
||||
|
||||
#endif /* _TOS_EVTDRV_EVENT_H_ */
|
||||
|
24
kernel/evtdrv/include/tos_evtdrv_global.h
Normal file
24
kernel/evtdrv/include/tos_evtdrv_global.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef _TOS_EVTDRV_GLOBAL_H_
|
||||
#define _TOS_EVTDRV_GLOBAL_H_
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
extern evtdrv_task_entry_t *evtdrv_task_table;
|
||||
extern evtdrv_ttb_sz_t evtdrv_task_table_size;
|
||||
|
||||
extern evtdrv_task_id_t evtdrv_curr_task;
|
||||
|
||||
extern evtdrv_event_t *evtdrv_events;
|
||||
|
||||
extern k_list_t evtdrv_msg_list;
|
||||
|
||||
extern k_list_t evtdrv_timer_list;
|
||||
|
||||
extern k_evtdrv_poll_t evtdrv_poll;
|
||||
|
||||
extern evtdrv_tick_t evtdrv_tick_count;
|
||||
|
||||
#endif /* TOS_CFG_EVENT_DRIVEN_EN */
|
||||
|
||||
#endif /* _TOS_EVTDRV_GLOBAL_H_ */
|
||||
|
69
kernel/evtdrv/include/tos_evtdrv_msg.h
Normal file
69
kernel/evtdrv/include/tos_evtdrv_msg.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#ifndef _TOS_EVTDRV_MSG_H_
|
||||
#define _TOS_EVTDRV_MSG_H_
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
typedef uint16_t evtdrv_msg_len_t;
|
||||
typedef uint8_t *evtdrv_msg_body_t;
|
||||
|
||||
typedef struct evtdrv_message_header_st {
|
||||
k_list_t list;
|
||||
evtdrv_task_id_t dst_task_id; // destination task id
|
||||
evtdrv_msg_len_t len;
|
||||
} evtdrv_msg_hdr_t;
|
||||
|
||||
#define EVTDRV_MSG_BODY2HDR(msg_body) ((evtdrv_msg_hdr_t *)((uint8_t *)msg_body - sizeof(evtdrv_msg_hdr_t)))
|
||||
#define EVTDRV_MSG_LEN(msg_len) (sizeof(evtdrv_msg_hdr_t) + msg_len)
|
||||
#define EVTDRV_MSG_HDR2BODY(msg_hdr) ((evtdrv_msg_body_t)((evtdrv_msg_hdr_t *)msg_hdr + 1))
|
||||
|
||||
/**
|
||||
* @brief Allocate a message body.
|
||||
* Allocate a message body as a payload to hold the message content.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] msg_len the length of the message payload.
|
||||
*
|
||||
* @return the message body allocated.
|
||||
* @retval #NULL allocate failed.
|
||||
* @retval #NO-NULL allocate successfully.
|
||||
*/
|
||||
__API__ evtdrv_msg_body_t tos_evtdrv_msg_alloc(evtdrv_msg_len_t msg_len);
|
||||
|
||||
/**
|
||||
* @brief Free a message body.
|
||||
*
|
||||
* @attention if you wanna free a message body, the message must be "dequeued"(already received by the target task)
|
||||
*
|
||||
* @param[in] msg_body message body to free.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #EVTDRV_ERR_PTR_NULL message body is NULL.
|
||||
* @retval #EVTDRV_ERR_MSG_BUSY message is still in the message queue(not received).
|
||||
* @retval #EVTDRV_ERR_NONE free successfully.
|
||||
*/
|
||||
__API__ evtdrv_err_t tos_evtdrv_msg_free(evtdrv_msg_body_t msg_body);
|
||||
|
||||
/**
|
||||
* @brief Send a message to the target task.
|
||||
*
|
||||
* @attention next time the target task should be "wakeup" by the event of TOS_EVTDRV_SYS_EVENT_MSG.
|
||||
*
|
||||
* @param[in] task_id id of the target task.
|
||||
* @param[in] msg_body message body to send.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #EVTDRV_ERR_PTR_NULL message body is NULL.
|
||||
* @retval #EVTDRV_ERR_TASK_INVALID target task id is invalid.
|
||||
* @retval #EVTDRV_ERR_NONE send successfully.
|
||||
*/
|
||||
__API__ evtdrv_err_t tos_evtdrv_msg_send(evtdrv_task_id_t dst_task_id, evtdrv_msg_body_t msg_body);
|
||||
|
||||
__API__ evtdrv_msg_body_t tos_evtdrv_msg_recv(void);
|
||||
|
||||
__KERNEL__ void evtdrv_msg_init(void);
|
||||
|
||||
#endif /* TOS_CFG_EVENT_DRIVEN_EN */
|
||||
|
||||
#endif /* _TOS_EVTDRV_MSG_H_ */
|
||||
|
37
kernel/evtdrv/include/tos_evtdrv_sys.h
Normal file
37
kernel/evtdrv/include/tos_evtdrv_sys.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef _TOS_EVTDRV_SYS_H_
|
||||
#define _TOS_EVTDRV_SYS_H_
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
typedef void (*k_evtdrv_poll_t)(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize the event-driven system.
|
||||
*
|
||||
* @attention event-driven is a simplified schedule model to support the none-context-swith-based multi-task programming.("the big while 1")
|
||||
* must enable TOS_CFG_MMHEAP_EN to use event-driven.
|
||||
*
|
||||
* @param[in] tasks array of the tasks.
|
||||
* @param[in] task_table_size size of the tasks.
|
||||
* @param[in] poll the user defined poll function.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #EVTDRV_ERR_MMHEAP_NOT_ENABLED mmheap is not enabled.
|
||||
* @retval #EVTDRV_ERR_MEM_ALLOC_FAILED memory allocate failed.
|
||||
* @retval #EVTDRV_ERR_NONE initialize successfully.
|
||||
*/
|
||||
__API__ evtdrv_err_t tos_evtdrv_sys_init(evtdrv_task_entry_t tasks[], evtdrv_ttb_sz_t task_table_size, k_evtdrv_poll_t poll);
|
||||
|
||||
/**
|
||||
* @brief Start the event-driven system.
|
||||
*
|
||||
* @attention start the event-driven multi-task "schedule".
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__API__ void tos_evtdrv_sys_start(void);
|
||||
|
||||
#endif /* TOS_CFG_EVENT_DRIVEN_EN */
|
||||
|
||||
#endif /* _TOS_EVTDRV_SYS_H_ */
|
||||
|
31
kernel/evtdrv/include/tos_evtdrv_task.h
Normal file
31
kernel/evtdrv/include/tos_evtdrv_task.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef _TOS_EVTDRV_TASK_H_
|
||||
#define _TOS_EVTDRV_TASK_H_
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
#define TOS_EVTDRV_TASK_ID_NONE ((evtdrv_task_id_t)-1)
|
||||
|
||||
// return event handled
|
||||
typedef evtdrv_event_flag_t (*evtdrv_task_entry_t)(evtdrv_event_flag_t event_flags);
|
||||
|
||||
#define EVTDRV_TASK_ID2TASK(task_id) (evtdrv_task_entry_t)(evtdrv_task_table[task_id])
|
||||
|
||||
/**
|
||||
* @brief Get the actived("running") task id.
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* @return the actived("running") task id.
|
||||
*/
|
||||
__API__ evtdrv_task_id_t tos_evtdrv_task_self(void);
|
||||
|
||||
__KERNEL__ evtdrv_bool_t evtdrv_task_id_is_invalid(evtdrv_task_id_t task_id);
|
||||
|
||||
__KERNEL__ evtdrv_bool_t evtdrv_task_is_self(evtdrv_task_id_t task_id);
|
||||
|
||||
__KERNEL__ void evtdrv_task_init(void);
|
||||
|
||||
#endif /* TOS_CFG_EVENT_DRIVEN_EN */
|
||||
|
||||
#endif /* _TOS_EVTDRV_TASK_H_ */
|
||||
|
45
kernel/evtdrv/include/tos_evtdrv_tick.h
Normal file
45
kernel/evtdrv/include/tos_evtdrv_tick.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef _TOS_EVTDRV_TICK_H_
|
||||
#define _TOS_EVTDRV_TICK_H_
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
/**
|
||||
* @brief Get the current systick cout.
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* @return current systick count.
|
||||
*/
|
||||
__API__ evtdrv_tick_t tos_evtdrv_systick_get(void);
|
||||
|
||||
/**
|
||||
* @brief tick interrupt handler.
|
||||
*
|
||||
* @attention if you wanna use event-driven timer, you must deal with the tick.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
__API__ void tos_evtdrv_tick_handler(void);
|
||||
|
||||
/**
|
||||
* @brief Convert tick count to milli-seconds.
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* @return the milli-seconds equals to the tick count.
|
||||
*/
|
||||
__API__ evtdrv_time_t tos_evtdrv_tick2millisec(evtdrv_tick_t tick);
|
||||
|
||||
/**
|
||||
* @brief Convert milli-seconds to tick count.
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* @return the tick count equals to the tick count.
|
||||
*/
|
||||
__API__ evtdrv_tick_t tos_evtdrv_millisec2tick(evtdrv_time_t ms);
|
||||
|
||||
#endif /* TOS_CFG_EVENT_DRIVEN_EN */
|
||||
|
||||
#endif /* _TOS_EVTDRV_TICK_H_ */
|
||||
|
82
kernel/evtdrv/include/tos_evtdrv_timer.h
Normal file
82
kernel/evtdrv/include/tos_evtdrv_timer.h
Normal file
@@ -0,0 +1,82 @@
|
||||
#ifndef _TOS_EVTDRV_TIMER_H_
|
||||
#define _TOS_EVTDRV_TIMER_H_
|
||||
|
||||
#define EVTDRV_TIME_MILLISEC_PER_SEC (1000u)
|
||||
|
||||
typedef enum evtdrv_timer_option_en {
|
||||
EVTDRV_TIMER_OPT_ONESHOT,
|
||||
EVTDRV_TIMER_OPT_PERIODIC,
|
||||
} evtdrv_timer_opt_t;
|
||||
|
||||
typedef void (*evtdrv_timer_callback_t)(void *arg);
|
||||
|
||||
typedef struct evtdrv_timer_st {
|
||||
evtdrv_timer_callback_t cb;
|
||||
void *cb_arg;
|
||||
|
||||
k_list_t list;
|
||||
evtdrv_tick_t expires;
|
||||
evtdrv_tick_t period;
|
||||
|
||||
evtdrv_timer_opt_t opt;
|
||||
} evtdrv_timer_t;
|
||||
|
||||
typedef struct evtdrv_timer_control_st {
|
||||
evtdrv_tick_t next_expires;
|
||||
evtdrv_tick_t list;
|
||||
} evtdrv_timer_ctl_t;
|
||||
|
||||
/**
|
||||
* @brief Create a timer.
|
||||
* Create a timer.
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* @param[in] tmr pointer to the handler of the timer.
|
||||
* @param[in] callback callback function called when the timer expires.
|
||||
* @param[in] cb_arg argument for the callback.
|
||||
* @param[in] opt option for the function call.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #EVTDRV_ERR_PTR_NULL task_id is invalid.
|
||||
* @retval #EVTDRV_ERR_NONE event_flags is not valid for user use.
|
||||
*/
|
||||
__API__ evtdrv_err_t tos_evtdrv_timer_create(evtdrv_timer_t *tmr,
|
||||
evtdrv_timer_callback_t callback,
|
||||
void *cb_arg,
|
||||
evtdrv_timer_opt_t opt);
|
||||
|
||||
/**
|
||||
* @brief Start a timer.
|
||||
* Start the timer to run.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] tmr pointer to the handler of the timer.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #EVTDRV_ERR_PTR_NULL tmr is a NULL pointer.
|
||||
* @retval #EVTDRV_ERR_TIMER_ALREADY_EXIST tmr is already exist.
|
||||
* @retval #EVTDRV_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ evtdrv_err_t tos_evtdrv_timer_start(evtdrv_timer_t *tmr, evtdrv_tick_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Stop a timer.
|
||||
* Stop the timer from running.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] tmr pointer to the handler of the timer.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #EVTDRV_ERR_PTR_NULL tmr is a NULL pointer.
|
||||
* @retval #EVTDRV_ERR_TIMER_INACTIVE the timer is not active yet.
|
||||
* @retval #EVTDRV_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ evtdrv_err_t tos_evtdrv_timer_stop(evtdrv_timer_t *tmr);
|
||||
|
||||
__KERNEL__ void evtdrv_timer_update(void);
|
||||
|
||||
#endif /* _TOS_EVTDRV_TIMER_H_ */
|
||||
|
11
kernel/evtdrv/include/tos_evtdrv_types.h
Normal file
11
kernel/evtdrv/include/tos_evtdrv_types.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef _TOS_EVTDRV_TYPES_H_
|
||||
#define _TOS_EVTDRV_TYPES_H_
|
||||
|
||||
typedef int8_t evtdrv_bool_t;
|
||||
typedef uint8_t evtdrv_task_id_t; // task id type
|
||||
typedef uint8_t evtdrv_ttb_sz_t; // task table size type
|
||||
typedef uint64_t evtdrv_tick_t;
|
||||
typedef uint32_t evtdrv_time_t;
|
||||
|
||||
#endif
|
||||
|
111
kernel/evtdrv/tos_evtdrv_event.c
Normal file
111
kernel/evtdrv/tos_evtdrv_event.c
Normal file
@@ -0,0 +1,111 @@
|
||||
#include "tos_evtdrv.h"
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
__API__ evtdrv_err_t tos_evtdrv_event_set(evtdrv_task_id_t task_id, evtdrv_event_flag_t event_flags)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
uint8_t i = 0;
|
||||
evtdrv_event_t *event;
|
||||
evtdrv_event_flag_t flag;
|
||||
|
||||
if (evtdrv_task_id_is_invalid(task_id)) {
|
||||
return EVTDRV_ERR_TASK_INVALID;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
event = &evtdrv_events[task_id];
|
||||
for (i = 0; i < sizeof(evtdrv_event_flag_t) * 8; ++i) {
|
||||
flag = (1 << i);
|
||||
|
||||
if (event_flags & flag) {
|
||||
if (event->nesting[i] == (evtdrv_event_nesting_t)-1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
++event->nesting[i];
|
||||
event->flags |= flag;
|
||||
}
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return EVTDRV_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ evtdrv_err_t tos_evtdrv_event_reset(evtdrv_task_id_t task_id, evtdrv_event_flag_t event_flags)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
uint8_t i = 0;
|
||||
evtdrv_event_t *event;
|
||||
evtdrv_event_flag_t flag;
|
||||
|
||||
if (evtdrv_task_id_is_invalid(task_id)) {
|
||||
return EVTDRV_ERR_TASK_INVALID;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
event = &evtdrv_events[task_id];
|
||||
for (i = 0; i < sizeof(evtdrv_event_flag_t) * 8; ++i) {
|
||||
flag = (1 << i);
|
||||
|
||||
if (event_flags & flag) {
|
||||
if (!(event->flags & flag)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (event->nesting[i] > (evtdrv_event_nesting_t)0u) {
|
||||
--event->nesting[i];
|
||||
}
|
||||
|
||||
if (event->nesting[i] == (evtdrv_event_nesting_t)0u) {
|
||||
event->flags &= ~flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return EVTDRV_ERR_NONE;
|
||||
}
|
||||
|
||||
__KERNEL__ evtdrv_err_t evtdrv_event_init(void)
|
||||
{
|
||||
evtdrv_task_id_t i;
|
||||
evtdrv_event_t *event;
|
||||
|
||||
evtdrv_events = (evtdrv_event_t *)tos_mmheap_calloc(evtdrv_task_table_size, sizeof(evtdrv_event_t));
|
||||
if (!evtdrv_events) {
|
||||
return EVTDRV_ERR_MEM_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
for (i = 0; i < evtdrv_task_table_size; ++i) {
|
||||
event = &evtdrv_events[i];
|
||||
event->flags = TOS_EVTDRV_EVENT_NONE;
|
||||
}
|
||||
|
||||
return EVTDRV_ERR_NONE;
|
||||
}
|
||||
|
||||
__KERNEL__ evtdrv_event_flag_t evtdrv_event_fetch(evtdrv_task_id_t *task_id)
|
||||
{
|
||||
evtdrv_task_id_t i;
|
||||
evtdrv_event_t *event;
|
||||
|
||||
for (i = 0; i < evtdrv_task_table_size; ++i) {
|
||||
event = &evtdrv_events[i];
|
||||
if (event->flags != TOS_EVTDRV_EVENT_NONE) {
|
||||
if (task_id) {
|
||||
*task_id = i;
|
||||
}
|
||||
return event->flags;
|
||||
}
|
||||
}
|
||||
|
||||
return TOS_EVTDRV_EVENT_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
21
kernel/evtdrv/tos_evtdrv_global.c
Normal file
21
kernel/evtdrv/tos_evtdrv_global.c
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "tos_evtdrv.h"
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
evtdrv_task_entry_t *evtdrv_task_table = K_NULL;
|
||||
evtdrv_ttb_sz_t evtdrv_task_table_size = 0;
|
||||
|
||||
evtdrv_task_id_t evtdrv_curr_task = TOS_EVTDRV_TASK_ID_NONE;
|
||||
|
||||
evtdrv_event_t *evtdrv_events = K_NULL;
|
||||
|
||||
k_evtdrv_poll_t evtdrv_poll = K_NULL;
|
||||
|
||||
evtdrv_tick_t evtdrv_tick_count = (evtdrv_tick_t)0u;
|
||||
|
||||
TOS_LIST_DEFINE(evtdrv_msg_list);
|
||||
|
||||
TOS_LIST_DEFINE(evtdrv_timer_list);
|
||||
|
||||
#endif
|
||||
|
106
kernel/evtdrv/tos_evtdrv_msg.c
Normal file
106
kernel/evtdrv/tos_evtdrv_msg.c
Normal file
@@ -0,0 +1,106 @@
|
||||
#include "tos_evtdrv.h"
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
__API__ evtdrv_msg_body_t tos_evtdrv_msg_alloc(evtdrv_msg_len_t msg_len)
|
||||
{
|
||||
evtdrv_msg_hdr_t *msg_hdr = K_NULL;
|
||||
|
||||
if (!msg_len) {
|
||||
return K_NULL;
|
||||
}
|
||||
|
||||
msg_hdr = (evtdrv_msg_hdr_t *)tos_mmheap_alloc(EVTDRV_MSG_LEN(msg_len));
|
||||
if (!msg_hdr) {
|
||||
return K_NULL;
|
||||
}
|
||||
|
||||
tos_list_init(&msg_hdr->list);
|
||||
msg_hdr->len = msg_len;
|
||||
msg_hdr->dst_task_id = TOS_EVTDRV_TASK_ID_NONE;
|
||||
|
||||
return EVTDRV_MSG_HDR2BODY(msg_hdr);
|
||||
}
|
||||
|
||||
__API__ evtdrv_err_t tos_evtdrv_msg_free(evtdrv_msg_body_t msg_body)
|
||||
{
|
||||
evtdrv_msg_hdr_t *msg_hdr = K_NULL;
|
||||
|
||||
if (!msg_body) {
|
||||
return EVTDRV_ERR_PTR_NULL;
|
||||
}
|
||||
|
||||
msg_hdr = EVTDRV_MSG_BODY2HDR(msg_body);
|
||||
if (msg_hdr->dst_task_id != TOS_EVTDRV_TASK_ID_NONE ||
|
||||
!tos_list_empty(&msg_hdr->list)) {
|
||||
return EVTDRV_ERR_MSG_BUSY;
|
||||
}
|
||||
|
||||
tos_mmheap_free(msg_hdr);
|
||||
|
||||
return EVTDRV_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ evtdrv_err_t tos_evtdrv_msg_send(evtdrv_task_id_t dst_task_id, evtdrv_msg_body_t msg_body)
|
||||
{
|
||||
evtdrv_msg_hdr_t *msg_hdr = K_NULL;
|
||||
|
||||
if (!msg_body) {
|
||||
return EVTDRV_ERR_PTR_NULL;
|
||||
}
|
||||
|
||||
if (evtdrv_task_id_is_invalid(dst_task_id)) {
|
||||
tos_evtdrv_msg_free(msg_body);
|
||||
return EVTDRV_ERR_TASK_INVALID;
|
||||
}
|
||||
|
||||
msg_hdr = EVTDRV_MSG_BODY2HDR(msg_body);
|
||||
msg_hdr->dst_task_id = dst_task_id;
|
||||
tos_list_add(&msg_hdr->list, &evtdrv_msg_list);
|
||||
|
||||
tos_evtdrv_event_set(dst_task_id, TOS_EVTDRV_SYS_EVENT_MSG);
|
||||
|
||||
return EVTDRV_ERR_NONE;
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ void evtdrv_msg_prepare4use(evtdrv_msg_hdr_t *msg_hdr)
|
||||
{
|
||||
tos_list_del_init(&msg_hdr->list);
|
||||
msg_hdr->dst_task_id = TOS_EVTDRV_TASK_ID_NONE;
|
||||
}
|
||||
|
||||
__API__ evtdrv_msg_body_t tos_evtdrv_msg_recv(void)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_list_t *curr, *next;
|
||||
evtdrv_msg_hdr_t *msg_hdr = K_NULL;
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
TOS_LIST_FOR_EACH_SAFE(curr, next, &evtdrv_msg_list) {
|
||||
msg_hdr = TOS_LIST_ENTRY(curr, evtdrv_msg_hdr_t, list);
|
||||
if (!evtdrv_task_is_self(msg_hdr->dst_task_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
evtdrv_msg_prepare4use(msg_hdr);
|
||||
tos_evtdrv_event_set(tos_evtdrv_task_self(), TOS_EVTDRV_SYS_EVENT_MSG);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return EVTDRV_MSG_HDR2BODY(msg_hdr);
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
tos_evtdrv_event_reset(tos_evtdrv_task_self(), TOS_EVTDRV_SYS_EVENT_MSG);
|
||||
|
||||
return K_NULL;
|
||||
}
|
||||
|
||||
__KERNEL__ void evtdrv_msg_init(void)
|
||||
{
|
||||
tos_list_init(&evtdrv_msg_list);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
66
kernel/evtdrv/tos_evtdrv_sys.c
Normal file
66
kernel/evtdrv/tos_evtdrv_sys.c
Normal file
@@ -0,0 +1,66 @@
|
||||
#include "tos_evtdrv.h"
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
__API__ evtdrv_err_t tos_evtdrv_sys_init(evtdrv_task_entry_t tasks[], evtdrv_ttb_sz_t task_table_size, k_evtdrv_poll_t poll)
|
||||
{
|
||||
evtdrv_err_t err;
|
||||
|
||||
evtdrv_task_table = &tasks[0];
|
||||
evtdrv_task_table_size = task_table_size;
|
||||
|
||||
evtdrv_poll = poll;
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0
|
||||
mmheap_init(k_mmheap_pool, TOS_CFG_MMHEAP_POOL_SIZE);
|
||||
#else
|
||||
return EVTDRV_ERR_MMHEAP_NOT_ENABLED;
|
||||
#endif
|
||||
|
||||
err = evtdrv_event_init();
|
||||
if (err != EVTDRV_ERR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
evtdrv_msg_init();
|
||||
|
||||
evtdrv_task_init();
|
||||
|
||||
return EVTDRV_ERR_NONE;
|
||||
}
|
||||
|
||||
__STATIC__ void evtdrv_sys_run(void)
|
||||
{
|
||||
evtdrv_event_flag_t event_flag = TOS_EVTDRV_EVENT_NONE;
|
||||
evtdrv_task_id_t task_id = TOS_EVTDRV_TASK_ID_NONE;
|
||||
|
||||
evtdrv_timer_update();
|
||||
|
||||
if (evtdrv_poll) {
|
||||
evtdrv_poll();
|
||||
}
|
||||
|
||||
event_flag = evtdrv_event_fetch(&task_id);
|
||||
if (event_flag != TOS_EVTDRV_EVENT_NONE) {
|
||||
evtdrv_curr_task = task_id;
|
||||
event_flag = (EVTDRV_TASK_ID2TASK(task_id))(event_flag);
|
||||
evtdrv_curr_task = TOS_EVTDRV_TASK_ID_NONE;
|
||||
|
||||
// after task process, event that the task handled is returned.
|
||||
tos_evtdrv_event_reset(task_id, event_flag);
|
||||
} else {
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
pm_power_manager();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
__API__ void tos_evtdrv_sys_start(void)
|
||||
{
|
||||
while (K_TRUE) {
|
||||
evtdrv_sys_run();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
30
kernel/evtdrv/tos_evtdrv_task.c
Normal file
30
kernel/evtdrv/tos_evtdrv_task.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "tos_evtdrv.h"
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
__API__ evtdrv_task_id_t tos_evtdrv_task_self(void)
|
||||
{
|
||||
return evtdrv_curr_task;
|
||||
}
|
||||
|
||||
__KERNEL__ evtdrv_bool_t evtdrv_task_id_is_invalid(evtdrv_task_id_t task_id)
|
||||
{
|
||||
return task_id >= evtdrv_task_table_size;
|
||||
}
|
||||
|
||||
__KERNEL__ evtdrv_bool_t evtdrv_task_is_self(evtdrv_task_id_t task_id)
|
||||
{
|
||||
return task_id == evtdrv_curr_task;
|
||||
}
|
||||
|
||||
__KERNEL__ void evtdrv_task_init(void)
|
||||
{
|
||||
evtdrv_task_id_t i;
|
||||
|
||||
for (i = 0; i < evtdrv_task_table_size; ++i) {
|
||||
(evtdrv_task_table[i])(TOS_EVTDRV_SYS_EVENT_INIT);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
36
kernel/evtdrv/tos_evtdrv_tick.c
Normal file
36
kernel/evtdrv/tos_evtdrv_tick.c
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "tos_evtdrv.h"
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
__API__ evtdrv_time_t tos_evtdrv_tick2millisec(evtdrv_tick_t tick)
|
||||
{
|
||||
return (evtdrv_time_t)(tick * EVTDRV_TIME_MILLISEC_PER_SEC / TOS_CFG_CPU_TICK_PER_SECOND);
|
||||
}
|
||||
|
||||
__API__ evtdrv_tick_t tos_evtdrv_millisec2tick(evtdrv_time_t ms)
|
||||
{
|
||||
return ((evtdrv_tick_t)ms * TOS_CFG_CPU_TICK_PER_SECOND / EVTDRV_TIME_MILLISEC_PER_SEC);
|
||||
}
|
||||
|
||||
__API__ evtdrv_tick_t tos_evtdrv_systick_get(void)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
evtdrv_tick_t tick;
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
tick = evtdrv_tick_count;
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return tick;
|
||||
}
|
||||
|
||||
__API__ void tos_evtdrv_tick_handler(void)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
++evtdrv_tick_count;
|
||||
TOS_CPU_INT_ENABLE();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
114
kernel/evtdrv/tos_evtdrv_timer.c
Normal file
114
kernel/evtdrv/tos_evtdrv_timer.c
Normal file
@@ -0,0 +1,114 @@
|
||||
#include "tos_evtdrv.h"
|
||||
|
||||
#if TOS_CFG_EVENT_DRIVEN_EN > 0u
|
||||
|
||||
__STATIC__ void evtdrv_timer_place(evtdrv_timer_t *tmr, evtdrv_tick_t timeout)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_list_t *curr;
|
||||
evtdrv_timer_t *curr_tmr;
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
tmr->expires = tos_evtdrv_systick_get() + timeout;
|
||||
|
||||
TOS_LIST_FOR_EACH(curr, &evtdrv_timer_list) {
|
||||
curr_tmr = TOS_LIST_ENTRY(curr, evtdrv_timer_t, list);
|
||||
|
||||
if (tmr->expires < curr_tmr->expires) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
tos_list_add_tail(&tmr->list, curr);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
}
|
||||
|
||||
__STATIC__ void evtdrv_timer_takeoff(evtdrv_timer_t *tmr)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
tos_list_del(&tmr->list);
|
||||
TOS_CPU_INT_ENABLE();
|
||||
}
|
||||
|
||||
__API__ evtdrv_err_t tos_evtdrv_timer_create(evtdrv_timer_t *tmr,
|
||||
evtdrv_timer_callback_t callback,
|
||||
void *cb_arg,
|
||||
evtdrv_timer_opt_t opt)
|
||||
{
|
||||
if (!tmr || !callback) {
|
||||
return EVTDRV_ERR_PTR_NULL;
|
||||
}
|
||||
|
||||
tmr->cb = callback;
|
||||
tmr->opt = opt;
|
||||
tos_list_init(&tmr->list);
|
||||
|
||||
return EVTDRV_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ evtdrv_err_t tos_evtdrv_timer_start(evtdrv_timer_t *tmr, evtdrv_tick_t timeout)
|
||||
{
|
||||
if (!tmr) {
|
||||
return EVTDRV_ERR_PTR_NULL;
|
||||
}
|
||||
|
||||
if (!tos_list_empty(&tmr->list)) {
|
||||
return EVTDRV_ERR_TIMER_ALREADY_EXIST;
|
||||
}
|
||||
|
||||
evtdrv_timer_place(tmr, timeout);
|
||||
if (tmr->opt == EVTDRV_TIMER_OPT_PERIODIC) {
|
||||
tmr->period = timeout;
|
||||
}
|
||||
|
||||
return EVTDRV_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ evtdrv_err_t tos_evtdrv_timer_stop(evtdrv_timer_t *tmr)
|
||||
{
|
||||
if (!tmr) {
|
||||
return EVTDRV_ERR_PTR_NULL;
|
||||
}
|
||||
|
||||
if (tos_list_empty(&tmr->list)) {
|
||||
return EVTDRV_ERR_TIMER_INACTIVE;
|
||||
}
|
||||
|
||||
evtdrv_timer_takeoff(tmr);
|
||||
|
||||
return EVTDRV_ERR_NONE;
|
||||
}
|
||||
|
||||
__KERNEL__ void evtdrv_timer_update(void)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
evtdrv_timer_t *tmr;
|
||||
k_list_t *curr, *next;
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
TOS_LIST_FOR_EACH_SAFE(curr, next, &evtdrv_timer_list) {
|
||||
tmr = TOS_LIST_ENTRY(curr, evtdrv_timer_t, list);
|
||||
if (tmr->expires > tos_evtdrv_systick_get()) {
|
||||
break;
|
||||
}
|
||||
|
||||
// time's up
|
||||
evtdrv_timer_takeoff(tmr);
|
||||
|
||||
if (tmr->opt == EVTDRV_TIMER_OPT_PERIODIC) {
|
||||
evtdrv_timer_place(tmr, tmr->period);
|
||||
} else {
|
||||
evtdrv_timer_takeoff(tmr);
|
||||
}
|
||||
|
||||
(*tmr->cb)(tmr->cb_arg);
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_EVENT_DRIVEN_EN */
|
||||
|
Reference in New Issue
Block a user