diff --git a/TODO.md b/TODO.md index d233422a55183f0d1f75c93d27c426fc525e9af4..68341bebb1efe77fd65bbcd31ad9847bcdc6a69a 100644 --- a/TODO.md +++ b/TODO.md @@ -1,10 +1,13 @@ # EventOS开发规划 --------- -+ 【已完成,尚未全面测试】实现时间事件。 -+ 测试任务自动退出功能 ++ 定时器功能的全面测试 ++ 时间事件功能的全面测试 ++ 任务功能的全面测试 ++ 屏蔽事件的功能的测试 + 继续对代码各个子功能进行测试。 + 整理各个函数的命名。 -+ 仔细考虑重复publish或者send时间事件的操作 + 向M0 - M7各个芯片上的移植 + 主要的功能例程 -+ 简要文档 \ No newline at end of file ++ 简要文档 ++ 将所有的return变为goto风格 ++ 给EOS代码中添加详细的注释 diff --git a/eventos/eos.c b/eventos/eos.c index 5db5461ce7849643421daa07eeed5c563e0a47a6..d06042745ed133d1046129afc53b8ba0f22b4d9f 100644 --- a/eventos/eos.c +++ b/eventos/eos.c @@ -399,16 +399,36 @@ static bool equeue_no_current_task_event(eos_u16_t t_index) return ret; } +eos_err_t eos_task_delay_no_event(eos_u32_t tick) +{ + eos_task_handle_t task = eos_task_self(); + register eos_base_t level; + + level = eos_hw_interrupt_disable(); + task->event_recv_disable = true; + eos_hw_interrupt_enable(level); + + eos_task_delay(tick); + + level = eos_hw_interrupt_disable(); + task->event_recv_disable = false; + eos_hw_interrupt_enable(level); + + return EOS_EOK; +} + bool eos_task_wait_event(eos_event_t *const e_out, eos_s32_t time_ms) { eos_task_handle_t task = eos_task_self(); eos_err_t ret = eos_sem_take(&task->sem, time_ms); + /* disable interrupt */ register eos_base_t level = eos_hw_interrupt_disable(); if (ret == EOS_EOK) { EOS_ASSERT(eos.e_queue != EOS_NULL); + /* Find the first event data in e-queue and set it as handled. */ eos_event_data_t *e_item = eos.e_queue; while (e_item != EOS_NULL) @@ -460,6 +480,7 @@ bool eos_task_wait_event(eos_event_t *const e_out, eos_s32_t time_ms) } } + /* enable interrupt */ eos_hw_interrupt_enable(level); return false; @@ -557,6 +578,7 @@ Event ----------------------------------------------------------------------------- */ void eos_event_attribute_global(const char *topic) { + /* disable interrupt */ register eos_base_t level = eos_hw_interrupt_disable(); eos_u16_t e_id; @@ -568,11 +590,13 @@ void eos_event_attribute_global(const char *topic) EOS_ASSERT(eos.object[e_id].type == EosObj_Event); eos.object[e_id].attribute |= EOS_EVENT_ATTRIBUTE_GLOBAL; + /* enable interrupt */ eos_hw_interrupt_enable(level); } void eos_event_attribute_unblocked(const char *topic) { + /* disable interrupt */ register eos_base_t level = eos_hw_interrupt_disable(); eos_u16_t e_id; @@ -584,6 +608,7 @@ void eos_event_attribute_unblocked(const char *topic) EOS_ASSERT(eos.object[e_id].type == EosObj_Event); eos.object[e_id].attribute |= EOS_EVENT_ATTRIBUTE_UNBLOCKED; + /* enable interrupt */ eos_hw_interrupt_enable(level); } @@ -629,9 +654,11 @@ static void eos_task_function(void *parameter) static void eos_e_queue_delete_(eos_event_data_t const *item) { + /* parameter check */ EOS_ASSERT(eos.e_queue != EOS_NULL); EOS_ASSERT(item != EOS_NULL); + /* disable interrupt */ register eos_base_t level = eos_hw_interrupt_disable(); /* If the event data is only one in queue. */ @@ -662,6 +689,7 @@ static void eos_e_queue_delete_(eos_event_data_t const *item) /* free the event data. */ eos_heap_free(&eos.heap, (void *)item); + /* enable interrupt */ eos_hw_interrupt_enable(level); } @@ -862,6 +890,14 @@ static eos_s8_t eos_event_give_(const char *task, eos_u32_t task_id, { goto exit; } + if (eos_task_get_state(tcb) == EOS_TASK_SUSPEND) + { + goto exit; + } + if (tcb->event_recv_disable == true) + { + goto exit; + } g_owner.data[tcb->index / 8] = (1 << (tcb->index % 8)); } /* The publish-type event. */ @@ -881,6 +917,10 @@ static eos_s8_t eos_event_give_(const char *task, eos_u32_t task_id, { owner_set_bit(&g_owner, i, false); } + if (eos_task_get_state(obj->ocb.task.tcb) == EOS_TASK_SUSPEND) + { + owner_set_bit(&g_owner, i, false); + } } } diff --git a/eventos/eos.h b/eventos/eos.h index 910782a34a0c810620c8aac5f7a8a36699676e2f..de3d86ae1af36627a579e8f3ef5248b429062354 100644 --- a/eventos/eos.h +++ b/eventos/eos.h @@ -198,6 +198,7 @@ eos_err_t eos_task_yield(void); eos_err_t eos_task_delay(eos_u32_t tick); eos_err_t eos_task_delay_until(eos_u32_t *tick, eos_u32_t inc_tick); eos_err_t eos_task_delay_ms(eos_s32_t ms); +eos_err_t eos_task_delay_no_event(eos_u32_t tick); eos_err_t eos_task_suspend(eos_task_handle_t task); eos_err_t eos_task_resume(eos_task_handle_t task); eos_task_state_t eos_task_get_state(eos_task_handle_t task); @@ -206,9 +207,6 @@ eos_u8_t eos_task_get_priority(eos_task_handle_t task); bool eos_task_wait_specific_event(eos_event_t * const e_out, const char *topic, eos_s32_t time_ms); bool eos_task_wait_event(eos_event_t * const e_out, eos_s32_t time_ms); -/* defunct */ -void eos_task_defunct_enqueue(eos_task_handle_t task); -eos_task_handle_t eos_task_defunct_dequeue(void); /* ----------------------------------------------------------------------------- Timer @@ -227,9 +225,6 @@ eos_err_t eos_timer_set_time(eos_timer_handle_t timer, eos_u32_t time); eos_u32_t eos_timer_get_time(eos_timer_handle_t timer); eos_err_t eos_timer_reset(eos_timer_handle_t timer); -eos_u32_t eos_timer_next_timeout_tick(void); -void eos_timer_check(void); - /* ----------------------------------------------------------------------------- Semaphore ----------------------------------------------------------------------------- */ diff --git a/eventos/eos_def.h b/eventos/eos_def.h index f1707d6b229d0cc8949f77e1bd3800eedfb68ba1..a26c93321cce763fa6d9100b2c33810579a0a511 100644 --- a/eventos/eos_def.h +++ b/eventos/eos_def.h @@ -77,7 +77,6 @@ typedef bool eos_bool_t; #define EOS_SECTION(x) __attribute__((section(x))) #define EOS_USED __attribute__((used)) #define ALIGN(n) __attribute__((aligned(n))) - #define EOS_WEAK __attribute__((weak)) #define eos_inline static __inline #elif defined (__IAR_SYSTEMS_ICC__) /* for IAR Compiler */ #include @@ -85,7 +84,6 @@ typedef bool eos_bool_t; #define EOS_USED __root #define PRAGMA(x) _Pragma(#x) #define ALIGN(n) PRAGMA(data_alignment=n) - #define EOS_WEAK __weak #define eos_inline static inline #elif defined (__GNUC__) /* GNU GCC Compiler */ /* the version of GNU GCC must be greater than 4.x */ @@ -97,7 +95,6 @@ typedef bool eos_bool_t; #define EOS_SECTION(x) __attribute__((section(x))) #define EOS_USED __attribute__((used)) #define ALIGN(n) __attribute__((aligned(n))) - #define EOS_WEAK __attribute__((weak)) #define eos_inline static __inline #else #define eos_inline static inline @@ -111,9 +108,10 @@ typedef enum eos_task_state { EOS_TASK_INIT = 0x00, /**< Initialized status */ EOS_TASK_READY = 0x01, /**< Ready status */ - EOS_TASK_SUSPEND = 0x02, /**< Suspend status */ - EOS_TASK_RUNNING = 0x03, /**< Running status */ - EOS_TASK_CLOSE = 0x04, /**< Closed status */ + EOS_TASK_BLOCK = 0x02, /**< block status */ + EOS_TASK_SUSPEND = 0x03, + EOS_TASK_RUNNING = 0x04, /**< Running status */ + EOS_TASK_CLOSE = 0x05, /**< Closed status */ EOS_TASK_STAT_MASK = 0x07, } eos_task_state_t; @@ -122,13 +120,6 @@ typedef enum eos_task_state #define EOS_ERROR -1 /**< A generic error happens */ #define EOS_ETIMEOUT -2 /**< Timed out */ #define EOS_EFULL -3 /**< The resource is full */ -#define EOS_EEMPTY -4 /**< The resource is empty */ -#define EOS_ENOMEM -5 /**< No memory */ -#define EOS_ENOSYS -6 /**< No system */ -#define EOS_EBUSY -7 /**< Busy */ -#define EOS_EIO -8 /**< IO error */ -#define EOS_EINTR -9 /**< Interrupted system call */ -#define EOS_EINVAL -10 /**< Invalid argument */ /* maximum value of ipc type */ #define EOS_SEM_VALUE_MAX EOS_U16_MAX /**< Maximum number of semaphore .value */ diff --git a/eventos/eos_kernel.c b/eventos/eos_kernel.c index 770695f8b7e1f043cecffa50e4786d415b74ca9a..d16df949e0df6e43666a20ca692c505126ed337c 100644 --- a/eventos/eos_kernel.c +++ b/eventos/eos_kernel.c @@ -53,6 +53,9 @@ void eos_schedule_remove_task(ek_task_t *task); static eos_u32_t eos_tick_from_millisecond(eos_s32_t ms); static eos_err_t eos_timer_control(eos_timer_handle_t timer_, int cmd, void *arg); +static void eos_task_defunct_enqueue(eos_task_handle_t task); +static eos_task_handle_t eos_task_defunct_dequeue(void); +static eos_err_t eos_task_block(eos_task_handle_t task); eos_u8_t *eos_hw_stack_init(void *entry, void *parameter, @@ -810,7 +813,7 @@ static void _task_timeout(void *parameter) /* parameter check */ EOS_ASSERT(task != EOS_NULL); - EOS_ASSERT((task->status & EOS_TASK_STAT_MASK) == EOS_TASK_SUSPEND); + EOS_ASSERT((task->status & EOS_TASK_STAT_MASK) == EOS_TASK_BLOCK); EOS_ASSERT(eos_object_get_type((ek_obj_handle_t)task) == EOS_Object_Task); /* disable interrupt */ @@ -957,7 +960,7 @@ eos_err_t eos_task_startup(eos_task_handle_t task) task_->number_mask = 1L << task_->current_priority; /* change task stat */ - task_->status = EOS_TASK_SUSPEND; + task_->status = EOS_TASK_BLOCK; /* then resume it */ eos_task_resume(task); if (eos_task_self() != EOS_NULL) @@ -1061,8 +1064,8 @@ eos_err_t eos_task_sleep(eos_u32_t tick) /* reset task error */ task->error = EOS_EOK; - /* suspend task */ - eos_task_suspend((eos_task_handle_t)task); + /* make the task into sleep state */ + eos_task_block((eos_task_handle_t)task); /* reset the timeout of task timer and start it */ eos_timer_control((eos_timer_handle_t)&(task->task_timer), @@ -1128,7 +1131,7 @@ eos_err_t eos_task_delay_until(eos_u32_t *tick, eos_u32_t inc_tick) left_tick = *tick - cur_tick; /* suspend task */ - eos_task_suspend((eos_task_handle_t)task); + eos_task_block((eos_task_handle_t)task); /* reset the timeout of task timer and start it */ eos_timer_control((eos_timer_handle_t)&(task->task_timer), @@ -1251,6 +1254,45 @@ eos_err_t eos_task_control(eos_task_handle_t task_, int cmd, void *arg) return EOS_EOK; } +/** + * @brief This function will block the specified task and change it to block state. + * @param task is the task to be blocked. + * @return Return the operation status. If the return value is EOS_EOK, the function is successfully executed. + * If the return value is any other values, it means this operation failed. + */ +static eos_err_t eos_task_block(eos_task_handle_t task_) +{ + ek_task_handle_t task = (ek_task_handle_t)task_; + register eos_base_t stat; + register eos_base_t temp; + + /* parameter check */ + EOS_ASSERT(task != EOS_NULL); + EOS_ASSERT(eos_object_get_type((ek_obj_handle_t)task) == EOS_Object_Task); + EOS_ASSERT(task == (ek_task_handle_t)eos_task_self()); + + stat = task->status & EOS_TASK_STAT_MASK; + if ((stat != EOS_TASK_READY) && (stat != EOS_TASK_RUNNING)) + { + return EOS_ERROR; + } + + /* disable interrupt */ + temp = eos_hw_interrupt_disable(); + + /* change task stat */ + eos_schedule_remove_task(task); + task->status = EOS_TASK_BLOCK | (task->status & ~EOS_TASK_STAT_MASK); + + /* stop task timer anyway */ + eos_timer_stop((eos_timer_handle_t)&(task->task_timer)); + + /* enable interrupt */ + eos_hw_interrupt_enable(temp); + + return EOS_EOK; +} + /** * @brief This function will suspend the specified task and change it to suspend state. * @note This function ONLY can suspend current task itself. @@ -1311,7 +1353,8 @@ eos_err_t eos_task_resume(eos_task_handle_t task_) EOS_ASSERT(task != EOS_NULL); EOS_ASSERT(eos_object_get_type((ek_obj_handle_t)task) == EOS_Object_Task); - if ((task->status & EOS_TASK_STAT_MASK) != EOS_TASK_SUSPEND) + if ((task->status & EOS_TASK_STAT_MASK) != EOS_TASK_BLOCK && + (task->status & EOS_TASK_STAT_MASK) != EOS_TASK_SUSPEND) { return EOS_ERROR; } @@ -1371,7 +1414,7 @@ eos_inline eos_err_t _ipc_object_init(struct ek_ipc_object *ipc) eos_inline eos_err_t _ipc_list_suspend(ek_list_t *list, ek_task_handle_t task) { /* suspend task */ - eos_task_suspend((eos_task_handle_t)task); + eos_task_block((eos_task_handle_t)task); struct ek_list_node *n; ek_task_handle_t stask; @@ -1601,7 +1644,6 @@ eos_err_t eos_sem_take(eos_sem_handle_t sem_, eos_s32_t time) /* has waiting time, start task timer */ if (time > 0) { - /* reset the timeout of task timer and start it */ eos_timer_control((eos_timer_handle_t)&(task->task_timer), EOS_TIMER_CTRL_SET_TIME, @@ -2542,7 +2584,7 @@ eos_err_t eos_timer_start(eos_timer_handle_t timer_) { /* check whether timer task is ready */ if ((_soft_timer_status == EOS_SOFT_TIMER_IDLE) && - ((_timer_task.status & EOS_TASK_STAT_MASK) == EOS_TASK_SUSPEND)) + ((_timer_task.status & EOS_TASK_STAT_MASK) == EOS_TASK_BLOCK)) { /* resume timer task to check soft timer */ eos_task_resume((eos_task_handle_t)&_timer_task); @@ -2895,7 +2937,7 @@ static void _timer_task_entry(void *parameter) if (_timer_list_next_timeout(_soft_timer_list, &next_timeout) != EOS_EOK) { /* no software timer exist, suspend self. */ - eos_task_suspend(eos_task_self()); + eos_task_block(eos_task_self()); eos_schedule(); } else diff --git a/libcpu/arm/cortex-m4/cpuport.c b/libcpu/arm/cortex-m4/cpuport.c index fe9ea2e6541966727251be11efcae17d27f7b0d2..2ef7400750f64f2ddd24ca730688fee867bc6d2c 100644 --- a/libcpu/arm/cortex-m4/cpuport.c +++ b/libcpu/arm/cortex-m4/cpuport.c @@ -1,8 +1,6 @@ #include -EOS_TAG("CpuPort") - #if /* ARMCC */ ( (defined ( __CC_ARM ) && defined ( __TARGET_FPU_VFP )) \ /* Clang */ || (defined ( __clang__ ) && defined ( __VFP_FP__ ) && !defined(__SOFTFP__)) \ /* IAR */ || (defined ( __ICCARM__ ) && defined ( __ARMVFP__ )) \ @@ -181,22 +179,6 @@ void eos_hw_hard_fault_exception(struct exception_info *exception_info) while (1); } -/** - * shutdown CPU - */ -EOS_WEAK void eos_hw_cpu_shutdown(void) -{ - EOS_ASSERT(0); -} - -/** - * reset CPU - */ -EOS_WEAK void eos_hw_cpu_reset(void) -{ - SCB_AIRCR = SCB_RESET_VALUE; -} - #ifdef RT_USING_CPU_FFS /** * This function finds the first bit set (beginning with the least significant bit)