From b27c7e482648535760e012cd6f1afef1d800e2d2 Mon Sep 17 00:00:00 2001 From: bernard Date: Sun, 15 Oct 2017 22:31:53 +0800 Subject: [PATCH] [Kernel] Add signal implementation. 1. Add signal implementation; 2. Change the 'rt_uint8_t' of cmd to 'int'; --- src/KConfig | 9 +- src/clock.c | 14 +- src/components.c | 5 + src/device.c | 16 +- src/idle.c | 4 + src/ipc.c | 28 ++-- src/kservice.c | 4 +- src/scheduler.c | 21 ++- src/signal.c | 382 +++++++++++++++++++++++++++++++++++++++++++++++ src/thread.c | 28 ++-- src/timer.c | 2 +- 11 files changed, 479 insertions(+), 34 deletions(-) create mode 100644 src/signal.c diff --git a/src/KConfig b/src/KConfig index 2266ab3e55..1d50c0865a 100644 --- a/src/KConfig +++ b/src/KConfig @@ -39,7 +39,7 @@ config RT_USING_OVERFLOW_CHECK config RT_DEBUG_INIT int "Enable system initialization informat print" - default 1 + default 0 help print the procedure name of initialization @@ -100,6 +100,13 @@ config RT_USING_MESSAGEQUEUE bool "Enable message queue" default y +config RT_USING_SIGNALS + bool "Enable signals" + select RT_USING_MEMPOOL + default n + help + A signal is an asynchronous notification sent to a specific thread + in order to notify it of an event that occurred. endmenu menu "Memory Management" diff --git a/src/clock.c b/src/clock.c index 36e26238ed..734c0d5014 100644 --- a/src/clock.c +++ b/src/clock.c @@ -108,13 +108,23 @@ void rt_tick_increase(void) * This function will calculate the tick from millisecond. * * @param ms the specified millisecond + * - Negative Number wait forever + * - Zero not wait + * - Max 0x7fffffff * * @return the calculated tick */ -rt_tick_t rt_tick_from_millisecond(rt_uint32_t ms) +int rt_tick_from_millisecond(rt_int32_t ms) { + int tick; + + if (ms < 0) + tick = RT_WAITING_FOREVER; + else + tick = (RT_TICK_PER_SECOND * ms + 999) / 1000; + /* return the calculated tick */ - return (RT_TICK_PER_SECOND * ms + 999) / 1000; + return tick; } RTM_EXPORT(rt_tick_from_millisecond); diff --git a/src/components.c b/src/components.c index 13a3822ed3..d4982b13c9 100644 --- a/src/components.c +++ b/src/components.c @@ -237,6 +237,11 @@ int rtthread_startup(void) /* scheduler system initialization */ rt_system_scheduler_init(); +#ifdef RT_USING_SIGNALS + /* signal system initialization */ + rt_system_signal_init(); +#endif + /* create init_thread */ rt_application_init(); diff --git a/src/device.c b/src/device.c index 1175a340c9..ac4f5b0ffd 100644 --- a/src/device.c +++ b/src/device.c @@ -56,6 +56,11 @@ rt_err_t rt_device_register(rt_device_t dev, dev->ref_count = 0; dev->open_flag = 0; +#if defined(RT_USING_DFS) && defined(RT_USING_DFS_DEVFS) + dev->fops = RT_NULL; + rt_list_init(&(dev->wait_queue)); +#endif + return RT_EOK; } RTM_EXPORT(rt_device_register); @@ -213,11 +218,16 @@ rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflag) { result = dev->open(dev, oflag); } + else + { + /* set open flag */ + dev->open_flag = (oflag & RT_DEVICE_OFLAG_MASK); + } /* set open flag */ if (result == RT_EOK || result == -RT_ENOSYS) { - dev->open_flag = oflag | RT_DEVICE_OFLAG_OPEN; + dev->open_flag |= RT_DEVICE_OFLAG_OPEN; dev->ref_count++; /* don't let bad things happen silently. If you are bitten by this assert, @@ -349,7 +359,7 @@ RTM_EXPORT(rt_device_write); * * @return the result */ -rt_err_t rt_device_control(rt_device_t dev, rt_uint8_t cmd, void *arg) +rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg) { RT_ASSERT(dev != RT_NULL); @@ -359,7 +369,7 @@ rt_err_t rt_device_control(rt_device_t dev, rt_uint8_t cmd, void *arg) return dev->control(dev, cmd, arg); } - return RT_EOK; + return -RT_ENOSYS; } RTM_EXPORT(rt_device_control); diff --git a/src/idle.c b/src/idle.c index e268c085a7..68b816f7ed 100644 --- a/src/idle.c +++ b/src/idle.c @@ -127,6 +127,10 @@ void rt_thread_idle_excute(void) if (thread->cleanup != RT_NULL) thread->cleanup(thread); +#ifdef RT_USING_SIGNALS + rt_thread_free_sig(thread); +#endif + /* if it's a system object, not delete it */ if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) { diff --git a/src/ipc.c b/src/ipc.c index 8bdfc93db6..dbf0881b02 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -478,7 +478,7 @@ RTM_EXPORT(rt_sem_release); * * @return the error code */ -rt_err_t rt_sem_control(rt_sem_t sem, rt_uint8_t cmd, void *arg) +rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg) { rt_ubase_t level; RT_ASSERT(sem != RT_NULL); @@ -644,14 +644,13 @@ rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time) register rt_base_t temp; struct rt_thread *thread; + /* this function must not be used in interrupt even if time = 0 */ + RT_DEBUG_IN_THREAD_CONTEXT; + RT_ASSERT(mutex != RT_NULL); /* get current thread */ thread = rt_thread_self(); - if (!thread) return RT_EOK; /* return directory if scheduler not started */ - - /* this function must not be used in interrupt even if time = 0 */ - RT_DEBUG_IN_THREAD_CONTEXT; /* disable interrupt */ temp = rt_hw_interrupt_disable(); @@ -672,6 +671,7 @@ rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time) } else { +__again: /* The value of mutex is 1 in initial status. Therefore, if the * value is great than 0, it indicates the mutex is avaible. */ @@ -740,6 +740,9 @@ rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time) if (thread->error != RT_EOK) { + /* interrupt by signal, try it again */ + if (thread->error == -RT_EINTR) goto __again; + /* return error */ return thread->error; } @@ -778,13 +781,12 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) need_schedule = RT_FALSE; - /* get current thread */ - thread = rt_thread_self(); - if (!thread) return RT_EOK; - /* only thread could release mutex because we need test the ownership */ RT_DEBUG_IN_THREAD_CONTEXT; + /* get current thread */ + thread = rt_thread_self(); + /* disable interrupt */ temp = rt_hw_interrupt_disable(); @@ -870,7 +872,7 @@ RTM_EXPORT(rt_mutex_release); * * @return the error code */ -rt_err_t rt_mutex_control(rt_mutex_t mutex, rt_uint8_t cmd, void *arg) +rt_err_t rt_mutex_control(rt_mutex_t mutex, int cmd, void *arg) { return -RT_ERROR; } @@ -1212,7 +1214,7 @@ RTM_EXPORT(rt_event_recv); * * @return the error code */ -rt_err_t rt_event_control(rt_event_t event, rt_uint8_t cmd, void *arg) +rt_err_t rt_event_control(rt_event_t event, int cmd, void *arg) { rt_ubase_t level; RT_ASSERT(event != RT_NULL); @@ -1687,7 +1689,7 @@ RTM_EXPORT(rt_mb_recv); * * @return the error code */ -rt_err_t rt_mb_control(rt_mailbox_t mb, rt_uint8_t cmd, void *arg) +rt_err_t rt_mb_control(rt_mailbox_t mb, int cmd, void *arg) { rt_ubase_t level; RT_ASSERT(mb != RT_NULL); @@ -2235,7 +2237,7 @@ RTM_EXPORT(rt_mq_recv); * * @return the error code */ -rt_err_t rt_mq_control(rt_mq_t mq, rt_uint8_t cmd, void *arg) +rt_err_t rt_mq_control(rt_mq_t mq, int cmd, void *arg) { rt_ubase_t level; struct rt_mq_message *msg; diff --git a/src/kservice.c b/src/kservice.c index 4ffccaf341..4afea50bca 100644 --- a/src/kservice.c +++ b/src/kservice.c @@ -1114,6 +1114,8 @@ RTM_EXPORT(rt_hw_console_output); */ void rt_kputs(const char *str) { + if (!str) return; + #ifdef RT_USING_DEVICE if (_console_device == RT_NULL) { @@ -1265,7 +1267,7 @@ const rt_uint8_t __lowest_bit_bitmap[] = * @return return the index of the first bit set. If value is 0, then this function * shall return 0. */ -rt_ubase_t __rt_ffs(rt_ubase_t value) +int __rt_ffs(int value) { if (value == 0) return 0; diff --git a/src/scheduler.c b/src/scheduler.c index e3e200efc7..6fe5055053 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -42,7 +42,6 @@ static rt_int16_t rt_scheduler_lock_nest; extern volatile rt_uint8_t rt_interrupt_nest; -extern rt_ubase_t __rt_ffs(rt_ubase_t value); rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX]; struct rt_thread *rt_current_thread; @@ -241,8 +240,18 @@ void rt_schedule(void) if (rt_interrupt_nest == 0) { + extern void rt_thread_handle_sig(rt_bool_t clean_state); + rt_hw_context_switch((rt_uint32_t)&from_thread->sp, (rt_uint32_t)&to_thread->sp); + + /* enable interrupt */ + rt_hw_interrupt_enable(level); + +#ifdef RT_USING_SIGNALS + /* check signal status */ + rt_thread_handle_sig(RT_TRUE); +#endif } else { @@ -250,12 +259,16 @@ void rt_schedule(void) rt_hw_context_switch_interrupt((rt_uint32_t)&from_thread->sp, (rt_uint32_t)&to_thread->sp); + /* enable interrupt */ + rt_hw_interrupt_enable(level); } } + else + { + /* enable interrupt */ + rt_hw_interrupt_enable(level); + } } - - /* enable interrupt */ - rt_hw_interrupt_enable(level); } /* diff --git a/src/signal.c b/src/signal.c new file mode 100644 index 0000000000..d70d25087b --- /dev/null +++ b/src/signal.c @@ -0,0 +1,382 @@ +/* + * File : signal.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017/10/5 Bernard the first version + */ + +#include +#include + +#include +#include + +#ifdef RT_USING_SIGNALS + +#ifndef RT_SIG_INFO_MAX +#define RT_SIG_INFO_MAX 32 +#endif + +// #define DBG_ENABLE +#define DBG_SECTION_NAME "[SIGN]" +#define DBG_COLOR +#define DBG_LEVEL DBG_LOG +#include + +#define sig_mask(sig_no) (1u << sig_no) +#define sig_valid(sig_no) (sig_no >= 0 && sig_no < RT_SIG_MAX) + +struct siginfo_node +{ + struct siginfo si; + struct rt_slist_node list; +}; + +static struct rt_mempool *_rt_siginfo_pool; +static void _signal_deliver(rt_thread_t tid); +void rt_thread_handle_sig(rt_bool_t clean_state); + +static void _signal_default_handler(int signo) +{ + dbg_log(DBG_INFO, "handled signo[%d] with default action.\n", signo); + return ; +} + +static void _signal_entry(void* parameter) +{ + rt_thread_t tid = rt_thread_self(); + + dbg_enter; + + /* handle signal */ + rt_thread_handle_sig(RT_FALSE); + + /* never come back... */ + rt_hw_interrupt_disable(); + /* return to thread */ + tid->sp = tid->sig_ret; + tid->sig_ret = RT_NULL; + + dbg_log(DBG_LOG, "switch back to: 0x%08x\n", tid->sp); + tid->stat &= ~RT_THREAD_STAT_SIGNAL; + + rt_hw_context_switch_to((rt_uint32_t)&(tid->sp)); +} + +static void _signal_deliver(rt_thread_t tid) +{ + rt_ubase_t level; + + /* thread is not interested in pended signals */ + if (!(tid->sig_pending & tid->sig_mask)) return; + + level = rt_hw_interrupt_disable(); + if (tid->stat == RT_THREAD_SUSPEND) + { + /* resume thread to handle signal */ + rt_thread_resume(tid); + /* add signal state */ + tid->stat |= RT_THREAD_STAT_SIGNAL; + + rt_hw_interrupt_enable(level); + + /* re-schedule */ + rt_schedule(); + } + else + { + if (tid == rt_thread_self()) + { + /* add signal state */ + tid->stat |= RT_THREAD_STAT_SIGNAL; + rt_hw_interrupt_enable(level); + + /* do signal action in self thread context */ + rt_thread_handle_sig(RT_TRUE); + } + else if (!(tid->stat & RT_THREAD_STAT_SIGNAL)) + { + tid->stat |= RT_THREAD_STAT_SIGNAL; + /* point to the signal handle entry */ + tid->sig_ret = tid->sp; + tid->sp = rt_hw_stack_init((void*)_signal_entry, RT_NULL, + (void *)((char *)tid->sig_ret - 32), RT_NULL); + + rt_hw_interrupt_enable(level); + dbg_log(DBG_LOG, "signal stack pointer @ 0x%08x\n", tid->sp); + + /* re-schedule */ + rt_schedule(); + } + else + { + rt_hw_interrupt_enable(level); + } + } +} + +rt_sighandler_t rt_signal_install(int signo, rt_sighandler_t handler) +{ + rt_sighandler_t old; + rt_thread_t tid = rt_thread_self(); + + if (!sig_valid(signo)) return SIG_ERR; + + rt_enter_critical(); + if (tid->sig_vectors == RT_NULL) + { + rt_thread_alloc_sig(tid); + } + + if (tid->sig_vectors) + { + old = tid->sig_vectors[signo]; + + if (handler == SIG_IGN) tid->sig_vectors[signo] = RT_NULL; + else if (handler == SIG_DFL) tid->sig_vectors[signo] = _signal_default_handler; + else tid->sig_vectors[signo] = handler; + } + rt_exit_critical(); + + return old; +} + +void rt_signal_mask(int signo) +{ + rt_base_t level; + rt_thread_t tid = rt_thread_self(); + + level = rt_hw_interrupt_disable(); + + tid->sig_mask &= ~sig_mask(signo); + + rt_hw_interrupt_enable(level); +} + +void rt_signal_unmask(int signo) +{ + rt_base_t level; + rt_thread_t tid = rt_thread_self(); + + level = rt_hw_interrupt_disable(); + + tid->sig_mask |= sig_mask(signo); + + /* let thread handle pended signals */ + if (tid->sig_mask & tid->sig_pending) + { + rt_hw_interrupt_enable(level); + _signal_deliver(tid); + } + else + { + rt_hw_interrupt_enable(level); + } +} + +void rt_thread_handle_sig(rt_bool_t clean_state) +{ + rt_base_t level; + + rt_thread_t tid = rt_thread_self(); + struct siginfo_node *si_node; + + level = rt_hw_interrupt_disable(); + while (tid->sig_pending & tid->sig_mask) + { + int signo, error; + rt_sighandler_t handler; + + si_node = (struct siginfo_node *)tid->si_list; + if (!si_node) break; + + /* remove this sig info node from list */ + if (si_node->list.next == RT_NULL) + tid->si_list = RT_NULL; + else + tid->si_list = (void*)rt_slist_entry(si_node->list.next, struct siginfo_node, list); + + signo = si_node->si.si_signo; + handler = tid->sig_vectors[signo]; + rt_hw_interrupt_enable(level); + + dbg_log(DBG_LOG, "handle signal: %d, handler 0x%08x\n", signo, handler); + if (handler) handler(signo); + + level = rt_hw_interrupt_disable(); + tid->sig_pending &= ~sig_mask(signo); + error = si_node->si.si_errno; + + rt_mp_free(si_node); /* release this siginfo node */ + /* set errno in thread tcb */ + tid->error = error; + } + + /* whether clean signal status */ + if (clean_state == RT_TRUE) tid->stat &= ~RT_THREAD_STAT_SIGNAL; + + rt_hw_interrupt_enable(level); +} + +void rt_thread_alloc_sig(rt_thread_t tid) +{ + int index; + rt_base_t level; + rt_sighandler_t *vectors; + + vectors = (rt_sighandler_t *)RT_KERNEL_MALLOC(sizeof(rt_sighandler_t) * RT_SIG_MAX); + RT_ASSERT(vectors != RT_NULL); + + for (index = 0; index < RT_SIG_MAX; index ++) + { + vectors[index] = _signal_default_handler; + } + + level = rt_hw_interrupt_disable(); + tid->sig_vectors = vectors; + rt_hw_interrupt_enable(level); +} + +void rt_thread_free_sig(rt_thread_t tid) +{ + rt_base_t level; + struct siginfo_node *si_list; + rt_sighandler_t *sig_vectors; + + level = rt_hw_interrupt_disable(); + si_list = (struct siginfo_node*)tid->si_list; + tid->si_list = RT_NULL; + + sig_vectors = tid->sig_vectors; + tid->sig_vectors = RT_NULL; + rt_hw_interrupt_enable(level); + + if (si_list) + { + struct rt_slist_node *node; + struct siginfo_node *si_node; + + dbg_log(DBG_LOG, "free signal info list\n"); + node = &(si_list->list); + do { + si_node = rt_slist_entry(node, struct siginfo_node, list); + rt_mp_free(si_node); + + node = node->next; + } while (node); + } + + if (sig_vectors) + { + RT_KERNEL_FREE(sig_vectors); + } +} + +int rt_thread_kill(rt_thread_t tid, int sig) +{ + siginfo_t si; + rt_base_t level; + struct siginfo_node *si_node; + + RT_ASSERT(tid != RT_NULL); + if (!sig_valid(sig)) return -RT_EINVAL; + + dbg_log(DBG_INFO, "send signal: %d\n", sig); + si.si_errno = RT_EINTR; + si.si_signo = sig; + si.si_code = SI_USER; + si.si_value.sival_ptr = RT_NULL; + + level = rt_hw_interrupt_disable(); + if (tid->sig_pending & sig_mask(sig)) + { + /* whether already emits this signal? */ + struct rt_slist_node *node; + struct siginfo_node *entry; + + node = (struct rt_slist_node *)tid->si_list; + rt_hw_interrupt_enable(level); + + /* update sig infor */ + rt_enter_critical(); + for (; (node) != RT_NULL; node = node->next) + { + entry = rt_slist_entry(node, struct siginfo_node, list); + if (entry->si.si_signo == sig) + { + memcpy(&(entry->si), &si, sizeof(siginfo_t)); + rt_exit_critical(); + return 0; + } + } + rt_exit_critical(); + + /* disable interrupt to protect tcb */ + level = rt_hw_interrupt_disable(); + } + else + { + /* a new signal */ + tid->sig_pending |= sig_mask(sig); + } + rt_hw_interrupt_enable(level); + + si_node = (struct siginfo_node*) rt_mp_alloc(_rt_siginfo_pool, 0); + if (si_node) + { + rt_slist_init(&(si_node->list)); + memcpy(&(si_node->si), &si, sizeof(siginfo_t)); + + level = rt_hw_interrupt_disable(); + if (!tid->si_list) tid->si_list = si_node; + else + { + struct siginfo_node *si_list; + + si_list = (struct siginfo_node*)tid->si_list; + rt_slist_append(&(si_list->list), &(si_node->list)); + } + rt_hw_interrupt_enable(level); + } + else + { + dbg_log(DBG_ERROR, "The allocation of signal infor node failed.\n"); + } + + /* deliver signal to this thread */ + _signal_deliver(tid); + + return RT_EOK; +} + +int rt_system_signal_init(void) +{ + _rt_siginfo_pool = rt_mp_create("signal", RT_SIG_INFO_MAX, sizeof(struct siginfo_node)); + if (_rt_siginfo_pool == RT_NULL) + { + dbg_log(DBG_ERROR, "create memory pool for signal info failed.\n"); + RT_ASSERT(0); + } + + return 0; +} + +#endif + diff --git a/src/thread.c b/src/thread.c index 0048261e96..50111d9917 100644 --- a/src/thread.c +++ b/src/thread.c @@ -185,6 +185,16 @@ static rt_err_t _rt_thread_init(struct rt_thread *thread, 0, RT_TIMER_FLAG_ONE_SHOT); + /* initialize signal */ +#ifdef RT_USING_SIGNALS + thread->sig_mask = 0x00; + thread->sig_pending = 0x00; + + thread->sig_ret = RT_NULL; + thread->sig_vectors = RT_NULL; + thread->si_list = RT_NULL; +#endif + RT_OBJECT_HOOK_CALL(rt_thread_inited_hook, (thread)); return RT_EOK; @@ -260,7 +270,7 @@ rt_err_t rt_thread_startup(rt_thread_t thread) { /* thread check */ RT_ASSERT(thread != RT_NULL); - RT_ASSERT(thread->stat == RT_THREAD_INIT); + RT_ASSERT((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_INIT); /* set current priority to init priority */ thread->current_priority = thread->init_priority; @@ -305,7 +315,7 @@ rt_err_t rt_thread_detach(rt_thread_t thread) /* thread check */ RT_ASSERT(thread != RT_NULL); - if (thread->stat != RT_THREAD_INIT) + if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT) { /* remove from schedule */ rt_schedule_remove_thread(thread); @@ -403,7 +413,7 @@ rt_err_t rt_thread_delete(rt_thread_t thread) /* thread check */ RT_ASSERT(thread != RT_NULL); - if (thread->stat != RT_THREAD_INIT) + if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT) { /* remove from schedule */ rt_schedule_remove_thread(thread); @@ -448,7 +458,7 @@ rt_err_t rt_thread_yield(void) thread = rt_current_thread; /* if the thread stat is READY and on ready queue list */ - if (thread->stat == RT_THREAD_READY && + if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_READY && thread->tlist.next != thread->tlist.prev) { /* remove thread from thread list */ @@ -535,7 +545,7 @@ RTM_EXPORT(rt_thread_delay); * * @return RT_EOK */ -rt_err_t rt_thread_control(rt_thread_t thread, rt_uint8_t cmd, void *arg) +rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg) { register rt_base_t temp; @@ -549,7 +559,7 @@ rt_err_t rt_thread_control(rt_thread_t thread, rt_uint8_t cmd, void *arg) temp = rt_hw_interrupt_disable(); /* for ready thread, change queue */ - if (thread->stat == RT_THREAD_READY) + if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_READY) { /* remove thread from schedule queue first */ rt_schedule_remove_thread(thread); @@ -622,7 +632,7 @@ rt_err_t rt_thread_suspend(rt_thread_t thread) RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend: %s\n", thread->name)); - if (thread->stat != RT_THREAD_READY) + if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_READY) { RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend: thread disorder, %d\n", thread->stat)); @@ -664,7 +674,7 @@ rt_err_t rt_thread_resume(rt_thread_t thread) RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread resume: %s\n", thread->name)); - if (thread->stat != RT_THREAD_SUSPEND) + if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_SUSPEND) { RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread resume: thread disorder, %d\n", thread->stat)); @@ -705,7 +715,7 @@ void rt_thread_timeout(void *parameter) /* thread check */ RT_ASSERT(thread != RT_NULL); - RT_ASSERT(thread->stat == RT_THREAD_SUSPEND); + RT_ASSERT((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND); /* set error number */ thread->error = -RT_ETIMEOUT; diff --git a/src/timer.c b/src/timer.c index 1543870aa4..c56a453a3c 100644 --- a/src/timer.c +++ b/src/timer.c @@ -451,7 +451,7 @@ RTM_EXPORT(rt_timer_stop); * * @return RT_EOK */ -rt_err_t rt_timer_control(rt_timer_t timer, rt_uint8_t cmd, void *arg) +rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg) { /* timer check */ RT_ASSERT(timer != RT_NULL);