diff options
| author | tmmdh <[email protected]> | 2021-01-20 18:45:20 +0800 |
|---|---|---|
| committer | tmmdh <[email protected]> | 2021-01-20 18:45:20 +0800 |
| commit | 9db4d446382426d215ffe79f60920c98a8b1be53 (patch) | |
| tree | a3bd61199194d5f8251bf7ee889e22baedf5dc31 /src | |
| parent | 55c0a9f27900d19556d52110be6397f3ee15a6c3 (diff) | |
| parent | afd575105d2fdd29fb003fb49c6e4f5446f824ce (diff) | |
Merge branch 'master' of https://github.com/RT-Thread/rt-thread
Diffstat (limited to 'src')
| -rw-r--r-- | src/Kconfig | 14 | ||||
| -rw-r--r-- | src/SConscript | 13 | ||||
| -rw-r--r-- | src/clock.c | 28 | ||||
| -rw-r--r-- | src/device.c | 33 | ||||
| -rw-r--r-- | src/idle.c | 79 | ||||
| -rwxr-xr-x | src/ipc.c | 80 | ||||
| -rw-r--r-- | src/kservice.c | 8 | ||||
| -rw-r--r-- | src/memheap.c | 18 | ||||
| -rw-r--r-- | src/object.c | 14 | ||||
| -rw-r--r-- | src/scheduler.c | 9 | ||||
| -rw-r--r-- | src/thread.c | 70 | ||||
| -rw-r--r-- | src/timer.c | 8 |
12 files changed, 194 insertions, 180 deletions
diff --git a/src/Kconfig b/src/Kconfig index 63a7a67887..803c827e51 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -270,6 +270,18 @@ menu "Memory Management" config RT_USING_MEMHEAP_AS_HEAP bool "Use all of memheap objects as heap" endif + + config RT_USING_USERHEAP + bool "Use user heap" + help + If this option is selected, please implement these functions: + rt_malloc(), rt_malloc_sethook() + rt_free(), rt_free_sethook() + rt_calloc(), rt_realloc() + rt_system_heap_init() + + And if FinSH is used at the same time, please implement list_mem() + endchoice if RT_USING_SMALL_MEM @@ -294,7 +306,7 @@ menu "Memory Management" default y if RT_USING_SMALL_MEM default y if RT_USING_SLAB default y if RT_USING_MEMHEAP_AS_HEAP - + default y if RT_USING_USERHEAP endmenu menu "Kernel Device Object" diff --git a/src/SConscript b/src/SConscript index 82c3b8aaf1..68523978d6 100644 --- a/src/SConscript +++ b/src/SConscript @@ -6,9 +6,6 @@ src = Glob('*.c') CPPPATH = [RTT_ROOT + '/include'] -if GetDepend('RT_USING_MODULE') == False: - SrcRemove(src, ['module.c']) - if GetDepend('RT_USING_HEAP') == False or GetDepend('RT_USING_SMALL_MEM') == False: SrcRemove(src, ['mem.c']) @@ -23,12 +20,20 @@ if GetDepend('RT_USING_MEMHEAP') == False: if GetDepend('RT_USING_MEMHEAP_AS_HEAP'): SrcRemove(src, ['mem.c']) +if GetDepend('RT_USING_USERHEAP'): + SrcRemove(src, ['mem.c', 'slab.c']) + +if GetDepend('RT_USING_SIGNALS') == False: + SrcRemove(src, ['signal.c']) + if GetDepend('RT_USING_DEVICE') == False: SrcRemove(src, ['device.c']) if GetDepend('RT_USING_SMP') == False: SrcRemove(src, ['cpu.c']) -group = DefineGroup('Kernel', src, depend = [''], CPPPATH = CPPPATH) +CPPDEFINES = ['__RTTHREAD__'] + +group = DefineGroup('Kernel', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) Return('group') diff --git a/src/clock.c b/src/clock.c index a91cd829b6..66923e5c00 100644 --- a/src/clock.c +++ b/src/clock.c @@ -13,6 +13,7 @@ * 2010-07-13 Bernard fix rt_tick_from_millisecond issue found by kuronca * 2011-06-26 Bernard add rt_tick_set function. * 2018-11-22 Jesven add per cpu tick + * 2020-12-29 Meco Man add function rt_tick_get_millisecond() */ #include <rthw.h> @@ -25,17 +26,6 @@ static rt_tick_t rt_tick = 0; #endif /** - * This function will initialize system tick and set it to zero. - * @ingroup SystemInit - * - * @deprecated since 1.1.0, this function does not need to be invoked - * in the system initialization. - */ -void rt_system_tick_init(void) -{ -} - -/** * @addtogroup Clock */ @@ -127,5 +117,21 @@ rt_tick_t rt_tick_from_millisecond(rt_int32_t ms) } RTM_EXPORT(rt_tick_from_millisecond); +/** + * This function will provide the passed millisecond from boot. + * + * @return passed millisecond from boot + */ +RT_WEAK rt_tick_t rt_tick_get_millisecond(void) +{ +#if 1000 % RT_TICK_PER_SECOND == 0u + return rt_tick_get() * (1000u / RT_TICK_PER_SECOND); +#else + #warning "rt-thread cannot provide a correct 1ms-based tick any longer,\ + please redefine this function in another file by using a high-precision hard-timer." + return 0; +#endif +} + /**@}*/ diff --git a/src/device.c b/src/device.c index 32c06b380c..a4f004fb69 100644 --- a/src/device.c +++ b/src/device.c @@ -111,38 +111,7 @@ rt_err_t rt_device_init_all(void) */ rt_device_t rt_device_find(const char *name) { - struct rt_object *object; - struct rt_list_node *node; - struct rt_object_information *information; - - /* enter critical */ - if (rt_thread_self() != RT_NULL) - rt_enter_critical(); - - /* try to find device object */ - information = rt_object_get_information(RT_Object_Class_Device); - RT_ASSERT(information != RT_NULL); - for (node = information->object_list.next; - node != &(information->object_list); - node = node->next) - { - object = rt_list_entry(node, struct rt_object, list); - if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0) - { - /* leave critical */ - if (rt_thread_self() != RT_NULL) - rt_exit_critical(); - - return (rt_device_t)object; - } - } - - /* leave critical */ - if (rt_thread_self() != RT_NULL) - rt_exit_critical(); - - /* not found */ - return RT_NULL; + return (rt_device_t)rt_object_find(name, RT_Object_Class_Device); } RTM_EXPORT(rt_device_find); diff --git a/src/idle.c b/src/idle.c index 99db64f571..aa14552a49 100644 --- a/src/idle.c +++ b/src/idle.c @@ -150,82 +150,37 @@ void rt_thread_idle_excute(void) { /* Loop until there is no dead thread. So one call to rt_thread_idle_excute * will do all the cleanups. */ - while (_has_defunct_thread()) + /* disable interrupt */ + + RT_DEBUG_NOT_IN_INTERRUPT; + +#ifdef RT_USING_HEAP + while (1) { rt_base_t lock; rt_thread_t thread; -#ifdef RT_USING_MODULE - struct rt_dlmodule *module = RT_NULL; -#endif - RT_DEBUG_NOT_IN_INTERRUPT; - /* disable interrupt */ lock = rt_hw_interrupt_disable(); - /* re-check whether list is empty */ - if (_has_defunct_thread()) - { - /* get defunct thread */ - thread = rt_list_entry(rt_thread_defunct.next, - struct rt_thread, - tlist); -#ifdef RT_USING_MODULE - module = (struct rt_dlmodule*)thread->module_id; - if (module) - { - dlmodule_destroy(module); - } -#endif - /* remove defunct thread */ - rt_list_remove(&(thread->tlist)); - - /* lock scheduler to prevent scheduling in cleanup function. */ - rt_enter_critical(); - - /* invoke thread cleanup */ - 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) - { - /* detach this object */ - rt_object_detach((rt_object_t)thread); - /* unlock scheduler */ - rt_exit_critical(); - - /* enable interrupt */ - rt_hw_interrupt_enable(lock); - - return; - } - - /* unlock scheduler */ - rt_exit_critical(); - } - else + /* check whether list is empty */ + if (!_has_defunct_thread()) { - /* enable interrupt */ rt_hw_interrupt_enable(lock); - - /* may the defunct thread list is removed by others, just return */ - return; + break; } - - /* enable interrupt */ - rt_hw_interrupt_enable(lock); - -#ifdef RT_USING_HEAP + /* get defunct thread */ + thread = rt_list_entry(rt_thread_defunct.next, + struct rt_thread, + tlist); + /* remove defunct thread */ + rt_list_remove(&(thread->tlist)); /* release thread's stack */ RT_KERNEL_FREE(thread->stack_addr); /* delete thread object */ rt_object_delete((rt_object_t)thread); -#endif + rt_hw_interrupt_enable(lock); } +#endif } extern void rt_system_power_manager(void); @@ -37,7 +37,8 @@ * 2020-07-29 Meco Man fix thread->event_set/event_info when received an * event without pending * 2020-10-11 Meco Man add value overflow-check code - * 2020-10-25 hupu fix priority inversion bug of mutex + * 2021-01-03 Meco Man add rt_mb_urgent() + * 2021-01-20 hupu fix priority inversion bug of mutex */ #include <rtthread.h> @@ -1576,7 +1577,6 @@ rt_err_t rt_mb_send_wait(rt_mailbox_t mb, if (mb->entry == mb->size && timeout == 0) { rt_hw_interrupt_enable(temp); - return -RT_EFULL; } @@ -1698,6 +1698,71 @@ rt_err_t rt_mb_send(rt_mailbox_t mb, rt_ubase_t value) RTM_EXPORT(rt_mb_send); /** + * This function will send an urgent mail to mailbox object, if there are threads + * suspended on mailbox object, it will be waked up. This function will return + * immediately. + * + * @param mb the mailbox object + * @param value the mail + * + * @return the error code + */ +rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value) +{ + register rt_ubase_t temp; + + /* parameter check */ + RT_ASSERT(mb != RT_NULL); + RT_ASSERT(rt_object_get_type(&mb->parent.parent) == RT_Object_Class_MailBox); + + RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(mb->parent.parent))); + + /* disable interrupt */ + temp = rt_hw_interrupt_disable(); + + if (mb->entry == mb->size) + { + rt_hw_interrupt_enable(temp); + return -RT_EFULL; + } + + /* rewind to the previous position */ + if (mb->out_offset > 0) + { + mb->out_offset --; + } + else + { + mb->out_offset = mb->size - 1; + } + + /* set ptr */ + mb->msg_pool[mb->out_offset] = value; + + /* increase message entry */ + mb->entry ++; + + /* resume suspended thread */ + if (!rt_list_isempty(&mb->parent.suspend_thread)) + { + rt_ipc_list_resume(&(mb->parent.suspend_thread)); + + /* enable interrupt */ + rt_hw_interrupt_enable(temp); + + rt_schedule(); + + return RT_EOK; + } + + /* enable interrupt */ + rt_hw_interrupt_enable(temp); + + return RT_EOK; +} +RTM_EXPORT(rt_mb_urgent); + +/** * This function will receive a mail from mailbox object, if there is no mail * in mailbox object, the thread shall wait for a specified time. * @@ -1807,8 +1872,12 @@ rt_err_t rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeout) ++ mb->out_offset; if (mb->out_offset >= mb->size) mb->out_offset = 0; + /* decrease message entry */ - mb->entry --; + if(mb->entry > 0) + { + mb->entry --; + } /* resume suspended thread */ if (!rt_list_isempty(&(mb->suspend_sender_thread))) @@ -2482,7 +2551,10 @@ rt_err_t rt_mq_recv(rt_mq_t mq, mq->msg_queue_tail = RT_NULL; /* decrease message entry */ - mq->entry --; + if(mq->entry > 0) + { + mq->entry --; + } /* enable interrupt */ rt_hw_interrupt_enable(temp); diff --git a/src/kservice.c b/src/kservice.c index 7caf43ce28..3415a606eb 100644 --- a/src/kservice.c +++ b/src/kservice.c @@ -541,7 +541,7 @@ void rt_show_version(void) rt_kprintf("- RT - Thread Operating System\n"); rt_kprintf(" / | \\ %d.%d.%d build %s\n", RT_VERSION, RT_SUBVERSION, RT_REVISION, __DATE__); - rt_kprintf(" 2006 - 2020 Copyright by rt-thread team\n"); + rt_kprintf(" 2006 - 2021 Copyright by rt-thread team\n"); } RTM_EXPORT(rt_show_version); @@ -1116,7 +1116,7 @@ RTM_EXPORT(rt_console_get_device); * * @param name the name of new console device * - * @return the old console device handler + * @return the old console device handler on successful, or RT_NULL on failure. */ rt_device_t rt_console_set_device(const char *name) { @@ -1127,6 +1127,10 @@ rt_device_t rt_console_set_device(const char *name) /* find new console device */ new_device = rt_device_find(name); + + /* check whether it's a same device */ + if (new_device == old_device) return RT_NULL; + if (new_device != RT_NULL) { if (_console_device != RT_NULL) diff --git a/src/memheap.c b/src/memheap.c index aef56e1a74..afa06fb9bf 100644 --- a/src/memheap.c +++ b/src/memheap.c @@ -126,8 +126,8 @@ rt_err_t rt_memheap_detach(struct rt_memheap *heap) RT_ASSERT(heap); RT_ASSERT(rt_object_get_type(&heap->parent) == RT_Object_Class_MemHeap); RT_ASSERT(rt_object_is_systemobject(&heap->parent)); - - rt_object_detach(&(heap->lock.parent.parent)); + + rt_sem_detach(&heap->lock); rt_object_detach(&(heap->parent)); /* Return a successful completion. */ @@ -712,6 +712,20 @@ void *rt_calloc(rt_size_t count, rt_size_t size) } RTM_EXPORT(rt_calloc); +void rt_memory_info(rt_uint32_t *total, + rt_uint32_t *used, + rt_uint32_t *max_used) +{ + if (total != RT_NULL) + *total = _heap.pool_size; + + if (used != RT_NULL) + *used = _heap.pool_size - _heap.available_size; + + if (max_used != RT_NULL) + *max_used = _heap.max_used_size; +} + #endif #endif diff --git a/src/object.c b/src/object.c index 6866d805ca..56263618b3 100644 --- a/src/object.c +++ b/src/object.c @@ -192,18 +192,6 @@ void rt_object_put_sethook(void (*hook)(struct rt_object *object)) #endif /** - * @ingroup SystemInit - * - * This function will initialize system object management. - * - * @deprecated since 0.3.0, this function does not need to be invoked - * in the system initialization. - */ -void rt_system_object_init(void) -{ -} - -/** * @addtogroup KernelObject */ @@ -485,7 +473,7 @@ void rt_object_delete(rt_object_t object) RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object)); /* reset object type */ - object->type = 0; + object->type = RT_Object_Class_Null; /* lock interrupt */ temp = rt_hw_interrupt_disable(); diff --git a/src/scheduler.c b/src/scheduler.c index 2250c4a006..06f305ea0b 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -43,7 +43,7 @@ rt_uint8_t rt_thread_ready_table[32]; #ifndef RT_USING_SMP extern volatile rt_uint8_t rt_interrupt_nest; static rt_int16_t rt_scheduler_lock_nest; -struct rt_thread *rt_current_thread; +struct rt_thread *rt_current_thread = RT_NULL; rt_uint8_t rt_current_priority; #endif /*RT_USING_SMP*/ @@ -90,12 +90,7 @@ static void _rt_scheduler_stack_check(struct rt_thread *thread) rt_ubase_t level; rt_kprintf("thread:%s stack overflow\n", thread->name); -#ifdef RT_USING_FINSH - { - extern long list_thread(void); - list_thread(); - } -#endif + level = rt_hw_interrupt_disable(); while (level); } diff --git a/src/thread.c b/src/thread.c index 49e2022bf7..0db9dd8e4d 100644 --- a/src/thread.c +++ b/src/thread.c @@ -77,6 +77,31 @@ void rt_thread_inited_sethook(void (*hook)(rt_thread_t thread)) #endif +/* must be invoke witch rt_hw_interrupt_disable */ +static void _thread_cleanup_execute(rt_thread_t thread) +{ + register rt_base_t level; +#ifdef RT_USING_MODULE + struct rt_dlmodule *module = RT_NULL; +#endif + level = rt_hw_interrupt_disable(); +#ifdef RT_USING_MODULE + module = (struct rt_dlmodule*)thread->module_id; + if (module) + { + dlmodule_destroy(module); + } +#endif + /* invoke thread cleanup */ + if (thread->cleanup != RT_NULL) + thread->cleanup(thread); + +#ifdef RT_USING_SIGNALS + rt_thread_free_sig(thread); +#endif + rt_hw_interrupt_enable(level); +} + void rt_thread_exit(void) { struct rt_thread *thread; @@ -88,6 +113,8 @@ void rt_thread_exit(void) /* disable interrupt */ level = rt_hw_interrupt_disable(); + _thread_cleanup_execute(thread); + /* remove from schedule */ rt_schedule_remove_thread(thread); /* change stat */ @@ -96,8 +123,7 @@ void rt_thread_exit(void) /* remove it from timer list */ rt_timer_detach(&thread->thread_timer); - if ((rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) && - thread->cleanup == RT_NULL) + if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) { rt_object_detach((rt_object_t)thread); } @@ -347,14 +373,15 @@ rt_err_t rt_thread_detach(rt_thread_t thread) rt_schedule_remove_thread(thread); } + _thread_cleanup_execute(thread); + /* release thread timer */ rt_timer_detach(&(thread->thread_timer)); /* change stat */ thread->stat = RT_THREAD_CLOSE; - if ((rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) && - thread->cleanup == RT_NULL) + if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) { rt_object_detach((rt_object_t)thread); } @@ -449,6 +476,8 @@ rt_err_t rt_thread_delete(rt_thread_t thread) rt_schedule_remove_thread(thread); } + _thread_cleanup_execute(thread); + /* release thread timer */ rt_timer_detach(&(thread->thread_timer)); @@ -862,38 +891,7 @@ RTM_EXPORT(rt_thread_timeout); */ rt_thread_t rt_thread_find(char *name) { - struct rt_object_information *information; - struct rt_object *object; - struct rt_list_node *node; - - /* enter critical */ - if (rt_thread_self() != RT_NULL) - rt_enter_critical(); - - /* try to find device object */ - information = rt_object_get_information(RT_Object_Class_Thread); - RT_ASSERT(information != RT_NULL); - for (node = information->object_list.next; - node != &(information->object_list); - node = node->next) - { - object = rt_list_entry(node, struct rt_object, list); - if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0) - { - /* leave critical */ - if (rt_thread_self() != RT_NULL) - rt_exit_critical(); - - return (rt_thread_t)object; - } - } - - /* leave critical */ - if (rt_thread_self() != RT_NULL) - rt_exit_critical(); - - /* not found */ - return RT_NULL; + return (rt_thread_t)rt_object_find(name, RT_Object_Class_Thread); } RTM_EXPORT(rt_thread_find); diff --git a/src/timer.c b/src/timer.c index 4b9003794c..d882711151 100644 --- a/src/timer.c +++ b/src/timer.c @@ -331,7 +331,6 @@ rt_err_t rt_timer_start(rt_timer_t timer) _rt_timer_remove(timer); /* change status of timer */ timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; - rt_hw_interrupt_enable(level); RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(timer->parent))); @@ -342,9 +341,6 @@ rt_err_t rt_timer_start(rt_timer_t timer) RT_ASSERT(timer->init_tick < RT_TICK_MAX / 2); timer->timeout_tick = rt_tick_get() + timer->init_tick; - /* disable interrupt */ - level = rt_hw_interrupt_disable(); - #ifdef RT_USING_TIMER_SOFT if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER) { @@ -579,7 +575,7 @@ void rt_timer_check(void) { continue; } - + rt_list_remove(&(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1])); if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) && (t->parent.flag & RT_TIMER_FLAG_ACTIVATED)) { @@ -667,7 +663,7 @@ void rt_soft_timer_check(void) { continue; } - + rt_list_remove(&(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1])); if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) && (t->parent.flag & RT_TIMER_FLAG_ACTIVATED)) { |
