summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortmmdh <[email protected]>2021-01-20 18:45:20 +0800
committertmmdh <[email protected]>2021-01-20 18:45:20 +0800
commit9db4d446382426d215ffe79f60920c98a8b1be53 (patch)
treea3bd61199194d5f8251bf7ee889e22baedf5dc31 /src
parent55c0a9f27900d19556d52110be6397f3ee15a6c3 (diff)
parentafd575105d2fdd29fb003fb49c6e4f5446f824ce (diff)
Merge branch 'master' of https://github.com/RT-Thread/rt-thread
Diffstat (limited to 'src')
-rw-r--r--src/Kconfig14
-rw-r--r--src/SConscript13
-rw-r--r--src/clock.c28
-rw-r--r--src/device.c33
-rw-r--r--src/idle.c79
-rwxr-xr-xsrc/ipc.c80
-rw-r--r--src/kservice.c8
-rw-r--r--src/memheap.c18
-rw-r--r--src/object.c14
-rw-r--r--src/scheduler.c9
-rw-r--r--src/thread.c70
-rw-r--r--src/timer.c8
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);
diff --git a/src/ipc.c b/src/ipc.c
index 4c1d4a756a..d037708979 100755
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -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))
{