sync branch rt-smart. (#6641)

* Synchronize the code of the rt mart branch to the master branch.
  * TTY device
  * Add lwP code from rt-smart
  * Add vnode in DFS, but DFS will be re-write for rt-smart
  * There are three libcpu for rt-smart:
    * arm/cortex-a, arm/aarch64
    * riscv64

Co-authored-by: Rbb666 <zhangbingru@rt-thread.com>
Co-authored-by: zhkag <zhkag@foxmail.com>
This commit is contained in:
guo
2022-12-03 12:07:44 +08:00
committed by GitHub
co-authored by Rbb666 zhkag
parent aaf5462c6d
commit ecf2d82159
1693 changed files with 389530 additions and 9680 deletions
+22
View File
@@ -17,6 +17,13 @@ config RT_USING_ARCH_DATA_TYPE
Please re-define these data types in rtconfig_project.h file.
config RT_USING_SMART
bool "Enable RT-Thread Smart (microkernel on kernel/userland)"
default n
select RT_USING_LWP
help
RT-Thread Smart is a microkernel based operating system on RT-Thread.
config RT_USING_SMP
bool "Enable SMP(Symmetric multiprocessing)"
default n
@@ -407,6 +414,21 @@ menu "Kernel Device Object"
bool "Using ops for each device object"
default n
config RT_USING_DM
bool "Enable device driver model with device tree"
default n
help
Enable device driver model with device tree (FDT). It will use more memory
to parse and support device tree feature.
config RT_USING_DM_FDT
bool "Enablie builtin libfdt"
depends on RT_USING_DM
default y
help
libfdt - Flat Device Tree manipulation. If your code already contains the
libfdt, you can cancel this built-in libfdt to avoid link issue.
config RT_USING_INTERRUPT_INFO
bool "Enable additional interrupt trace information"
default n
+3
View File
@@ -27,6 +27,9 @@ if GetDepend('RT_USING_DEVICE') == False:
if GetDepend('RT_USING_SMP') == False:
SrcRemove(src, ['cpu.c'])
if GetDepend('RT_USING_DM') == False:
SrcRemove(src, ['driver.c'])
group = DefineGroup('Kernel', src, depend = [''], CPPPATH = inc, CPPDEFINES = ['__RTTHREAD__'])
Return('group')
+26 -2
View File
@@ -10,6 +10,10 @@
#include <rthw.h>
#include <rtthread.h>
#ifdef RT_USING_USERSPACE
#include <lwp.h>
#endif
#ifdef RT_USING_SMP
static struct rt_cpu _cpus[RT_CPUS_NR];
rt_hw_spinlock_t _cpus_lock;
@@ -64,6 +68,7 @@ static void _cpu_preempt_enable(void)
/* enable interrupt */
rt_hw_local_irq_enable(level);
}
#endif /* RT_USING_SMP */
/**
* @brief Initialize a static spinlock object.
@@ -72,7 +77,9 @@ static void _cpu_preempt_enable(void)
*/
void rt_spin_lock_init(struct rt_spinlock *lock)
{
#ifdef RT_USING_SMP
rt_hw_spin_lock_init(&lock->lock);
#endif
}
RTM_EXPORT(rt_spin_lock_init)
@@ -86,8 +93,12 @@ RTM_EXPORT(rt_spin_lock_init)
*/
void rt_spin_lock(struct rt_spinlock *lock)
{
#ifdef RT_USING_SMP
_cpu_preempt_disable();
rt_hw_spin_lock(&lock->lock);
#else
rt_enter_critical();
#endif
}
RTM_EXPORT(rt_spin_lock)
@@ -98,8 +109,12 @@ RTM_EXPORT(rt_spin_lock)
*/
void rt_spin_unlock(struct rt_spinlock *lock)
{
#ifdef RT_USING_SMP
rt_hw_spin_unlock(&lock->lock);
_cpu_preempt_enable();
#else
rt_exit_critical();
#endif
}
RTM_EXPORT(rt_spin_unlock)
@@ -115,6 +130,7 @@ RTM_EXPORT(rt_spin_unlock)
*/
rt_base_t rt_spin_lock_irqsave(struct rt_spinlock *lock)
{
#ifdef RT_USING_SMP
unsigned long level;
_cpu_preempt_disable();
@@ -123,6 +139,9 @@ rt_base_t rt_spin_lock_irqsave(struct rt_spinlock *lock)
rt_hw_spin_lock(&lock->lock);
return level;
#else
return rt_hw_interrupt_disable();
#endif
}
RTM_EXPORT(rt_spin_lock_irqsave)
@@ -135,10 +154,14 @@ RTM_EXPORT(rt_spin_lock_irqsave)
*/
void rt_spin_unlock_irqrestore(struct rt_spinlock *lock, rt_base_t level)
{
#ifdef RT_USING_SMP
rt_hw_spin_unlock(&lock->lock);
rt_hw_local_irq_enable(level);
_cpu_preempt_enable();
#else
rt_hw_interrupt_enable(level);
#endif
}
RTM_EXPORT(rt_spin_unlock_irqrestore)
@@ -223,6 +246,9 @@ void rt_cpus_lock_status_restore(struct rt_thread *thread)
{
struct rt_cpu* pcpu = rt_cpu_self();
#ifdef RT_USING_USERSPACE
lwp_mmu_switch(thread);
#endif
pcpu->current_thread = thread;
if (!thread->cpus_lock_nest)
{
@@ -230,5 +256,3 @@ void rt_cpus_lock_status_restore(struct rt_thread *thread)
}
}
RTM_EXPORT(rt_cpus_lock_status_restore);
#endif /* RT_USING_SMP */
+83
View File
@@ -457,4 +457,87 @@ rt_err_t rt_device_set_tx_complete(rt_device_t dev,
}
RTM_EXPORT(rt_device_set_tx_complete);
#ifdef RT_USING_DM
/**
* This function bind drvier and device
*
* @param driver the pointer of driver structure
* @param device the pointer of device structure
* @param node the pointer of fdt node structure
*
* @return the error code, RT_EOK on successfully.
*/
rt_err_t rt_device_bind_driver(rt_device_t device, rt_driver_t driver, void *node)
{
if((!driver) || (!device))
{
return -RT_EINVAL;
}
device->drv = driver;
#ifdef RT_USING_DEVICE_OPS
device->ops = driver->dev_ops;
#endif
device->dtb_node = node;
return RT_EOK;
}
RTM_EXPORT(rt_device_bind_driver);
/**
* This function create rt_device according to driver infomation
*
* @param drv the pointer of driver structure
* @param device_id specify the ID of the rt_device
*
* @return the error code, RT_EOK on successfully.
*/
rt_device_t rt_device_create_since_driver(rt_driver_t drv,int device_id)
{
rt_device_t device;
if (!drv)
{
return RT_NULL;
}
device = (rt_device_t)rt_calloc(1,drv->device_size);
if(device == RT_NULL)
{
return RT_NULL;
}
device->device_id = device_id;
rt_snprintf(device->parent.name, sizeof(device->parent.name), "%s%d", drv->name, device_id);
return device;
}
RTM_EXPORT(rt_device_create_since_driver);
/**
* This function rt_device probe and init
*
* @param device the pointer of rt_device structure
* @return the error code, RT_EOK on successfully.
*/
rt_err_t rt_device_probe_and_init(rt_device_t device)
{
int ret = -RT_ERROR;
if (!device)
{
return -RT_EINVAL;
}
if(!device->drv)
{
return -RT_ERROR;
}
if(device->drv->probe)
{
ret = device->drv->probe((rt_device_t)device);
}
if(device->drv->probe_init)
{
ret = device->drv->probe_init((rt_device_t)device);
}
return ret;
}
RTM_EXPORT(rt_device_probe_and_init);
#endif /* RT_USING_DM */
#endif /* RT_USING_DEVICE */
+113
View File
@@ -0,0 +1,113 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <rtthread.h>
#ifdef RT_USING_FDT
#include <dtb_node.h>
#endif
#if defined(RT_USING_POSIX_DEVIO)
#include <rtdevice.h> /* for wqueue_init */
#endif
/**
* This function driver device match with id
*
* @param drv the pointer of driver structure
* @param device_id the id of the device
*
* @return the error code, RT_EOK on successfully.
*/
rt_err_t rt_driver_match_with_id(const rt_driver_t drv,int device_id)
{
rt_device_t device;
int ret;
if (!drv)
{
return -RT_EINVAL;
}
device = rt_device_create_since_driver(drv,device_id);
if(!device)
{
return -RT_ERROR;
}
ret = rt_device_bind_driver(device,drv,RT_NULL);
if(ret != 0)
{
return -RT_ERROR;
}
ret = rt_device_probe_and_init(device);
if(ret != 0)
{
return -RT_ERROR;
}
return ret;
}
RTM_EXPORT(rt_driver_match_with_id);
#ifdef RT_USING_FDT
/**
* This function driver device match with dtb_node
*
* @param drv the pointer of driver structure
* @param from_node dtb node entry
* @param max_dev_num the max device support
*
* @return the error code, RT_EOK on successfully.
*/
rt_err_t rt_driver_match_with_dtb(const rt_driver_t drv,void *from_node,int max_dev_num)
{
struct dtb_node** node_list;
rt_device_t device;
int ret,i;
int total_dev_num = 0;
if ((!drv)||(!drv->dev_match)||(!drv->dev_match->compatible)||(!from_node)||(!drv->device_size))
{
return -RT_EINVAL;
}
node_list = rt_calloc(max_dev_num,sizeof(void *));
if(!node_list)
{
return -RT_ERROR;
}
ret = dtb_node_find_all_compatible_node(from_node,drv->dev_match->compatible,node_list,max_dev_num,&total_dev_num);
if((ret != 0) || (!total_dev_num))
{
return -RT_ERROR;
}
for(i = 0; i < total_dev_num; i ++)
{
if (!dtb_node_device_is_available(node_list[i]))
{
continue;
}
device = rt_device_create_since_driver(drv,i);
if(!device)
{
continue;
}
ret = rt_device_bind_driver(device,drv,node_list[i]);
if(ret != 0)
{
continue;
}
ret = rt_device_probe_and_init(device);
if(ret != 0)
{
continue;
}
}
rt_free(node_list);
return ret;
}
RTM_EXPORT(rt_driver_match_with_dtb);
#endif
+299 -51
View File
File diff suppressed because it is too large Load Diff
+68 -19
View File
@@ -32,6 +32,12 @@
#include <dlmodule.h>
#endif /* RT_USING_MODULE */
#ifdef RT_USING_LWP
#include <lwp.h>
#include <lwp_user_mm.h>
#include <console.h>
#endif
/* use precision */
#define RT_PRINTF_PRECISION
@@ -96,7 +102,7 @@ RTM_EXPORT(rt_strerror);
*/
rt_err_t rt_get_errno(void)
{
rt_thread_t tid;
rt_thread_t tid = RT_NULL;
if (rt_interrupt_get_nest() != 0)
{
@@ -106,7 +112,9 @@ rt_err_t rt_get_errno(void)
tid = rt_thread_self();
if (tid == RT_NULL)
{
return __rt_errno;
}
return tid->error;
}
@@ -119,7 +127,7 @@ RTM_EXPORT(rt_get_errno);
*/
void rt_set_errno(rt_err_t error)
{
rt_thread_t tid;
rt_thread_t tid = RT_NULL;
if (rt_interrupt_get_nest() != 0)
{
@@ -148,14 +156,18 @@ RTM_EXPORT(rt_set_errno);
*/
int *_rt_errno(void)
{
rt_thread_t tid;
rt_thread_t tid = RT_NULL;
if (rt_interrupt_get_nest() != 0)
{
return (int *)&__rt_errno;
}
tid = rt_thread_self();
if (tid != RT_NULL)
{
return (int *) & (tid->error);
}
return (int *)&__rt_errno;
}
@@ -188,10 +200,10 @@ RT_WEAK void *rt_memset(void *s, int c, rt_ubase_t count)
#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
unsigned int i;
unsigned int i = 0;
char *m = (char *)s;
unsigned long buffer;
unsigned long *aligned_addr;
unsigned long buffer = 0;
unsigned long *aligned_addr = RT_NULL;
unsigned char d = (unsigned int)c & (unsigned char)(-1); /* To avoid sign extension, copy C to an
unsigned variable. (unsigned)((char)(-1))=0xFF for 8bit and =0xFFFF for 16bit: word independent */
@@ -258,7 +270,7 @@ RT_WEAK void *rt_memcpy(void *dst, const void *src, rt_ubase_t count)
{
#ifdef RT_KSERVICE_USING_TINY_SIZE
char *tmp = (char *)dst, *s = (char *)src;
rt_ubase_t len;
rt_ubase_t len = 0;
if (tmp <= s || tmp > (s + count))
{
@@ -282,8 +294,8 @@ RT_WEAK void *rt_memcpy(void *dst, const void *src, rt_ubase_t count)
char *dst_ptr = (char *)dst;
char *src_ptr = (char *)src;
long *aligned_dst;
long *aligned_src;
long *aligned_dst = RT_NULL;
long *aligned_src = RT_NULL;
rt_ubase_t len = count;
/* If the size is small, or either SRC or DST is unaligned,
@@ -378,7 +390,7 @@ RTM_EXPORT(rt_memmove);
*/
rt_int32_t rt_memcmp(const void *cs, const void *ct, rt_size_t count)
{
const unsigned char *su1, *su2;
const unsigned char *su1 = RT_NULL, *su2 = RT_NULL;
int res = 0;
for (su1 = (const unsigned char *)cs, su2 = (const unsigned char *)ct; 0 < count; ++su1, ++su2, count--)
@@ -403,17 +415,23 @@ RTM_EXPORT(rt_memcmp);
*/
char *rt_strstr(const char *s1, const char *s2)
{
int l1, l2;
int l1 = 0, l2 = 0;
l2 = rt_strlen(s2);
if (!l2)
return (char *)s1;
{
return (char *)s1;
}
l1 = rt_strlen(s1);
while (l1 >= l2)
{
l1 --;
if (!rt_memcmp(s1, s2, l2))
return (char *)s1;
{
return (char *)s1;
}
s1 ++;
}
@@ -435,7 +453,7 @@ RTM_EXPORT(rt_strstr);
*/
rt_int32_t rt_strcasecmp(const char *a, const char *b)
{
int ca, cb;
int ca = 0, cb = 0;
do
{
@@ -476,7 +494,10 @@ char *rt_strncpy(char *dst, const char *src, rt_size_t n)
{
/* NUL pad the remaining n-1 bytes */
while (--n != 0)
*d++ = 0;
{
*d++ = 0;
}
break;
}
} while (--n != 0);
@@ -532,7 +553,10 @@ rt_int32_t rt_strncmp(const char *cs, const char *ct, rt_size_t count)
while (count)
{
if ((__res = *cs - *ct++) != 0 || !*cs++)
break;
{
break;
}
count --;
}
@@ -574,7 +598,7 @@ RTM_EXPORT(rt_strcmp);
*/
rt_size_t rt_strlen(const char *s)
{
const char *sc;
const char *sc = RT_NULL;
for (sc = s; *sc != '\0'; ++sc) /* nothing */
;
@@ -623,7 +647,9 @@ char *rt_strdup(const char *s)
char *tmp = (char *)rt_malloc(len);
if (!tmp)
return RT_NULL;
{
return RT_NULL;
}
rt_memcpy(tmp, s, len);
@@ -1230,6 +1256,28 @@ RTM_EXPORT(rt_console_get_device);
*/
rt_device_t rt_console_set_device(const char *name)
{
#ifdef RT_USING_LWP
rt_device_t new_iodev = RT_NULL, old_iodev = RT_NULL;
extern void console_init();
console_init(); /*add line discipline*/
/* find new console device */
new_iodev = rt_device_find(name);
if (new_iodev != RT_NULL)
{
if (_console_device != RT_NULL)
{
old_iodev = console_set_iodev(new_iodev);
}
else
{
console_register("console", new_iodev);
_console_device = rt_device_find("console");
rt_device_open(_console_device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_STREAM);
}
}
return old_iodev;
#else
rt_device_t new_device, old_device;
/* save old device */
@@ -1255,6 +1303,7 @@ rt_device_t rt_console_set_device(const char *name)
}
return old_device;
#endif
}
RTM_EXPORT(rt_console_set_device);
#endif /* RT_USING_DEVICE */
@@ -1702,7 +1751,7 @@ RTM_EXPORT(rt_malloc_align);
*/
RT_WEAK void rt_free_align(void *ptr)
{
void *real_ptr;
void *real_ptr = RT_NULL;
/* NULL check */
if (ptr == RT_NULL) return;
+78
View File
@@ -23,6 +23,17 @@
#include <dlmodule.h>
#endif /* RT_USING_MODULE */
#ifdef RT_USING_LWP
#include <lwp.h>
#endif
struct rt_custom_object
{
struct rt_object parent;
rt_err_t (*destroy)(void *);
void *data;
};
/*
* define object_info for the number of _object_container items.
*/
@@ -59,6 +70,12 @@ enum rt_object_info_type
#endif
#ifdef RT_USING_HEAP
RT_Object_Info_Memory, /**< The object is a memory. */
#endif
#ifdef RT_USING_LWP
RT_Object_Info_Channel, /**< The object is a IPC channel */
#endif
#ifdef RT_USING_HEAP
RT_Object_Info_Custom, /**< The object is a custom object */
#endif
RT_Object_Info_Unknown, /**< The object is unknown. */
};
@@ -112,6 +129,11 @@ static struct rt_object_information _object_container[RT_Object_Info_Unknown] =
/* initialize object container - small memory */
{RT_Object_Class_Memory, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Memory), sizeof(struct rt_memory)},
#endif
#ifdef RT_USING_LWP
/* initialize object container - module */
{RT_Object_Class_Channel, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Channel), sizeof(struct rt_channel)},
{RT_Object_Class_Custom, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Custom), sizeof(struct rt_custom_object)},
#endif
};
#ifndef __on_rt_object_attach_hook
@@ -607,4 +629,60 @@ rt_object_t rt_object_find(const char *name, rt_uint8_t type)
return RT_NULL;
}
#ifdef RT_USING_HEAP
/**
* This function will create a custom object
* container.
*
* @param name the specified name of object.
* @param type the type of object
* @param data the custom data
* @param data_destroy the custom object destroy callback
*
* @return the found object or RT_NULL if there is no this object
* in object container.
*
* @note this function shall not be invoked in interrupt status.
*/
rt_object_t rt_custom_object_create(const char *name, void *data, rt_err_t (*data_destroy)(void *))
{
struct rt_custom_object *cobj = RT_NULL;
cobj = (struct rt_custom_object *)rt_object_allocate(RT_Object_Class_Custom, name);
if (!cobj)
{
return RT_NULL;
}
cobj->destroy = data_destroy;
cobj->data = data;
return (struct rt_object *)cobj;
}
/**
* This function will destroy a custom object
* container.
*
* @param obj the specified name of object.
*
* @note this function shall not be invoked in interrupt status.
*/
rt_err_t rt_custom_object_destroy(rt_object_t obj)
{
rt_err_t ret = -1;
struct rt_custom_object *cobj = (struct rt_custom_object *)obj;
if (obj && obj->type == RT_Object_Class_Custom)
{
if (cobj->destroy)
{
ret = cobj->destroy(cobj->data);
}
rt_object_delete(obj);
}
return ret;
}
#endif
/**@}*/
+54 -15
View File
@@ -33,6 +33,10 @@
#include <rtthread.h>
#include <rthw.h>
#ifdef RT_USING_LWP
#include <lwp.h>
#endif /* RT_USING_LWP */
rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];
rt_uint32_t rt_thread_ready_priority_group;
#if RT_THREAD_PRIORITY_MAX > 32
@@ -94,6 +98,19 @@ static void _scheduler_stack_check(struct rt_thread *thread)
{
RT_ASSERT(thread != RT_NULL);
#ifdef RT_USING_LWP
#ifndef ARCH_MM_MMU
struct rt_lwp *lwp = thread ? (struct rt_lwp *)thread->lwp : 0;
/* if stack pointer locate in user data section skip stack check. */
if (lwp && ((rt_uint32_t)thread->sp > (rt_uint32_t)lwp->data_entry &&
(rt_uint32_t)thread->sp <= (rt_uint32_t)lwp->data_entry + (rt_uint32_t)lwp->data_size))
{
return;
}
#endif /* not defined ARCH_MM_MMU */
#endif /* RT_USING_LWP */
#ifdef ARCH_CPU_STACK_GROWS_UPWARD
if (*((rt_uint8_t *)((rt_ubase_t)thread->stack_addr + thread->stack_size - 1)) != '#' ||
#else
@@ -322,13 +339,17 @@ void rt_schedule(void)
}
#ifdef RT_USING_SIGNALS
if ((current_thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)
if ((current_thread->stat & RT_THREAD_SUSPEND_MASK) == RT_THREAD_SUSPEND_MASK)
{
/* if current_thread signal is in pending */
if ((current_thread->stat & RT_THREAD_STAT_SIGNAL_MASK) & RT_THREAD_STAT_SIGNAL_PENDING)
{
#ifdef RT_USING_LWP
rt_thread_wakeup(current_thread);
#else
rt_thread_resume(current_thread);
#endif
}
}
#endif /* RT_USING_SIGNALS */
@@ -343,13 +364,20 @@ void rt_schedule(void)
current_thread->oncpu = RT_CPU_DETACHED;
if ((current_thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_RUNNING)
{
if (current_thread->current_priority < highest_ready_priority)
if (current_thread->bind_cpu == RT_CPUS_NR || current_thread->bind_cpu == cpu_id)
{
to_thread = current_thread;
}
else if (current_thread->current_priority == highest_ready_priority && (current_thread->stat & RT_THREAD_STAT_YIELD_MASK) == 0)
{
to_thread = current_thread;
if (current_thread->current_priority < highest_ready_priority)
{
to_thread = current_thread;
}
else if (current_thread->current_priority == highest_ready_priority && (current_thread->stat & RT_THREAD_STAT_YIELD_MASK) == 0)
{
to_thread = current_thread;
}
else
{
rt_schedule_insert_thread(current_thread);
}
}
else
{
@@ -526,7 +554,7 @@ void rt_schedule(void)
RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("switch in interrupt\n"));
rt_hw_context_switch_interrupt((rt_ubase_t)&from_thread->sp,
(rt_ubase_t)&to_thread->sp);
(rt_ubase_t)&to_thread->sp, from_thread, to_thread);
}
}
else
@@ -566,13 +594,17 @@ void rt_scheduler_do_irq_switch(void *context)
current_thread = pcpu->current_thread;
#ifdef RT_USING_SIGNALS
if ((current_thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)
if ((current_thread->stat & RT_THREAD_SUSPEND_MASK) == RT_THREAD_SUSPEND_MASK)
{
/* if current_thread signal is in pending */
if ((current_thread->stat & RT_THREAD_STAT_SIGNAL_MASK) & RT_THREAD_STAT_SIGNAL_PENDING)
{
#ifdef RT_USING_LWP
rt_thread_wakeup(current_thread);
#else
rt_thread_resume(current_thread);
#endif
}
}
#endif /* RT_USING_SIGNALS */
@@ -596,13 +628,20 @@ void rt_scheduler_do_irq_switch(void *context)
current_thread->oncpu = RT_CPU_DETACHED;
if ((current_thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_RUNNING)
{
if (current_thread->current_priority < highest_ready_priority)
if (current_thread->bind_cpu == RT_CPUS_NR || current_thread->bind_cpu == cpu_id)
{
to_thread = current_thread;
}
else if (current_thread->current_priority == highest_ready_priority && (current_thread->stat & RT_THREAD_STAT_YIELD_MASK) == 0)
{
to_thread = current_thread;
if (current_thread->current_priority < highest_ready_priority)
{
to_thread = current_thread;
}
else if (current_thread->current_priority == highest_ready_priority && (current_thread->stat & RT_THREAD_STAT_YIELD_MASK) == 0)
{
to_thread = current_thread;
}
else
{
rt_schedule_insert_thread(current_thread);
}
}
else
{
+7 -3
View File
@@ -102,10 +102,14 @@ static void _signal_deliver(rt_thread_t tid)
return;
}
if ((tid->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)
if ((tid->stat & RT_THREAD_SUSPEND_MASK) == RT_THREAD_SUSPEND_MASK)
{
/* resume thread to handle signal */
#ifdef RT_USING_LWP
rt_thread_wakeup(tid);
#else
rt_thread_resume(tid);
#endif
/* add signal state */
tid->stat |= (RT_THREAD_STAT_SIGNAL | RT_THREAD_STAT_SIGNAL_PENDING);
@@ -197,7 +201,7 @@ void *rt_signal_check(void* context)
rt_hw_interrupt_enable(level);
sig_context = rt_hw_stack_init((void *)_signal_entry, context,
(void *)(context - 32), RT_NULL);
(void*)((char*)context - 32), RT_NULL);
return sig_context;
}
}
@@ -350,7 +354,7 @@ int rt_signal_wait(const rt_sigset_t *set, rt_siginfo_t *si, rt_int32_t timeout)
}
/* suspend self thread */
rt_thread_suspend(tid);
rt_thread_suspend_with_flag(tid, RT_UNINTERRUPTIBLE);
/* set thread stat as waiting for signal */
tid->stat |= RT_THREAD_STAT_SIGNAL_WAIT;
+202 -32
View File
@@ -133,7 +133,7 @@ static void _thread_timeout(void *parameter)
/* parameter check */
RT_ASSERT(thread != RT_NULL);
RT_ASSERT((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND);
RT_ASSERT((thread->stat & RT_THREAD_SUSPEND_MASK) == RT_THREAD_SUSPEND_MASK);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
/* disable interrupt */
@@ -167,6 +167,10 @@ static rt_err_t _thread_init(struct rt_thread *thread,
/* init thread list */
rt_list_init(&(thread->tlist));
#ifdef RT_USING_LWP
thread->wakeup.func = RT_NULL;
#endif
thread->entry = (void *)entry;
thread->parameter = parameter;
@@ -253,7 +257,13 @@ static rt_err_t _thread_init(struct rt_thread *thread,
#ifdef RT_USING_LWP
thread->lwp = RT_NULL;
#endif /* RT_USING_LWP */
rt_list_init(&(thread->sibling));
rt_memset(&thread->signal, 0, sizeof(lwp_sigset_t));
rt_memset(&thread->signal_mask, 0, sizeof(lwp_sigset_t));
thread->signal_mask_bak = 0;
thread->signal_in_process = 0;
rt_memset(&thread->user_ctx, 0, sizeof thread->user_ctx);
#endif
#ifdef RT_USING_CPU_USAGE
thread->duration_tick = 0;
@@ -598,6 +608,7 @@ rt_err_t rt_thread_sleep(rt_tick_t tick)
{
rt_base_t level;
struct rt_thread *thread;
int err;
if (tick == 0)
{
@@ -619,22 +630,31 @@ rt_err_t rt_thread_sleep(rt_tick_t tick)
thread->error = RT_EOK;
/* suspend thread */
rt_thread_suspend(thread);
err = rt_thread_suspend_with_flag(thread, RT_INTERRUPTIBLE);
/* reset the timeout of thread timer and start it */
rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &tick);
rt_timer_start(&(thread->thread_timer));
if (err == RT_EOK)
{
rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &tick);
rt_timer_start(&(thread->thread_timer));
/* enable interrupt */
rt_hw_interrupt_enable(level);
/* enable interrupt */
rt_hw_interrupt_enable(level);
rt_schedule();
thread->error = -RT_EINTR;
rt_schedule();
/* clear error number of this thread to RT_EOK */
if (thread->error == -RT_ETIMEOUT)
thread->error = RT_EOK;
/* clear error number of this thread to RT_EOK */
if (thread->error == -RT_ETIMEOUT)
thread->error = RT_EOK;
}
else
{
rt_hw_interrupt_enable(level);
}
return thread->error;
return err;
}
/**
@@ -689,7 +709,7 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick)
left_tick = *tick - cur_tick;
/* suspend thread */
rt_thread_suspend(thread);
rt_thread_suspend_with_flag(thread, RT_UNINTERRUPTIBLE);
/* reset the timeout of thread timer and start it */
rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &left_tick);
@@ -734,6 +754,66 @@ rt_err_t rt_thread_mdelay(rt_int32_t ms)
}
RTM_EXPORT(rt_thread_mdelay);
#ifdef RT_USING_SMP
static void rt_thread_cpu_bind(rt_thread_t thread, int cpu)
{
rt_base_t level;
if (cpu >= RT_CPUS_NR)
{
cpu = RT_CPUS_NR;
}
level = rt_hw_interrupt_disable();
if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_READY)
{
/* unbind */
/* remove from old ready queue */
rt_schedule_remove_thread(thread);
/* change thread bind cpu */
thread->bind_cpu = cpu;
/* add to new ready queue */
rt_schedule_insert_thread(thread);
if (rt_thread_self() != RT_NULL)
{
rt_schedule();
}
}
else
{
thread->bind_cpu = cpu;
if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_RUNNING)
{
/* thread is running on a cpu */
int current_cpu = rt_hw_cpu_id();
if (cpu != RT_CPUS_NR)
{
if (thread->oncpu == current_cpu)
{
/* current thread on current cpu */
if (cpu != current_cpu)
{
/* bind to other cpu */
rt_hw_ipi_send(RT_SCHEDULE_IPI, 1U << cpu);
/* self cpu need reschedule */
rt_schedule();
}
/* else do nothing */
}
else
{
/* no running on self cpu, but dest cpu can be itself */
rt_hw_ipi_send(RT_SCHEDULE_IPI, 1U << thread->oncpu);
}
}
/* else do nothing */
}
}
rt_hw_interrupt_enable(level);
}
#endif
/**
* @brief This function will control thread behaviors according to control command.
*
@@ -837,26 +917,46 @@ rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg)
{
rt_uint8_t cpu;
if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT)
{
/* we only support bind cpu before started phase. */
return RT_ERROR;
}
cpu = (rt_uint8_t)(rt_size_t)arg;
thread->bind_cpu = cpu > RT_CPUS_NR? RT_CPUS_NR : cpu;
break;
}
#endif /* RT_USING_SMP */
default:
break;
cpu = (rt_uint8_t)(size_t)arg;
rt_thread_cpu_bind(thread, cpu);
break;
}
#endif /*RT_USING_SMP*/
default:
break;
}
return RT_EOK;
}
RTM_EXPORT(rt_thread_control);
#ifdef RT_USING_LWP
int lwp_suspend_sigcheck(rt_thread_t thread, int suspend_flag);
#endif
static void rt_thread_set_suspend_state(struct rt_thread *thread, int suspend_flag)
{
rt_uint8_t stat = RT_THREAD_SUSPEND_UNINTERRUPTIBLE;
RT_ASSERT(thread != RT_NULL);
switch (suspend_flag)
{
case RT_INTERRUPTIBLE:
stat = RT_THREAD_SUSPEND_INTERRUPTIBLE;
break;
case RT_KILLABLE:
stat = RT_THREAD_SUSPEND_KILLABLE;
break;
case RT_UNINTERRUPTIBLE:
stat = RT_THREAD_SUSPEND_UNINTERRUPTIBLE;
break;
default:
RT_ASSERT(0);
break;
}
thread->stat = stat | (thread->stat & ~RT_THREAD_STAT_MASK);
}
/**
* @brief This function will suspend the specified thread and change it to suspend state.
*
@@ -872,7 +972,7 @@ RTM_EXPORT(rt_thread_control);
* @return Return the operation status. If the return value is RT_EOK, the function is successfully executed.
* If the return value is any other values, it means this operation failed.
*/
rt_err_t rt_thread_suspend(rt_thread_t thread)
rt_err_t rt_thread_suspend_with_flag(rt_thread_t thread, int suspend_flag)
{
rt_base_t stat;
rt_base_t level;
@@ -893,10 +993,24 @@ rt_err_t rt_thread_suspend(rt_thread_t thread)
/* disable interrupt */
level = rt_hw_interrupt_disable();
if (stat == RT_THREAD_RUNNING)
{
/* not suspend running status thread on other core */
RT_ASSERT(thread == rt_thread_self());
}
#ifdef RT_USING_LWP
if (lwp_suspend_sigcheck(thread, suspend_flag) == 0)
{
/* not to suspend */
rt_hw_interrupt_enable(level);
rt_kprintf("-RT_EINTR\r\n");
return -RT_EINTR;
}
#endif
/* change thread stat */
rt_schedule_remove_thread(thread);
thread->stat = RT_THREAD_SUSPEND | (thread->stat & ~RT_THREAD_STAT_MASK);
rt_thread_set_suspend_state(thread, suspend_flag);
/* stop thread timer anyway */
rt_timer_stop(&(thread->thread_timer));
@@ -907,6 +1021,12 @@ rt_err_t rt_thread_suspend(rt_thread_t thread)
RT_OBJECT_HOOK_CALL(rt_thread_suspend_hook, (thread));
return RT_EOK;
}
RTM_EXPORT(rt_thread_suspend_with_flag);
rt_err_t rt_thread_suspend(rt_thread_t thread)
{
return rt_thread_suspend_with_flag(thread, RT_UNINTERRUPTIBLE);
}
RTM_EXPORT(rt_thread_suspend);
/**
@@ -927,7 +1047,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_STAT_MASK) != RT_THREAD_SUSPEND)
if ((thread->stat & RT_THREAD_SUSPEND_MASK) != RT_THREAD_SUSPEND_MASK)
{
RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread resume: thread disorder, %d\n",
thread->stat));
@@ -943,17 +1063,67 @@ rt_err_t rt_thread_resume(rt_thread_t thread)
rt_timer_stop(&thread->thread_timer);
/* insert to schedule ready list */
rt_schedule_insert_thread(thread);
#ifdef RT_USING_LWP
thread->wakeup.func = RT_NULL;
#endif
/* enable interrupt */
rt_hw_interrupt_enable(level);
/* insert to schedule ready list */
rt_schedule_insert_thread(thread);
RT_OBJECT_HOOK_CALL(rt_thread_resume_hook, (thread));
return RT_EOK;
}
RTM_EXPORT(rt_thread_resume);
#ifdef RT_USING_LWP
/**
* This function will wakeup a thread with customized operation.
*
* @param thread the thread to be resumed
*
* @return the operation status, RT_EOK on OK, -RT_ERROR on error
*/
rt_err_t rt_thread_wakeup(rt_thread_t thread)
{
register rt_base_t temp;
rt_err_t ret;
RT_ASSERT(thread != RT_NULL);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
/* disable interrupt */
temp = rt_hw_interrupt_disable();
if (thread->wakeup.func)
{
ret = thread->wakeup.func(thread->wakeup.user_data, thread);
thread->wakeup.func = RT_NULL;
}
else
{
ret = rt_thread_resume(thread);
}
rt_hw_interrupt_enable(temp);
return ret;
}
RTM_EXPORT(rt_thread_wakeup);
void rt_thread_wakeup_set(struct rt_thread *thread, rt_wakeup_func_t func, void* user_data)
{
register rt_base_t temp;
RT_ASSERT(thread != RT_NULL);
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
temp = rt_hw_interrupt_disable();
thread->wakeup.func = func;
thread->wakeup.user_data = user_data;
rt_hw_interrupt_enable(temp);
}
RTM_EXPORT(rt_thread_wakeup_set);
#endif
/**
* @brief This function will find the specified thread.
*
+24 -6
View File
@@ -502,7 +502,7 @@ rt_err_t rt_timer_start(rt_timer_t timer)
{
/* check whether timer thread is ready */
if ((_soft_timer_status == RT_SOFT_TIMER_IDLE) &&
((_timer_thread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND))
((_timer_thread.stat & RT_THREAD_SUSPEND_MASK) == RT_THREAD_SUSPEND_MASK))
{
/* resume timer thread to check soft timer */
rt_thread_resume(&_timer_thread);
@@ -534,18 +534,21 @@ rt_err_t rt_timer_stop(rt_timer_t timer)
{
rt_base_t level;
/* parameter check */
/* disable interrupt */
level = rt_hw_interrupt_disable();
/* timer check */
RT_ASSERT(timer != RT_NULL);
RT_ASSERT(rt_object_get_type(&timer->parent) == RT_Object_Class_Timer);
if (!(timer->parent.flag & RT_TIMER_FLAG_ACTIVATED))
{
rt_hw_interrupt_enable(level);
return -RT_ERROR;
}
RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(timer->parent)));
/* disable interrupt */
level = rt_hw_interrupt_disable();
_timer_remove(timer);
/* change status */
timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
@@ -610,6 +613,21 @@ rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg)
case RT_TIMER_CTRL_GET_REMAIN_TIME:
*(rt_tick_t *)arg = timer->timeout_tick;
break;
case RT_TIMER_CTRL_GET_FUNC:
*(void **)arg = timer->timeout_func;
break;
case RT_TIMER_CTRL_SET_FUNC:
timer->timeout_func = (void (*)(void*))arg;
break;
case RT_TIMER_CTRL_GET_PARM:
*(void **)arg = timer->parameter;
break;
case RT_TIMER_CTRL_SET_PARM:
timer->parameter = arg;
break;
default:
break;
@@ -801,7 +819,7 @@ static void _timer_thread_entry(void *parameter)
if (_timer_list_next_timeout(_soft_timer_list, &next_timeout) != RT_EOK)
{
/* no software timer exist, suspend self. */
rt_thread_suspend(rt_thread_self());
rt_thread_suspend_with_flag(rt_thread_self(), RT_UNINTERRUPTIBLE);
rt_schedule();
}
else