为rtt驱动提供更多的借口支持
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -247,7 +247,8 @@
|
||||
"limits.h": "c",
|
||||
"ctime": "c",
|
||||
"pthread_impl.h": "c",
|
||||
"time.h": "c"
|
||||
"time.h": "c",
|
||||
"u_thread_util.h": "c"
|
||||
},
|
||||
"cortex-debug.showRTOS": false,
|
||||
"cortex-debug.variableUseNaturalFormat": false,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
export TOOLCHAIN=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/
|
||||
export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/lib/gcc/arm-none-eabi/5.4.1/armv7-m
|
||||
# export TOOLCHAIN=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/
|
||||
# export TOOLCHAIN_LIB=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp
|
||||
# export TOOLCHAIN=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/
|
||||
# export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/lib/gcc/arm-none-eabi/5.4.1/armv7-m
|
||||
export TOOLCHAIN=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/
|
||||
export TOOLCHAIN_LIB=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp
|
||||
export KEN_OFFSET=0x2000
|
||||
export INIT_OFFSET=0x10000
|
||||
export BOOTFS_ADDR_OFFSET=0x20000
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
#include <u_types.h>
|
||||
|
||||
void u_thread_del(obj_handler_t th_hd);
|
||||
int u_thread_create(obj_handler_t *th_hd, void *stack, umword_t stack_size, void *msg_buf, void (*thread_func)(void), int prio);
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
#include <u_task.h>
|
||||
#include <u_hd_man.h>
|
||||
#include <u_thread_util.h>
|
||||
void u_thread_del(obj_handler_t th_hd)
|
||||
{
|
||||
task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, th_hd));
|
||||
}
|
||||
int u_thread_create(obj_handler_t *th_hd, void *stack, umword_t stack_size, void *msg_buf, void (*thread_func)(void), int prio)
|
||||
{
|
||||
assert(th_hd);
|
||||
@@ -31,7 +35,7 @@ int u_thread_create(obj_handler_t *th_hd, void *stack, umword_t stack_size, void
|
||||
handler_free_umap(th1_hd);
|
||||
return msg_tag_get_prot(tag);
|
||||
}
|
||||
tag = thread_exec_regs(th1_hd, (umword_t)thread_func, (umword_t)stack + stack_size, RAM_BASE(), 0);
|
||||
tag = thread_exec_regs(th1_hd, (umword_t)thread_func, (umword_t)stack + stack_size - sizeof(void *), RAM_BASE(), 0);
|
||||
if (msg_tag_get_prot(tag) < 0)
|
||||
{
|
||||
handler_free_umap(th1_hd);
|
||||
|
||||
@@ -12,6 +12,8 @@ include_directories(
|
||||
${CMAKE_CURRENT_LIST_DIR}/
|
||||
${CMAKE_CURRENT_LIST_DIR}/inc
|
||||
${CMAKE_CURRENT_LIST_DIR}/components/drivers/include
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/util/inc
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/server/drv/rtthread_drv/bsp/stm32/stm32f103-onenet-nbiot/board
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/server/drv/rtthread_drv/bsp/stm32/libraries/STM32F1xx_HAL/CMSIS/Device/ST/STM32F1xx/Include
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/server/drv/rtthread_drv/bsp/stm32/libraries/HAL_Drivers
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
4
mkrtos_user/server/drv/rtthread_drv/inc/rtthread_inter.h
Normal file
4
mkrtos_user/server/drv/rtthread_drv/inc/rtthread_inter.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#include <rtdef.h>
|
||||
rt_err_t rt_thread_bind_mkrtos(rt_thread_t th);
|
||||
@@ -4,14 +4,16 @@
|
||||
#include <u_drv.h>
|
||||
#include <stdio.h>
|
||||
#include <syscall_backend.h>
|
||||
|
||||
#include <rtthread_inter.h>
|
||||
/* defined the LED0 pin: PC0 */
|
||||
#define LED0_PIN GET_PIN(C, 0)
|
||||
extern void rt_hw_board_init(void);
|
||||
extern int dfs_init(void);
|
||||
static struct rt_thread main_rtt;
|
||||
int main(void)
|
||||
{
|
||||
printf("test\n");
|
||||
rt_thread_bind_mkrtos(&main_rtt);
|
||||
/* init board */
|
||||
rt_hw_board_init();
|
||||
dfs_init();
|
||||
|
||||
635
mkrtos_user/server/drv/rtthread_drv/src/object.c
Normal file
635
mkrtos_user/server/drv/rtthread_drv/src/object.c
Normal file
@@ -0,0 +1,635 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-03-14 Bernard the first version
|
||||
* 2006-04-21 Bernard change the scheduler lock to interrupt lock
|
||||
* 2006-05-18 Bernard fix the object init bug
|
||||
* 2006-08-03 Bernard add hook support
|
||||
* 2007-01-28 Bernard rename RT_OBJECT_Class_Static to RT_Object_Class_Static
|
||||
* 2010-10-26 yi.qiu add module support in rt_object_allocate and rt_object_free
|
||||
* 2017-12-10 Bernard Add object_info enum.
|
||||
* 2018-01-25 Bernard Fix the object find issue when enable MODULE.
|
||||
* 2022-01-07 Gabriel Moving __on_rt_xxxxx_hook to object.c
|
||||
* 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
|
||||
#ifdef RT_USING_MODULE
|
||||
#include <dlmodule.h>
|
||||
#endif /* RT_USING_MODULE */
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
#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.
|
||||
*/
|
||||
enum rt_object_info_type
|
||||
{
|
||||
RT_Object_Info_Thread = 0, /**< The object is a thread. */
|
||||
#ifdef RT_USING_DEVICE
|
||||
RT_Object_Info_Device, /**< The object is a device */
|
||||
#endif
|
||||
RT_Object_Info_Unknown, /**< The object is unknown. */
|
||||
};
|
||||
|
||||
#define _OBJ_CONTAINER_LIST_INIT(c) \
|
||||
{&(_object_container[c].object_list), &(_object_container[c].object_list)}
|
||||
|
||||
static struct rt_object_information _object_container[RT_Object_Info_Unknown] =
|
||||
{
|
||||
{RT_Object_Class_Thread, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Thread), sizeof(struct rt_thread), RT_SPINLOCK_INIT},
|
||||
#ifdef RT_USING_DEVICE
|
||||
/* initialize object container - device */
|
||||
{RT_Object_Class_Device, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Device), sizeof(struct rt_device), RT_SPINLOCK_INIT},
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifndef __on_rt_object_attach_hook
|
||||
#define __on_rt_object_attach_hook(obj) __ON_HOOK_ARGS(rt_object_attach_hook, (obj))
|
||||
#endif
|
||||
#ifndef __on_rt_object_detach_hook
|
||||
#define __on_rt_object_detach_hook(obj) __ON_HOOK_ARGS(rt_object_detach_hook, (obj))
|
||||
#endif
|
||||
#ifndef __on_rt_object_trytake_hook
|
||||
#define __on_rt_object_trytake_hook(parent) __ON_HOOK_ARGS(rt_object_trytake_hook, (parent))
|
||||
#endif
|
||||
#ifndef __on_rt_object_take_hook
|
||||
#define __on_rt_object_take_hook(parent) __ON_HOOK_ARGS(rt_object_take_hook, (parent))
|
||||
#endif
|
||||
#ifndef __on_rt_object_put_hook
|
||||
#define __on_rt_object_put_hook(parent) __ON_HOOK_ARGS(rt_object_put_hook, (parent))
|
||||
#endif
|
||||
|
||||
#if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
|
||||
static void (*rt_object_attach_hook)(struct rt_object *object);
|
||||
static void (*rt_object_detach_hook)(struct rt_object *object);
|
||||
void (*rt_object_trytake_hook)(struct rt_object *object);
|
||||
void (*rt_object_take_hook)(struct rt_object *object);
|
||||
void (*rt_object_put_hook)(struct rt_object *object);
|
||||
|
||||
/**
|
||||
* @addtogroup Hook
|
||||
*/
|
||||
|
||||
/**@{*/
|
||||
|
||||
/**
|
||||
* @brief This function will set a hook function, which will be invoked when object
|
||||
* attaches to kernel object system.
|
||||
*
|
||||
* @param hook is the hook function.
|
||||
*/
|
||||
void rt_object_attach_sethook(void (*hook)(struct rt_object *object))
|
||||
{
|
||||
rt_object_attach_hook = hook;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function will set a hook function, which will be invoked when object
|
||||
* detaches from kernel object system.
|
||||
*
|
||||
* @param hook is the hook function
|
||||
*/
|
||||
void rt_object_detach_sethook(void (*hook)(struct rt_object *object))
|
||||
{
|
||||
rt_object_detach_hook = hook;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function will set a hook function, which will be invoked when object
|
||||
* is taken from kernel object system.
|
||||
*
|
||||
* The object is taken means:
|
||||
* semaphore - semaphore is taken by thread
|
||||
* mutex - mutex is taken by thread
|
||||
* event - event is received by thread
|
||||
* mailbox - mail is received by thread
|
||||
* message queue - message is received by thread
|
||||
*
|
||||
* @param hook is the hook function.
|
||||
*/
|
||||
void rt_object_trytake_sethook(void (*hook)(struct rt_object *object))
|
||||
{
|
||||
rt_object_trytake_hook = hook;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function will set a hook function, which will be invoked when object
|
||||
* have been taken from kernel object system.
|
||||
*
|
||||
* The object have been taken means:
|
||||
* semaphore - semaphore have been taken by thread
|
||||
* mutex - mutex have been taken by thread
|
||||
* event - event have been received by thread
|
||||
* mailbox - mail have been received by thread
|
||||
* message queue - message have been received by thread
|
||||
* timer - timer is started
|
||||
*
|
||||
* @param hook the hook function.
|
||||
*/
|
||||
void rt_object_take_sethook(void (*hook)(struct rt_object *object))
|
||||
{
|
||||
rt_object_take_hook = hook;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function will set a hook function, which will be invoked when object
|
||||
* is put to kernel object system.
|
||||
*
|
||||
* @param hook is the hook function
|
||||
*/
|
||||
void rt_object_put_sethook(void (*hook)(struct rt_object *object))
|
||||
{
|
||||
rt_object_put_hook = hook;
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
#endif /* RT_USING_HOOK */
|
||||
|
||||
/**
|
||||
* @addtogroup KernelObject
|
||||
*/
|
||||
|
||||
/**@{*/
|
||||
|
||||
/**
|
||||
* @brief This function will return the specified type of object information.
|
||||
*
|
||||
* @param type is the type of object, which can be
|
||||
* RT_Object_Class_Thread/Semaphore/Mutex... etc
|
||||
*
|
||||
* @return the object type information or RT_NULL
|
||||
*/
|
||||
struct rt_object_information *
|
||||
rt_object_get_information(enum rt_object_class_type type)
|
||||
{
|
||||
int index;
|
||||
|
||||
type = type& ~RT_Object_Class_Static;
|
||||
|
||||
for (index = 0; index < RT_Object_Info_Unknown; index ++)
|
||||
if (_object_container[index].type == type) return &_object_container[index];
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
RTM_EXPORT(rt_object_get_information);
|
||||
|
||||
/**
|
||||
* @brief This function will return the length of object list in object container.
|
||||
*
|
||||
* @param type is the type of object, which can be
|
||||
* RT_Object_Class_Thread/Semaphore/Mutex... etc
|
||||
*
|
||||
* @return the length of object list
|
||||
*/
|
||||
int rt_object_get_length(enum rt_object_class_type type)
|
||||
{
|
||||
int count = 0;
|
||||
rt_base_t level;
|
||||
struct rt_list_node *node = RT_NULL;
|
||||
struct rt_object_information *information = RT_NULL;
|
||||
|
||||
information = rt_object_get_information((enum rt_object_class_type)type);
|
||||
if (information == RT_NULL) return 0;
|
||||
|
||||
level = rt_spin_lock_irqsave(&(information->spinlock));
|
||||
rt_list_for_each(node, &(information->object_list))
|
||||
{
|
||||
count ++;
|
||||
}
|
||||
rt_spin_unlock_irqrestore(&(information->spinlock), level);
|
||||
|
||||
return count;
|
||||
}
|
||||
RTM_EXPORT(rt_object_get_length);
|
||||
|
||||
/**
|
||||
* @brief This function will copy the object pointer of the specified type,
|
||||
* with the maximum size specified by maxlen.
|
||||
*
|
||||
* @param type is the type of object, which can be
|
||||
* RT_Object_Class_Thread/Semaphore/Mutex... etc
|
||||
*
|
||||
* @param pointers is the pointer will be saved to.
|
||||
*
|
||||
* @param maxlen is the maximum number of pointers can be saved.
|
||||
*
|
||||
* @return the copied number of object pointers.
|
||||
*/
|
||||
int rt_object_get_pointers(enum rt_object_class_type type, rt_object_t *pointers, int maxlen)
|
||||
{
|
||||
int index = 0;
|
||||
rt_base_t level;
|
||||
|
||||
struct rt_object *object;
|
||||
struct rt_list_node *node = RT_NULL;
|
||||
struct rt_object_information *information = RT_NULL;
|
||||
|
||||
if (maxlen <= 0) return 0;
|
||||
|
||||
information = rt_object_get_information((enum rt_object_class_type)type);
|
||||
if (information == RT_NULL) return 0;
|
||||
|
||||
level = rt_spin_lock_irqsave(&(information->spinlock));
|
||||
/* retrieve pointer of object */
|
||||
rt_list_for_each(node, &(information->object_list))
|
||||
{
|
||||
object = rt_list_entry(node, struct rt_object, list);
|
||||
|
||||
pointers[index] = object;
|
||||
index ++;
|
||||
|
||||
if (index >= maxlen) break;
|
||||
}
|
||||
rt_spin_unlock_irqrestore(&(information->spinlock), level);
|
||||
|
||||
return index;
|
||||
}
|
||||
RTM_EXPORT(rt_object_get_pointers);
|
||||
|
||||
/**
|
||||
* @brief This function will initialize an object and add it to object system
|
||||
* management.
|
||||
*
|
||||
* @param object is the specified object to be initialized.
|
||||
*
|
||||
* @param type is the object type.
|
||||
*
|
||||
* @param name is the object name. In system, the object's name must be unique.
|
||||
*/
|
||||
void rt_object_init(struct rt_object *object,
|
||||
enum rt_object_class_type type,
|
||||
const char *name)
|
||||
{
|
||||
rt_base_t level;
|
||||
#ifdef RT_USING_DEBUG
|
||||
struct rt_list_node *node = RT_NULL;
|
||||
#endif
|
||||
struct rt_object_information *information;
|
||||
#ifdef RT_USING_MODULE
|
||||
struct rt_dlmodule *module = dlmodule_self();
|
||||
#endif /* RT_USING_MODULE */
|
||||
|
||||
/* get object information */
|
||||
information = rt_object_get_information(type);
|
||||
RT_ASSERT(information != RT_NULL);
|
||||
|
||||
#ifdef RT_USING_DEBUG
|
||||
/* check object type to avoid re-initialization */
|
||||
|
||||
/* enter critical */
|
||||
level = rt_spin_lock_irqsave(&(information->spinlock));
|
||||
/* try to find object */
|
||||
for (node = information->object_list.next;
|
||||
node != &(information->object_list);
|
||||
node = node->next)
|
||||
{
|
||||
struct rt_object *obj;
|
||||
|
||||
obj = rt_list_entry(node, struct rt_object, list);
|
||||
RT_ASSERT(obj != object);
|
||||
}
|
||||
/* leave critical */
|
||||
rt_spin_unlock_irqrestore(&(information->spinlock), level);
|
||||
#endif
|
||||
|
||||
/* initialize object's parameters */
|
||||
/* set object type to static */
|
||||
object->type = type | RT_Object_Class_Static;
|
||||
#if RT_NAME_MAX > 0
|
||||
rt_strncpy(object->name, name, RT_NAME_MAX); /* copy name */
|
||||
#else
|
||||
object->name = name;
|
||||
#endif /* RT_NAME_MAX > 0 */
|
||||
|
||||
RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
|
||||
|
||||
level = rt_spin_lock_irqsave(&(information->spinlock));
|
||||
|
||||
#ifdef RT_USING_MODULE
|
||||
if (module)
|
||||
{
|
||||
rt_list_insert_after(&(module->object_list), &(object->list));
|
||||
object->module_id = (void *)module;
|
||||
}
|
||||
else
|
||||
#endif /* RT_USING_MODULE */
|
||||
{
|
||||
/* insert object into information object list */
|
||||
rt_list_insert_after(&(information->object_list), &(object->list));
|
||||
}
|
||||
rt_spin_unlock_irqrestore(&(information->spinlock), level);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function will detach a static object from object system,
|
||||
* and the memory of static object is not freed.
|
||||
*
|
||||
* @param object the specified object to be detached.
|
||||
*/
|
||||
void rt_object_detach(rt_object_t object)
|
||||
{
|
||||
rt_base_t level;
|
||||
struct rt_object_information *information;
|
||||
|
||||
/* object check */
|
||||
RT_ASSERT(object != RT_NULL);
|
||||
|
||||
RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
|
||||
|
||||
information = rt_object_get_information(object->type);
|
||||
RT_ASSERT(information != RT_NULL);
|
||||
|
||||
level = rt_spin_lock_irqsave(&(information->spinlock));
|
||||
/* remove from old list */
|
||||
rt_list_remove(&(object->list));
|
||||
rt_spin_unlock_irqrestore(&(information->spinlock), level);
|
||||
|
||||
object->type = 0;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_HEAP
|
||||
/**
|
||||
* @brief This function will allocate an object from object system.
|
||||
*
|
||||
* @param type is the type of object.
|
||||
*
|
||||
* @param name is the object name. In system, the object's name must be unique.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
|
||||
{
|
||||
struct rt_object *object;
|
||||
rt_base_t level;
|
||||
struct rt_object_information *information;
|
||||
#ifdef RT_USING_MODULE
|
||||
struct rt_dlmodule *module = dlmodule_self();
|
||||
#endif /* RT_USING_MODULE */
|
||||
|
||||
RT_DEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
/* get object information */
|
||||
information = rt_object_get_information(type);
|
||||
RT_ASSERT(information != RT_NULL);
|
||||
|
||||
object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size);
|
||||
if (object == RT_NULL)
|
||||
{
|
||||
/* no memory can be allocated */
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
/* clean memory data of object */
|
||||
rt_memset(object, 0x0, information->object_size);
|
||||
|
||||
/* initialize object's parameters */
|
||||
|
||||
/* set object type */
|
||||
object->type = type;
|
||||
|
||||
/* set object flag */
|
||||
object->flag = 0;
|
||||
|
||||
#if RT_NAME_MAX > 0
|
||||
rt_strncpy(object->name, name, RT_NAME_MAX); /* copy name */
|
||||
#else
|
||||
object->name = name;
|
||||
#endif /* RT_NAME_MAX > 0 */
|
||||
|
||||
RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
|
||||
|
||||
level = rt_spin_lock_irqsave(&(information->spinlock));
|
||||
|
||||
#ifdef RT_USING_MODULE
|
||||
if (module)
|
||||
{
|
||||
rt_list_insert_after(&(module->object_list), &(object->list));
|
||||
object->module_id = (void *)module;
|
||||
}
|
||||
else
|
||||
#endif /* RT_USING_MODULE */
|
||||
{
|
||||
/* insert object into information object list */
|
||||
rt_list_insert_after(&(information->object_list), &(object->list));
|
||||
}
|
||||
rt_spin_unlock_irqrestore(&(information->spinlock), level);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function will delete an object and release object memory.
|
||||
*
|
||||
* @param object is the specified object to be deleted.
|
||||
*/
|
||||
void rt_object_delete(rt_object_t object)
|
||||
{
|
||||
rt_base_t level;
|
||||
struct rt_object_information *information;
|
||||
|
||||
/* object check */
|
||||
RT_ASSERT(object != RT_NULL);
|
||||
RT_ASSERT(!(object->type & RT_Object_Class_Static));
|
||||
|
||||
RT_OBJECT_HOOK_CALL(rt_object_detach_hook, (object));
|
||||
|
||||
|
||||
information = rt_object_get_information(object->type);
|
||||
RT_ASSERT(information != RT_NULL);
|
||||
|
||||
level = rt_spin_lock_irqsave(&(information->spinlock));
|
||||
|
||||
/* remove from old list */
|
||||
rt_list_remove(&(object->list));
|
||||
|
||||
rt_spin_unlock_irqrestore(&(information->spinlock), level);
|
||||
|
||||
/* reset object type */
|
||||
object->type = RT_Object_Class_Null;
|
||||
|
||||
/* free the memory of object */
|
||||
RT_KERNEL_FREE(object);
|
||||
}
|
||||
#endif /* RT_USING_HEAP */
|
||||
|
||||
/**
|
||||
* @brief This function will judge the object is system object or not.
|
||||
*
|
||||
* @note Normally, the system object is a static object and the type
|
||||
* of object set to RT_Object_Class_Static.
|
||||
*
|
||||
* @param object is the specified object to be judged.
|
||||
*
|
||||
* @return RT_TRUE if a system object, RT_FALSE for others.
|
||||
*/
|
||||
rt_bool_t rt_object_is_systemobject(rt_object_t object)
|
||||
{
|
||||
/* object check */
|
||||
RT_ASSERT(object != RT_NULL);
|
||||
|
||||
if (object->type & RT_Object_Class_Static)
|
||||
return RT_TRUE;
|
||||
|
||||
return RT_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function will return the type of object without
|
||||
* RT_Object_Class_Static flag.
|
||||
*
|
||||
* @param object is the specified object to be get type.
|
||||
*
|
||||
* @return the type of object.
|
||||
*/
|
||||
rt_uint8_t rt_object_get_type(rt_object_t object)
|
||||
{
|
||||
/* object check */
|
||||
RT_ASSERT(object != RT_NULL);
|
||||
|
||||
return object->type & ~RT_Object_Class_Static;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function will find specified name object from object
|
||||
* container.
|
||||
*
|
||||
* @param name is the specified name of object.
|
||||
*
|
||||
* @param type is the type of object
|
||||
*
|
||||
* @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_object_find(const char *name, rt_uint8_t type)
|
||||
{
|
||||
struct rt_object *object = RT_NULL;
|
||||
struct rt_list_node *node = RT_NULL;
|
||||
struct rt_object_information *information = RT_NULL;
|
||||
rt_base_t level;
|
||||
|
||||
information = rt_object_get_information((enum rt_object_class_type)type);
|
||||
|
||||
/* parameter check */
|
||||
if ((name == RT_NULL) || (information == RT_NULL)) return RT_NULL;
|
||||
|
||||
/* which is invoke in interrupt status */
|
||||
RT_DEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
/* enter critical */
|
||||
level = rt_spin_lock_irqsave(&(information->spinlock));
|
||||
|
||||
/* try to find object */
|
||||
rt_list_for_each(node, &(information->object_list))
|
||||
{
|
||||
object = rt_list_entry(node, struct rt_object, list);
|
||||
if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
|
||||
{
|
||||
rt_spin_unlock_irqrestore(&(information->spinlock), level);
|
||||
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
rt_spin_unlock_irqrestore(&(information->spinlock), level);
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function will return the name of the specified object container
|
||||
*
|
||||
* @param object the specified object to be get name
|
||||
* @param name buffer to store the object name string
|
||||
* @param name_size maximum size of the buffer to store object name
|
||||
*
|
||||
* @return -RT_EINVAL if any parameter is invalid or RT_EOK if the operation is successfully executed
|
||||
*
|
||||
* @note this function shall not be invoked in interrupt status
|
||||
*/
|
||||
rt_err_t rt_object_get_name(rt_object_t object, char *name, rt_uint8_t name_size)
|
||||
{
|
||||
rt_err_t result = -RT_EINVAL;
|
||||
if ((object != RT_NULL) && (name != RT_NULL) && (name_size != 0U))
|
||||
{
|
||||
const char *obj_name = object->name;
|
||||
(void) rt_strncpy(name, obj_name, (rt_size_t)name_size);
|
||||
result = RT_EOK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_HEAP
|
||||
/**
|
||||
* This function will create a custom object
|
||||
* container.
|
||||
*
|
||||
* @param name the specified name 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
|
||||
|
||||
/**@}*/
|
||||
@@ -8,6 +8,9 @@
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
#include <u_thread.h>
|
||||
#include <u_ipc.h>
|
||||
|
||||
extern unsigned long get_thread_area(void);
|
||||
|
||||
rt_weak void *rt_calloc(rt_size_t count, rt_size_t size)
|
||||
@@ -91,69 +94,40 @@ rt_uint16_t rt_critical_level(void)
|
||||
}
|
||||
rt_thread_t rt_thread_self(void)
|
||||
{
|
||||
printf("[drv]%s:%d\n", __func__, __LINE__);
|
||||
return NULL; /*TODO:*/
|
||||
ipc_msg_t *i_msg;
|
||||
|
||||
thread_msg_buf_get(-1, (umword_t *)(&i_msg), NULL);
|
||||
|
||||
return (rt_thread_t)(i_msg->user[1]);
|
||||
}
|
||||
rt_err_t rt_thread_bind_mkrtos(rt_thread_t th)
|
||||
{
|
||||
ipc_msg_t *i_msg;
|
||||
|
||||
pthread_mutex_lock(&th->suspend_lock);
|
||||
th->tlist.next = th->tlist.prev = &th->tlist;
|
||||
th->stat = 0;
|
||||
|
||||
thread_msg_buf_get(-1, (umword_t *)(&i_msg), NULL);
|
||||
i_msg->user[1] = (umword_t)th;
|
||||
}
|
||||
rt_err_t rt_thread_suspend_with_flag(rt_thread_t thread, int suspend_flag)
|
||||
{
|
||||
//! 这里锁两次,第二次加锁将会导致挂起
|
||||
printf("[drv]%s:%d\n", __func__, __LINE__);
|
||||
|
||||
return 0; /*TODO:*/
|
||||
thread->stat = RT_THREAD_SUSPEND;
|
||||
pthread_mutex_lock(&thread->suspend_lock);
|
||||
thread->stat = 0;
|
||||
return 0;
|
||||
}
|
||||
rt_err_t rt_thread_resume(rt_thread_t thread)
|
||||
{
|
||||
pthread_mutex_unlock(&thread->suspend_lock);
|
||||
pthread_mutex_lock(&thread->suspend_lock);
|
||||
printf("[drv]%s:%d\n", __func__, __LINE__);
|
||||
|
||||
return 0; /*TODO:*/
|
||||
}
|
||||
rt_err_t rt_timer_start(rt_timer_t timer)
|
||||
{
|
||||
printf("[drv]%s:%d\n", __func__, __LINE__);
|
||||
|
||||
return 0; /*TODO:*/
|
||||
}
|
||||
rt_err_t rt_timer_stop(rt_timer_t timer)
|
||||
{
|
||||
printf("[drv]%s:%d\n", __func__, __LINE__);
|
||||
|
||||
return 0; /*TODO:*/
|
||||
}
|
||||
rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg)
|
||||
{
|
||||
printf("[drv]%s:%d\n", __func__, __LINE__);
|
||||
|
||||
return 0; /*TODO:*/
|
||||
}
|
||||
rt_tick_t rt_timer_next_timeout_tick(void)
|
||||
{
|
||||
printf("[drv]%s:%d\n", __func__, __LINE__);
|
||||
|
||||
return 0; /*TODO:*/
|
||||
}
|
||||
void rt_timer_check(void)
|
||||
{
|
||||
printf("[drv]%s:%d\n", __func__, __LINE__);
|
||||
|
||||
/*TODO:*/
|
||||
}
|
||||
void rt_object_init(struct rt_object *object,
|
||||
enum rt_object_class_type type,
|
||||
const char *name)
|
||||
{
|
||||
printf("[drv]%s:%d\n", __func__, __LINE__);
|
||||
|
||||
/*TODO:*/
|
||||
}
|
||||
rt_object_t rt_object_find(const char *name, rt_uint8_t type)
|
||||
{
|
||||
printf("[drv]%s:%d\n", __func__, __LINE__);
|
||||
|
||||
return NULL; /*TODO:*/
|
||||
}
|
||||
rt_uint8_t rt_object_get_type(rt_object_t object)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rt_set_errno(rt_err_t no)
|
||||
{
|
||||
errno = no;
|
||||
@@ -226,9 +200,202 @@ rt_err_t rt_mq_delete(rt_mq_t mq)
|
||||
/*TODO:*/
|
||||
return -1;
|
||||
}
|
||||
struct rt_object_information *
|
||||
rt_object_get_information(enum rt_object_class_type type)
|
||||
#include <u_thread_util.h>
|
||||
#include <u_hd_man.h>
|
||||
#include <u_ipc.h>
|
||||
#include <u_sys.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#define STACK_SIZE 1024
|
||||
|
||||
static obj_handler_t timer_hd = HANDLER_INVALID;
|
||||
static char timer_thmsg_buf[MSG_BUG_LEN];
|
||||
static __attribute__((aligned(8))) uint8_t timer_stack[STACK_SIZE];
|
||||
|
||||
#define TIMER_LIST_NR 16 //!< TODO:放到kconfig中
|
||||
static struct rt_timer *timer_list[TIMER_LIST_NR];
|
||||
static pthread_spinlock_t timer_lock;
|
||||
|
||||
static struct rt_timer *timer_alloc(struct rt_timer *tim, void (*func_cb)(void *arg), size_t exp_times, void *data, uint8_t flags)
|
||||
{
|
||||
/*TODO:*/
|
||||
pthread_spin_lock(&timer_lock);
|
||||
for (int i = 0; i < TIMER_LIST_NR; i++)
|
||||
{
|
||||
if (timer_list[i] == 0)
|
||||
{
|
||||
timer_list[i] = tim;
|
||||
timer_list[i]->inx = i;
|
||||
timer_list[i]->data = data;
|
||||
timer_list[i]->func_cb = func_cb;
|
||||
timer_list[i]->exp_times = exp_times;
|
||||
timer_list[i]->flags = flags;
|
||||
pthread_spin_unlock(&timer_lock);
|
||||
return timer_list[i];
|
||||
}
|
||||
}
|
||||
pthread_spin_unlock(&timer_lock);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
static void timer_free(struct rt_timer *entry)
|
||||
{
|
||||
assert(entry);
|
||||
timer_list[entry->inx] = NULL;
|
||||
}
|
||||
static void timer_func(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
usleep(1000);
|
||||
rt_timer_check();
|
||||
}
|
||||
}
|
||||
void rt_timer_check(void)
|
||||
{
|
||||
umword_t now_tick;
|
||||
|
||||
now_tick = sys_read_tick();
|
||||
pthread_spin_lock(&timer_lock);
|
||||
for (int i = 0; i < TIMER_LIST_NR; i++)
|
||||
{
|
||||
if (timer_list[i] &&
|
||||
timer_list[i]->start_times != 0 &&
|
||||
timer_list[i]->exp_times + timer_list[i]->start_times >= now_tick)
|
||||
{
|
||||
if ((timer_list[i]->flags & RT_TIMER_FLAG_ONE_SHOT) == 0)
|
||||
{
|
||||
pthread_spin_unlock(&timer_lock);
|
||||
timer_list[i]->func_cb(timer_list[i]->data);
|
||||
pthread_spin_lock(&timer_lock);
|
||||
timer_list[i] = NULL;
|
||||
}
|
||||
else if (timer_list[i]->flags & RT_TIMER_FLAG_PERIODIC)
|
||||
{
|
||||
pthread_spin_unlock(&timer_lock);
|
||||
timer_list[i]->func_cb(timer_list[i]->data);
|
||||
pthread_spin_lock(&timer_lock);
|
||||
if (timer_list[i])
|
||||
{
|
||||
timer_list[i]->start_times = sys_read_tick();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Error.*/
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_spin_unlock(&timer_lock);
|
||||
}
|
||||
void rt_timer_init(rt_timer_t timer,
|
||||
const char *name,
|
||||
void (*timeout)(void *parameter),
|
||||
void *parameter,
|
||||
rt_tick_t time,
|
||||
rt_uint8_t flag)
|
||||
{
|
||||
assert(timeout);
|
||||
if (timer_hd == HANDLER_INVALID)
|
||||
{
|
||||
int ret = u_thread_create(&timer_hd, timer_stack, STACK_SIZE, timer_thmsg_buf, timer_func, 2);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
errno = ret;
|
||||
return;
|
||||
}
|
||||
}
|
||||
struct rt_timer *entry = timer_alloc(timer, timeout, time, parameter, flag);
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
errno = -ENOMEM;
|
||||
return;
|
||||
}
|
||||
printf("%s name %s tick %d flag 0x%x.\n", name, time, flag);
|
||||
}
|
||||
rt_err_t rt_timer_start(rt_timer_t timer)
|
||||
{
|
||||
timer->start_times = sys_read_tick();
|
||||
return 0;
|
||||
}
|
||||
rt_err_t rt_timer_stop(rt_timer_t timer)
|
||||
{
|
||||
timer_free(timer);
|
||||
return 0;
|
||||
}
|
||||
rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg)
|
||||
{
|
||||
assert(timer);
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_TIMER_CTRL_SET_TIME:
|
||||
timer->exp_times = *(rt_tick_t *)arg;
|
||||
break;
|
||||
case RT_TIMER_CTRL_GET_TIME:
|
||||
*(rt_tick_t *)arg = timer->exp_times;
|
||||
break;
|
||||
case RT_TIMER_CTRL_GET_PARM:
|
||||
*(void **)arg = timer->data;
|
||||
break;
|
||||
case RT_TIMER_CTRL_SET_PARM:
|
||||
timer->data = arg;
|
||||
break;
|
||||
case RT_TIMER_CTRL_GET_FUNC:
|
||||
*(void **)arg = (void *)timer->func_cb;
|
||||
break;
|
||||
|
||||
case RT_TIMER_CTRL_SET_FUNC:
|
||||
timer->func_cb = (void (*)(void *))arg;
|
||||
break;
|
||||
case RT_TIMER_CTRL_GET_REMAIN_TIME:
|
||||
*(rt_tick_t *)arg = timer->exp_times - (sys_read_tick() - timer->start_times);
|
||||
break;
|
||||
case RT_TIMER_CTRL_GET_STATE:
|
||||
if (timer->start_times)
|
||||
{
|
||||
/*timer is start and run*/
|
||||
*(rt_uint32_t *)arg = RT_TIMER_FLAG_ACTIVATED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*timer is stop*/
|
||||
*(rt_uint32_t *)arg = RT_TIMER_FLAG_DEACTIVATED;
|
||||
}
|
||||
break;
|
||||
case RT_TIMER_CTRL_SET_ONESHOT:
|
||||
timer->flags &= ~RT_TIMER_FLAG_PERIODIC;
|
||||
break;
|
||||
case RT_TIMER_CTRL_SET_PERIODIC:
|
||||
timer->flags |= RT_TIMER_FLAG_PERIODIC;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
rt_tick_t rt_timer_next_timeout_tick(void)
|
||||
{
|
||||
pthread_spin_lock(&timer_lock);
|
||||
umword_t sys_tick;
|
||||
int min = INT32_MAX;
|
||||
|
||||
sys_tick = sys_read_tick();
|
||||
for (int i = 0; i < TIMER_LIST_NR; i++)
|
||||
{
|
||||
if (timer_list[i] &&
|
||||
timer_list[i]->start_times != 0)
|
||||
{
|
||||
int val = timer_list[i]->exp_times + timer_list[i]->start_times - sys_tick;
|
||||
|
||||
val = val < 0 ? 0 : val;
|
||||
if (val < min)
|
||||
{
|
||||
min = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_spin_unlock(&timer_lock);
|
||||
return min;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user