Although the C language is used in the design of RTT, the object-oriented approach is used. All threads and event devices are inherited from objects and managed in a linked list ..
Object Control Block/*** base structure of kernel object */struct rt_object {char name [rt_name_max]; // name rt_uint8_t type; // Kernel Object Type rt_uint8_t flag; // Kernel Object flag # ifdef rt_using_module void * module_id; // module ID # endif rt_list_t list; // node of the kernel object linked list}; typedef struct rt_object * rt_object_t; in the kernel, all objects are organized by the linked list. The linked list is defined as follows: struct rt_list_node {struct rt_list_node * Next; // point to the next node struct rt_list_node * Prev; // point to the previous node}; typedef struct rt_list_node rt_list_t; all possible derived objects are:/*** the object type can be one of the follows with specific * macros enabled: *-thread *-semaphore *-mutex *-event *-Mailbox *-messagequeue *-memheap *-mempool *-device *-timer *-module *-unknown *-static * /Enum Rt_object_class_type {rt_object_class_thread = 0, // thread # ifdef always success, // semaphore # endif # ifdef rt_using_mutex success, // mutex lock # endif # ifdef rt_using_event rt_object_class_event, // event # endif # ifdef rt_using_mailbox rt_object_class_mailbox, // email # endif # ifdef rt_using_messagequeue success, // Message Queue # endif # ifdef rt_using_memheap Memory, // memory heap # endif # ifdef into memory, // memory pool # endif # ifdef rt_using_device rt_object_class_device, // Device Driver # endif kernel, // clock # ifdef rt_using_module rt_object_class_module, // Module # endif rt_object_class_unknown, // unknown Kernel Object Type rt_object_class_static = 0x80 // RT-thread indicates whether it is a system kernel object }; all objects are placed in the object container:/*** the information of the Kern El object */struct rt_object_information {Enum rt_object_class_type type; // Kernel Object Type rt_list_t object_list; // Kernel Object linked list rt_size_t object_size; // kernel object size}; In RTT, the kernel object management system is implemented using an rt_object_information array, as shown in the following code: # DEFINE _ obj_container_list_init (c) \ // initialize the linked list of the kernel object container, which is defined by a macro, the previous and last nodes of the linked list point to their own address during initialization {& (rt_object_container [C]. object_list), & (rt_object_container [C]. object_list)} // The Kernel Object Management System. rt_object _ is used here _ Information array to implement struct rt_object_information rt_object_container [identifier] ={/ * initialize object container-thread */)}, // thread object information {rt_object_class_thread, _ identifier (rt_object_class_thread ), sizeof (struct rt_thread # ifdef rt_using_semaphore/* initialize object container-semaphore * // semaphore object information {rt_object_class_semaphore, _ encode (rt_object_class_sem Aphore), sizeof (struct rt_semaphore)}, # endif # ifdef rt_using_mutex/* initialize object container-mutex * // mutex object information {rt_object_class_mutex, _ timeout (conflict ), sizeof (struct rt_mutex)}, # endif # ifdef rt_using_event/* initialize object container-event * // event object information {rt_object_class_event, _ struct (rt_object_class_event ), sizeof (struct rt_event)}, # End If # ifdef rt_using_mailbox/* initialize object container-Mailbox * // email object information {rt_object_class_mailbox, _ blank (rt_object_class_mailbox), sizeof (struct rt_mailbox )}, # endif # ifdef rt_using_messagequeue/* initialize object container-Message Queue * // Message Queue object information {queue, _ Queue (rt_object_class_messagequeue), sizeof (struct rt_messagequeue )}, # Endif # ifdef rt_using_memheap/* initialize object container-memory heap * // memory heap object information {memory, _ memory (rt_object_class_memheap), sizeof (struct rt_memheap )}, # endif # ifdef rt_using_mempool/* initialize object container-memory pool * // memory pool object information {rt_object_class_mempool, _ memory (rt_object_class_mempool), sizeof (struct rt_mempool )}, # endif # ifdef Rt_using_device/* initialize object container-device * // device driver object information {rt_object_class_device, _ obj_container_list_init (rt_object_class_device), sizeof (struct rt_device )}, # endif/* initialize object container-timer * // clock object information {rt_object_class_timer, _ obj_container_list_init (rt_object_class_timer), sizeof (struct rt_timer )}, # ifdef rt_using_module/* initialize object container-module * // module object information {Rt_object_class_module, _ obj_container_list_init (rt_object_class_module), sizeof (struct rt_module) },# endif}; 1. kernel object initialization ==== Initialization is divided into static and dynamic, the main difference is that the static is determined during compilation, the thread stack is on the stack, and the dynamic is determined at runtime, its stack is on the stack. /*** This function will Initialize an object and add it to Object System * management. ** @ Param object the specified object to be initialized. * @ Param type the object type. * @ Param name the object name. in system, the object's name must be unique. */void rt_object_init (struct rt_object * object, // point to the existing object pointer Enum rt_object_class_type, // The object type const char * name) // Object Name string {register RT _ Base_t temp; struct rt_object_information * information; // object container # ifdef rt_using_module/* Get module object information */Information = (rt_module_self ()! = Rt_null )? & Rt_module_self ()-> module_object [type]: & rt_object_container [type]; # else/* Get object information * // from the object container array, obtain the linked list information of this type of object. Information = & rt_object_container [type]; # endif/* initialize object's parameters * // * Set object type to static * // set object to static object-> type = type | rt_object_class_static; /* copy name * // copy the name, string, and specify the string length rt_strncpy (Object-> name, name, rt_name_max); rt_object_hook _ Call (rt_object_attach_hook, (object);/* Lock interrupt * // disable interruption temp = rt_hw_interrupt_disable (); /* Insert object into information object list * // Insert the new object into the linked list rt_list_insert_after (& (Information-> object_list), & (Object-> list) of the current object container )); /* unlock interrupt * // enable or disable rt_hw_interrupt_enable (temp);} 2. thread disconnection/*** this function will detach a static object from object system, * and the memory of sta TIC object is not freed. ** @ Param object the specified object to be detached. */void rt_object_detach (rt_object_t object) {register rt_base_t temp;/* object check */rt_assert (object! = Rt_null); rt_object_hook_call (rt_object_detach_hook, (object);/* Lock interrupt */temp = rt_hw_interrupt_disable (); /* remove from old list * // delete an object from the linked list // because this is a static object method, it is not really a delete object, just remove it from the linked list // the memory space occupied by it will not recycle rt_list_remove (& (Object-> List);/* unlock interrupt */rt_hw_interrupt_enable (temp);} 3. dynamic initialization ====# ifdef rt_using_heap/*** this function will allocate an object from object system * * @ Param type the type of object * @ Param name 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, const char * Name) // because it is dynamic, you only need to input the type and name. The memory space is the {struct rt_object * object dynamically allocated in the function; register rt_base_t temp; struct rt_object_information * information; rt_debug_not_in_interrupt; # ifdef rt_using_module/** get module object information, * module object shoshould be managed by kernel object container */Information = (rt_module_self ()! = Rt_null & (type! = Rt_object_class_module ))? & Rt_module_self ()-> module_object [type]: & rt_object_container [type]; # else/* Get object information */Information = & rt_object_container [type]; # endif object = (struct rt_object *) rt_malloc (Information-> object_size); // dynamically allocates memory space on heap based on the required space if (Object = rt_null) {/* No memory can be allocated */return rt_null ;} // The subsequent steps are similar to static ones./* initialize object's parameters * // * Set object type */Object -> Type = type;/* Set object flag */Object-> flag = 0; # ifdef rt_using_module if (rt_module_self ()! = Rt_null) {object-> flag | = rt_object_flag_module;} object-> module_id = (void *) rt_module_self (); # endif/* copy name */rt_strncpy (Object-> name, name, rt_name_max); rt_object_hook_call (rt_object_attach_hook, (object )); /* Lock interrupt */temp = rt_hw_interrupt_disable ();/* Insert object into information object list */rt_list_insert_after (& (Information-> object_list ), & (Object-> List);/* unloc K interrupt */rt_hw_interrupt_enable (temp);/* return object */return object;} 4. dynamic thread deletion =====/ *** this function will delete an object and release object memory. ** @ Param object the specified object to be deleted. */void rt_object_delete (rt_object_t object) {register rt_base_t temp;/* object check */rt_assert (object! = Rt_null); rt_assert (! (Object-> type & rt_object_class_static); // asserted that it is not static rt_object_hook_call (rt_object_detach_hook, (object);/* Lock interrupt */temp = rt_hw_interrupt_disable (); /* remove from old list * // first Delete rt_list_remove (& (Object-> List) from the linked list;/* unlock interrupt */rt_hw_interrupt_enable (temp ); # If defined (rt_using_module) & defined (rt_using_slab) if (Object-> flag & rt_object_flag_module) rt_module_free (rt_module_t) object-> module_id, object ); else # endif/* free the memory of object * // because it is dynamic, you need to release the occupied space rt_free (object);} # endif