当前位置:网站首页>RT thread Kernel Implementation (II): critical area, object container
RT thread Kernel Implementation (II): critical area, object container
2022-06-30 06:39:00 【Mnnk】
A critical region (Critical Section)
- A simple way to ensure that only one thread can access data at any one time . Only one thread is allowed to access shared resources at any time .
- RT-Thread The protection of critical sections is handled simply , Just turn off all interrupts , NMI FAULT And hard FAULT With the exception of .
- Cortex M3 Authoritative guide Description of the exception mask register in .



- When critical segments are nested , If a simple switch is always interrupted , The total interrupt is turned on when the internal critical section is released , The outer critical section does not end , Should not be turned on .
context_rvds.sThe critical section switching function is defined in . When opening, save the currentPRIMASK. Restore the previous value when closing .
;/* ; * t_base_t rt_hw_interrupt_disable(); ; */
rt_hw_interrupt_disable PROC
EXPORT rt_hw_interrupt_disable
MRS r0, PRIMASK
CPSID I
BX LR
ENDP
;/* ; * void rt_hw_interrupt_enable(rt_base_t level); ; */
rt_hw_interrupt_enable PROC
EXPORT rt_hw_interrupt_enable
MSR PRIMASK, r0
BX LR
ENDP
Object container
- object ,RT-Thread All data structures in are called objects . In the whole system , The name of the object must be unique .
- The structure is in
rtdef.hIn the definition of .
/* ************************************************************************* * Kernel object structure ************************************************************************* */
/** * Kernel object basic data structure */
struct rt_object
{
char name[RT_NAME_MAX]; /* The name of the kernel object */
rt_uint8_t type; /* The type of kernel object */
rt_uint8_t flag; /* The state of the kernel object */
rt_list_t list; /* List nodes for kernel objects */
};
typedef struct rt_object *rt_object_t; /* Kernel object data type redefinition */
/** * Object types are enabled by the following macros , These macros are usually in rtconfig.h In the definition of * - Thread * - Semaphore * - Mutex * - Event * - MailBox * - MessageQueue * - MemHeap * - MemPool * - Device * - Timer * - Module * - Unknown * - Static */
enum rt_object_class_type
{
RT_Object_Class_Thread = 0, /* Objects are threads */
RT_Object_Class_Semaphore, /* The object is the semaphore */
RT_Object_Class_Mutex, /* Objects are mutexes */
RT_Object_Class_Event, /* The object is an event */
RT_Object_Class_MailBox, /* The object is a mailbox */
RT_Object_Class_MessageQueue, /* The object is the message queue */
RT_Object_Class_MemHeap, /* The object is a memory heap */
RT_Object_Class_MemPool, /* The object is a memory pool */
RT_Object_Class_Device, /* The object is a device */
RT_Object_Class_Timer, /* The object is a timer */
RT_Object_Class_Module, /* The object is a module */
RT_Object_Class_Unknown, /* Object unknown */
RT_Object_Class_Static = 0x80 /* Objects are static objects */
};
/** * Kernel object information structure , Container related */
struct rt_object_information
{
enum rt_object_class_type type; /* object type */
rt_list_t object_list; /* Object list node */
rt_size_t object_size; /* Object size */
};
- Each object has a corresponding structure , This structure is called the control of the object
block . For example, a thread has a thread control block , The timer will have a timer control block , Semaphores have semaphore control blocks, etc . Such as the following thread object , Other kernel objects are used directly at the beginning of the kernel object struct rt_object Directly define a kernel object variable .
struct rt_thread
{
/* rt object */
char name[RT_NAME_MAX]; /* The name of the object */
rt_uint8_t type; /* object type */
rt_uint8_t flags; /* Object state */
rt_list_t list; /* The list node of the object */
void *sp; /* Thread stack pointer */
void *entry; /* Thread entry address */
void *parameter; /* Thread parameters */
void *stack_addr; /* Thread start address */
rt_uint32_t stack_size; /* Thread stack size , The unit is byte */
rt_list_t tlist; /* Thread linked list node */
};
- Containers , stay RT-Thread in , Every time a user creates an object , This object will be placed in a place called a container , The purpose is to facilitate management . From the code point of view , A container is an array , Is a global variable , The data type is
struct rt_object_information. - stay
object.cIn the definition of .
/* * Subscript definition of object container array , Determine the size of the container */
enum rt_object_info_type
{
RT_Object_Info_Thread = 0, /* Objects are threads */
#ifdef RT_USING_SEMAPHORE
RT_Object_Info_Semaphore, /* The object is the semaphore */
#endif
#ifdef RT_USING_MUTEX
RT_Object_Info_Mutex, /* Objects are mutexes */
#endif
#ifdef RT_USING_EVENT
RT_Object_Info_Event, /* The object is an event */
#endif
#ifdef RT_USING_MAILBOX
RT_Object_Info_MailBox, /* The object is a mailbox */
#endif
#ifdef RT_USING_MESSAGEQUEUE
RT_Object_Info_MessageQueue, /* The object is the message queue */
#endif
#ifdef RT_USING_MEMHEAP
RT_Object_Info_MemHeap, /* The object is a memory heap */
#endif
#ifdef RT_USING_MEMPOOL
RT_Object_Info_MemPool, /* The object is a memory pool */
#endif
#ifdef RT_USING_DEVICE
RT_Object_Info_Device, /* The object is a device */
#endif
RT_Object_Info_Timer, /* The object is a timer */
#ifdef RT_USING_MODULE
RT_Object_Info_Module, /* The object is a module */
#endif
RT_Object_Info_Unknown, /* Object unknown */
};
#define _OBJ_CONTAINER_LIST_INIT(c) \ {&(rt_object_container[c].object_list), &(rt_object_container[c].object_list)}
static struct rt_object_information rt_object_container[RT_Object_Info_Unknown] =
{
/* Initialize the object container - Threads */
{
RT_Object_Class_Thread,
_OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Thread),
sizeof(struct rt_thread)
},
#ifdef RT_USING_SEMAPHORE
/* Initialize the object container - Semaphore */
{
RT_Object_Class_Semaphore,
_OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Semaphore),
sizeof(struct rt_semaphore)
},
#endif
#ifdef RT_USING_MUTEX
/* Initialize the object container - The mutex */
{
RT_Object_Class_Mutex,
_OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Mutex),
sizeof(struct rt_mutex)
},
#endif
#ifdef RT_USING_EVENT
/* Initialize the object container - event */
{
RT_Object_Class_Event,
_OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Event),
sizeof(struct rt_event)
},
#endif
#ifdef RT_USING_MAILBOX
/* Initialize the object container - mailbox */
{
RT_Object_Class_MailBox,
_OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MailBox),
sizeof(struct rt_mailbox)
},
#endif
#ifdef RT_USING_MESSAGEQUEUE
/* Initialize the object container - Message queue */
{
RT_Object_Class_MessageQueue,
_OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MessageQueue),
sizeof(struct rt_messagequeue)
},
#endif
#ifdef RT_USING_MEMHEAP
/* Initialize the object container - Memory heap */
{
RT_Object_Class_MemHeap,
_OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MemHeap),
sizeof(struct rt_memheap)
},
#endif
#ifdef RT_USING_MEMPOOL
/* Initialize the object container - Memory pool */
{
RT_Object_Class_MemPool,
_OBJ_CONTAINER_LIST_INIT(RT_Object_Info_MemPool),
sizeof(struct rt_mempool)
},
#endif
#ifdef RT_USING_DEVICE
/* Initialize the object container - equipment */
{
RT_Object_Class_Device,
_OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Device), sizeof(struct rt_device)},
#endif
/* Initialize the object container - Timer */ // The timer is not used for the time being
/* { RT_Object_Class_Timer, _OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Timer), sizeof(struct rt_timer) }, */
#ifdef RT_USING_MODULE
/* Initialize the object container - modular */
{
RT_Object_Class_Module,
_OBJ_CONTAINER_LIST_INIT(RT_Object_Info_Module),
sizeof(struct rt_module)
},
#endif
};
- Rong device Of Big Small from
RT_Object_Info_Unknown" set . - Object initialization , Hang the object in the object container , Double linked list .
/** * This function initializes the object and adds it to the object container * * @param object Object to initialize * @param type Type of object * @param name The name of the object , In the whole system , The name of the object must be unique */
void rt_object_init(struct rt_object *object,
enum rt_object_class_type type,
const char *name)
{
register rt_base_t temp;
struct rt_object_information *information;
/* Get object information , That is, get the corresponding object list header pointer from the container */
information = rt_object_get_information(type);
/* Set the object type to static */
object->type = type | RT_Object_Class_Static;
/* Copy the name */
rt_strncpy(object->name, name, RT_NAME_MAX);
/* Close the interrupt */
temp = rt_hw_interrupt_disable();
/* Insert the object into the corresponding list of the container , Different types of objects are in different lists */
rt_list_insert_after(&(information->object_list), &(object->list));
/* To interrupt */
rt_hw_interrupt_enable(temp);
}
- Object detaches from container .
/** * Detach objects from the container list , But the memory occupied by the object will not be released * * @param object Objects that need to be detached from the container */
void rt_object_detach(rt_object_t object)
{
register rt_base_t temp;
/* Close the interrupt */
temp = rt_hw_interrupt_disable();
/* Detach from the container list */
rt_list_remove(&(object->list));
/* Open the interrupt */
rt_hw_interrupt_enable(temp);
}
/** * Determine whether an object is a system object * Usually , An object will be set to... During initialization RT_Object_Class_Static * * @param Object types to be judged * * @return If it is a system object, it returns RT_TRUE, Otherwise return to RT_FALSE */
rt_bool_t rt_object_is_systemobject(rt_object_t object)
{
if (object->type & RT_Object_Class_Static)
return RT_TRUE;
return RT_FALSE;
}
- For example, two threads are created , Their diagram in the container list is as follows .

