ChibiOS/os/rt/dox/rt_arch.dox

356 lines
10 KiB
Plaintext

/*
ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
This file is part of ChibiOS.
ChibiOS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
ChibiOS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @startuml {rt_arch.png} "RT Core"
* package "Lists and Queues" {
* class ch_list_t {
* - next: ch_list_t *
* + ch_list_init()
* + ch_list_isempty()
* + ch_list_notempty()
* + ch_list_push()
* + ch_list_pop()
* }
* class ch_queue_t {
* - next: ch_queue_t *
* - prev: ch_queue_t *
* + ch_queue_init()
* + ch_queue_isempty()
* + ch_queue_notempty()
* + ch_queue_insert()
* + ch_queue_fifo_remove()
* + ch_queue_lifo_remove()
* + ch_queue_dequeue()
* }
* class ch_pqueue_t {
* # next: ch_pqueue_t *
* # prev: ch_pqueue_t *
* # prio: tprio_t
* + ch_pqueue_init()
* + ch_pqueue_fifo_remove_highest()
* + ch_pqueue_insert_ahead()
* + ch_pqueue_insert_behind()
* }
* }
*
* package OS {
* class "Port Timer" <<(S,#FF7700) Singleton>> {
* + {static} port_timer_get_time()
* }
*
* class "Port Layer" <<(S,#FF7700) Singleton>> {
* + {static} port_init()
* + {static} port_lock()
* + {static} port_unlock()
* + {static} port_suspend()
* + {static} port_enable()
* + {static} port_disable()
* + {static} port_switch()
* + {static} port_wait_for_interrupt()
* + {static} port_rt_get_counter_value()
* + {static} port_get_core_id()
* }
* "Port Layer" .r.> "Port Timer" : use\ntick-less mode\nonly
*
* class System <<(S,#FF7700) Singleton>> {
* - {static} ch_system : ch_system_t
* - {static} ch0 : os_instance_t
* - {static} ch1 : os_instance_t
* ~ currcore: os_instance_t *
* }
*
* class tm_calibration_t {
* ~ offset : sysinterval_t
* ~ __tm_calibration_object_init()
* }
*
* class system_debug_t {
* # panic_msg : volatile char *
* # isr_cnt : cnt_t
* # lock_cnt : cnt_t
* ~ __dbg_object_init()
* + chDbgCheck()
* + chDbgAssert()
* + chDbgCheckClassI()
* + chDbgCheckClassS()
* }
*
* class trace_event_t {
* }
*
* class trace_buffer_t {
* - prt : trace_event_t *
* ~ __trace_object_init()
* + chTraceWrite()
* + chTraceSuspend()
* + chTraceResume()
* }
* trace_buffer_t "1" *-- "1..*" trace_event_t : trace events\nbuffer
* trace_buffer_t "1" o-- "1" trace_event_t : next\nwritten
*
* class kernel_stats_t {
* # n_irq : ucnt_t
* # n_ctxswc : ucnt_t
* # m_crit_thd : time_measurement_t
* # m_crit_isr : time_measurement_t
* ~ __stats_object_init()
* }
*
* class registry_t {
* - queue : ch_queue_t
* ~ __reg_object_init()
* + {static} chRegFirstThread()
* + {static} chRegNextThread()
* + {static} chRegFindThreadByName()
* + {static} chRegFindThreadByPointer()
* + {static} chRegFindThreadByWorkingArea()
* }
* registry_t "1" o-- "1--*" thread_t : alive\nthreads
*
* class ch_system_t {
* + state : ch_system_state_t
* - reglist : registry_t
* - tmc : tm_calibration_t
* - instances[] : os_instance_t *
* + {static} chSysInit()
* + {static} chSysLock()
* + {static} chSysUnlock()
* + {static} chSysLockFromISR()
* + {static} chSysUnlockFromISR()
* + {static} chSysSwitch()
* }
* ch_system_t .u.> "Port Layer" : use
* ch_system_t *-- "1" registry_t : SMP\nonly
* ch_system_t *-r- "1" tm_calibration_t
* ch_system_t "1" o-- "1..*" os_instance_t : registered\ninstances\none for\neach core
*
* class os_instance_t {
* ~ core_id : core_id_t
* ~ rlist : ready_list_t
* ~ vtlist : virtual_timers_list_t
* ~ reglist : registry_t
* ~ mainthread : thread_t
* ~ dbg : system_debug_t
* ~ trace_buffer : trace_buffer_t
* ~ kernel_stats : kernel_stats_t
* + chInstanceObjectInit()
* ~ __instance_get_currthread()
* ~ __instance_set_currthread()
* }
* os_instance_t *-- "1" thread_t : Main\nThread
* os_instance_t *-- "1" registry_t : Non-SMP\nonly
* os_instance_t *-- "1" system_debug_t
* os_instance_t *-- "1" trace_buffer_t
* os_instance_t *-- "1" kernel_stats_t
*
* class thread_t {
* .. union ..
* - list : ch_list_t
* - queue : ch_queue_t
* - pqueue : ch_pqueue_t
* .. end union ..
* - state : tstate_t
* - owner : os_instance_t
* - rqueue : ch_queue_t
* - ctx : port_context
* - waiting: ch_list_t
* + {static} chThdCreate()
* + {static} chThdSleep()
* + {static} chThdSleepUntil()
* + {static} chThdExit()
* + chThdWait()
* + chThdAddRef()
* + chThdRelease()
* }
* thread_t o-- "0..*" thread_t : threads waiting\nfor termination
* thread_t o-- "1" os_instance_t : owner\ninstance
*
* class ready_list_t {
* - pqueue : ch_pqueue_t
* - current : thread_t *
* + {static} chSchReadyI()
* + {static} chSchWakeupS()
* + {static} chSchGoSleepS()
* + {static} chSchGoSleepTimeoutS()
* }
* ready_list_t "1" o-- "1..*" thread_t : ready\nthreads
* ready_list_t "0..1" o-- "1" thread_t : current\nthread
* ready_list_t "1" --* os_instance_t : instance\nready list
* }
*
* OS ..> "Lists and Queues" : use
* System *-- "1" ch_system_t : system\nroot object
* System *-- "1..2" os_instance_t : predefined\ninstances
* System o.. "1" os_instance_t : current core/instance\nmediated by\nport layer
*
* package "Virtual Timers" {
* class delta_list_t {
* - next : delta_list_t *
* - prev : delta_list_t *
* - delta : sysinterval_t
* }
*
* class virtual_timer_t {
* - dlist : delta_list_t
* - func : vtfunc_t
* - par : void *
* + {static} chVTDoTickI()
* + chVTObjectInit()
* + chVTSet()
* + chVTReset()
* }
* virtual_timer_t <.. ready_list_t : use
* virtual_timer_t *-- "1" delta_list_t
*
* class virtual_timers_list_t {
* - dlist : delta_list_t
* - systime : systime_t
* - lasttime : systime_t
* - laststamp : uint64_t
* # __vt_object_init()
* }
* virtual_timers_list_t o-- "0..*" virtual_timer_t : active timers
* virtual_timers_list_t *-- "1" delta_list_t
* virtual_timers_list_t "1" --* os_instance_t
* virtual_timers_list_t ..> "Port Timer" : use\ntick-less mode\nonly
* }
*
* @enduml
*
* @startuml {rt_arch.png} "RT Synchronization"
* package OS {
* class thread_t {
* - queue: ch_queue_t
* - wtmtxp: mutex_t *
* }
* }
* package "Lists and Queues" {
* class ch_list_t
* class ch_queue_t
* }
* package "Low Level Synchronization" {
*
* class thread_reference_t {
* - ref : thread_t *
* + chThdSuspendS()
* + chThdSuspendTimeoutS()
* + chThdResumeI()
* + chThdResumeS()
* }
* class threads_queue_t {
* - queue: ch_queue_t
* + chThdQueueObjectInit()
* + chThdEnqueueTimeoutS()
* + chThdDequeueNextI()
* + chThdDequeueAllI()
* }
* }
* package Messages {
* class messages <<(S,#FF7700) Singleton>> {
* + {static} chMsgWait()
* + {static} chMsgGet()
* + {static} chMsgRelease()
* + {static} chMsgSend()
* }
* }
* package Semaphores {
* class semaphore_t {
* - queue: ch_queue_t
* - cnt : cnt_t
* + chSemObjectInit()
* + chSemWait()
* + chSemWaitTimeout()
* + chSemSignal()
* + chSemReset()
* }
* }
* package Monitors {
* class mutex_t {
* - queue: ch_queue_t
* - owner : thread_t *
* - next : mutex_t *
* - cnt : cnt_t
* + chMtxObjectInit()
* + chMtxLock()
* + chMtxTryLock()
* + chMtxUnlock()
* + chMtxUnlockAll()
* }
* class condition_variable_t {
* - queue: ch_queue_t
* + chCondObjectInit()
* + chCondSignal()
* + chCondBroadcast()
* + chCondWait()
* + chCondWaitTimeout()
* }
* mutex_t "1" .l. "0..*" condition_variable_t : indirect\ncollaboration
* mutex_t o-- "0..*" thread_t : waiting\nthreads
* mutex_t o-- "0..1" thread_t : owner\nthread
* mutex_t o-- "0..1" mutex_t : next\nowned mutex
* condition_variable_t o-- "0..*" thread_t : waiting\nthreads
* }
*
* messages -u- thread_t : collaboration
*
* package Events {
* class events <<(S,#FF7700) Singleton>> {
* + {static} chEvtSignal()
* + {static} chEvtWaitOne()
* + {static} chEvtWaitAny()
* + {static} chEvtWaitAll()
* + {static} chEvtDispatch()
* }
* class event_source_t {
* - next : event_listener_t *
* + chEvtObjectInit()
* + chEvtRegister()
* + chEvtBroadcastFlags()
* }
* class event_listener_t {
* - next : event_listener_t *
* - listener : thread_t *
* - events : eventmask_t
* - flags : eventflags_t
* - wflags : eventflags_t
* }
* event_source_t "1" o-- "0..*" event_listener_t : registered\nlisteners
* event_listener_t o-- "1" event_listener_t : next\nregistered\nlistener
* event_listener_t "0..*" o-- "1" thread_t : listening\nthread
* }
*
* events -u- thread_t : collaboration
*
* thread_reference_t o-- "0..1" thread_t : referred\nthread
*
* threads_queue_t o-- "0..*" thread_t : queued\nthreads
*
* ch_queue_t "1" --* threads_queue_t
* ch_queue_t "1" --* semaphore_t
* ch_queue_t "1" --* mutex_t
* ch_queue_t "1" --* condition_variable_t
*
* thread_t o-- "0..*" mutex_t: owned\nmutexes
*
* semaphore_t o-- "0..*" thread_t : waiting\nthreads
*
* @enduml
*/