- The thread initialization function should also be modified accordingly .
rt_err_t rt_thread_init(struct rt_thread *thread,
const char *name, // name Parameters
void (*entry)(void *parameter),
void *parameter,
void *stack_start,
rt_uint32_t stack_size)
{
/* Thread object initialization */
/* The members at the beginning of the thread structure are rt_object_t type */
rt_object_init((rt_object_t)thread, RT_Object_Class_Thread, name);
rt_list_init(&(thread->tlist));
thread->entry = (void *)entry;
thread->parameter = parameter;
thread->stack_addr = stack_start;
thread->stack_size = stack_size;
/* Initialize the thread stack , And return the thread stack pointer */
thread->sp = (void *)rt_hw_stack_init( thread->entry,
thread->parameter,
(void *)((char *)thread->stack_addr + thread->stack_size - 4) );
return RT_EOK;
}
- Invocation time .
/* Initialization thread */
rt_thread_init( &rt_flag1_thread,
"rt_flag1_thread", /* Thread name , String form */
flag1_thread_entry,
RT_NULL,
&rt_flag1_thread_stack[0],
sizeof(rt_flag1_thread_stack) );
边栏推荐
- 880. decoded string at index
- Verilog中case,casez,casex语句的用法
- First experience of Galaxy Kirin
- 银河麒麟初体验
- Usage of case, casez and casex statements in Verilog
- Bat 使用细节2
- GO安装以及配置(1)
- ES6 deconstruction assignment
- Dynamic routing job
- Is it safe to open an account online? Can you open an account to speculate on the Internet?
猜你喜欢
随机推荐
Idea run SQL file
Collection and method of traversing collection elements (1)
Why does the verification code not refresh when clicked
How does Altium designer hide some temporarily unnecessary classes, such as GND
Thread safe solutions, communication between threads (classic examples of producers and consumers)
Wuenda coursera deep learning course
Bat usage details 2
IO streams (common streams)
1.5 - logical operation
Base64 explanation: playing with pictures Base64 encoding
Cocos studio3.1 installation package win
KEIL - 下载调试出现“TRACE HW not present”
Hao looking for a job
Unable to access the Internet at win10 /11 hotspot
1.9 - Classification of memory
Fastapi learning Day1
583. deleting two strings - Dynamic Planning
gazebo/set_ model_ State topic driving UAV model through posture
Installation and initialization of MariaDB database
1.9 - 存储器的分类









