lecture 10 handout
TRANSCRIPT
Informatics for industrial applications
Lecture 10 - ChibiOS/RT
Martino [email protected]
November 17, 2011
ChibiOS/RT Kernel services Hardware Abstraction Layer
Outline
1 ChibiOS/RTIntroductionArchitectureSource organization
2 Kernel servicesBase kernel servicesSynchronizationMemory managementI/O support
3 Hardware Abstraction LayerIntroductionADC driverSerial driver
ChibiOS/RT Kernel services Hardware Abstraction Layer
Introduction
ChibiOS/RT is a complete, portable, open source,compact and extremely fast RTOS.
Complete: threads, synchronization, memory management,hardware drivers
Portable: layered architecture enables easy porting
Open source: GPL3, GPL3 with linking exception, commerciallicense
Compact: 5.5 Kb kernel size, 400 bytes RAM (on ARM Cortex-M3)
Extremely fast: best in class context switch performance
ChibiOS/RT Kernel services Hardware Abstraction Layer
ChibiOS/RT history
ChibiOS/RT ancestor was an Operating System for Motorola 68000
In 1989 it supported GCC, ran EMACS, was preemptive andrealtime
...but in 1991 Linus Torvalds began the development of Linux
The original full-featured OS turned in a minimalistic, efficient,RTOS: ChibiOS/RT father
In 2007, after 15 years, it turned to ChibiOS/RT: an open sourceRTOS project targeted to embedded systems
The project is lead and mainly developed by Giovanni Di Sirio
ChibiOS/RT started growing in features, ports and users
Every part of the project has been deeply documented (Doxygen)
ChibiOS/RT Kernel services Hardware Abstraction Layer
ChibiOS/RT Features
Not just a schedulerSupport for startup and board initializationHAL abstracting many common device driversIntegration with other open source projects
Static designEverything in the kernel is static, nowhere memory is allocated orfreedAllocator subsystems are optionally available, but they are not part ofcore OSDynamic services are built as a layer on top of the fully static kernel
No error conditionsSystem APIs have no error conditionsAll the static core APIs always succeed if correct parameters arepassed
Simple, fast and compactEach API function should have the parameters you would expectNote: first “fast”, then “compact”
ChibiOS/RT Kernel services Hardware Abstraction Layer
ChibiOS/RT architecture
Kernel: the platform independent part of the OS kernel
Port layer: the architecture/compiler dependent part of the OSkernel
System startup, interrupts abstraction, lock/unlock primitives,context switch related structures and codeVery little code, but the quality of the implementation can affectheavily the performance of the ported OSProbably the most critical part of the whole OS
Hardware Abstraction Layer: abstract device drivers
Common I/O API to the applicationTotally portable across the various architectures and compilers
Platform layer: device drivers implementations
Board Initialization: files used to initialize the target board and theHAL before launching the application
ChibiOS/RT Kernel services Hardware Abstraction Layer
System states
Init In this state it is not possible to use any system API exceptchSysInit(), all the maskable interrupt are disabled
Normal All the interrupt sources are enabled and the system APIsare accessible, threads are running
Disabled In this state all interrupt sources are disabled, onlychSysSuspend() or chSysEnable() APIs can be invoked
Sleep Architecture-dependent low power mode, the idle threadgoes in this state and waits for interrupts
S-Locked Kernel locked and regular interrupt sources disabled, fastinterrupt sources are enabled
I-Locked Kernel locked and all interrupt sources disabled
Serving Regular Interrupt No system APIs are accessible but it ispossible to switch to the I-Locked state usingchSysLockFromIsr() and then invoke any I-Class API
Halted All interrupt sources are disabled and system stopped intoan infinite loop.
ChibiOS/RT Kernel services Hardware Abstraction Layer
API Name Suffixes
API name suffixes indicate from which system states a function canbe invoked.
API suffix can be one of the following:
None APIs without any suffix can be invoked only from theuser code in the Normal state unless differentlyspecified
I I-Class APIs are invokable only from the I-Locked orS-Locked states
S S-Class APIs are invokable only from the S-Lockedstate
ChibiOS/RT Kernel services Hardware Abstraction Layer
Outline
1 ChibiOS/RTIntroductionArchitectureSource organization
2 Kernel servicesBase kernel servicesSynchronizationMemory managementI/O support
3 Hardware Abstraction LayerIntroductionADC driverSerial driver
ChibiOS/RT Kernel services Hardware Abstraction Layer
Base kernel services
Initialization, low level locks, idle thread
chSysInit() ChibiOS/RT initializationchSysHalt() Halts the systemchSysLock() Enters the kernel lock modechSysUnlock() Leaves the kernel lock modechSysLockFromIsr() Enters the kernel lock mode from an ISRchSysUnlockFromIsr() Leaves the kernel lock mode from an ISRidle thread() Implements the idle thread infinite loop
ISRs abstraction macros
CH IRQ PROLOGUE() IRQ handler enter codeCH IRQ EPILOGUE() IRQ handler exit codeCH IRQ HANDLER(id) Normal IRQ handler declarationCH FAST IRQ HANDLER(id) Fast IRQ handler declaration
ChibiOS/RT Kernel services Hardware Abstraction Layer
Scheduler
The strategy is very simple: the currently ready thread with thehighest priority is executed
The ready list is a double linked list of threads ordered by priority
ChibiOS/RT Kernel services Hardware Abstraction Layer
Priorities
Threads priority levels are integers from LOWPRIO to HIGHPRIO:
IDLEPRIO Special priority level reserved for the Idle ThreadLOWPRIO Lowest priority level usable by user threads
NORMALPRIO The main() thread is started at this levelHIGHPRIO Highest priority level usable by user threads
ChibiOS/RT supports multiple threads at the same priority level andschedules them using an aggressive round-robin strategy
A round-robin rotation can happen if the currently executed thread:
voluntarily invokes the chThdYield() APIvoluntarily goes into a sleep stateis preempted by an higher priority threadif CH TIME QUANTUM constant is greater than zero and thespecified time quantum expired
If CH TIME QUANTUM is equal to zero, the round robin becomescooperative
ChibiOS/RT Kernel services Hardware Abstraction Layer
Threads
A thread is an abstraction of an independent instructions flow
In ChibiOS/RT it is a C function owning a processor context, stateinformations and a dedicated stack area
The working area is declared with a macro:static WORKING AREA(waThread1, 128);
Threads are created with the chThdCreateStatic() API:Thread* chThdCreateStatic(void *wsp, size t size, tprio t prio,tfunc t pf, void *arg)
wsp pointer to a working area dedicated to the thread stacksize size of the working areaprio the priority level for the new thread
pf the thread functionarg an argument passed to the thread function, it can be
NULL
ChibiOS/RT Kernel services Hardware Abstraction Layer
Threads operations
chThdCreateStatic() Creates a new thread into a static memory area
chThdExit() Terminates the current thread
chThdWait() Blocks the execution of the invoking thread until thespecified thread terminates, then the exit code is returned
chThdResume() Resumes a suspended thread
chThdTerminate() Requests a thread termination
chThdSleep() Suspends the invoking thread for the specified time
chThdYield() Yields the time slot
ChibiOS/RT Kernel services Hardware Abstraction Layer
Counting and binary semaphores
ChibiOS/RT implements semaphores in their “counting” variant
Counting semaphores are usually used as guards of resourcesavailable in a discrete quantity
A semaphore counter can be:
negative: there are exactly -N threads queued on the semaphorezero: no waiting threads, a wait operation would put in queue theinvoking threadpositive: no waiting threads, a wait operation would not put inqueue the invoking thread
Binary semaphores are implemented as a set of macros that use theexisting counting semaphores primitives
ChibiOS/RT Kernel services Hardware Abstraction Layer
Mutexes
The mutexes in ChibiOS/RT implements the full priority inheritancemechanism
When a thread is queued on a mutex, any thread holding the mutexgains the same priority of the waiting thread (if their priority wasnot already equal or higher)
The algorithm complexity (worst case) is N with N equal to thenumber of nested mutexes
Mutexes operations:
chMtxLock() Locks the specified mutexchMtxTryLock() Tries to lock a mutexchMtxUnlock() Unlocks the next owned mutex in reverse lock order
Enabling mutexes requires 5-12 extra bytes in the Thread structure
ChibiOS/RT Kernel services Hardware Abstraction Layer
Event flags
Each thread has a mask of pending event flags inside its Threadstructure
Operations defined for event flags:
Wait: the invoking thread goes to sleep until a certain combinationof event flags becomes pendingClear: a mask of event flags is cleared from the pending events maskSignal: an event mask is directly ORed to the mask of the signaledthreadBroadcast: each thread registered on an Event Source is signaledDispatch: an events mask is scanned and for each bit set to one anassociated handler function is invoked
Enabling events requires 1-4 extra bytes in the Thread structure
ChibiOS/RT Kernel services Hardware Abstraction Layer
Synchronous messages
Threads can both act as message servers and/or message clients
Messages are not copied, a pointer passed
Synchronous messages operations:
chMsgSend() Sends a message to the specified threadchMsgGet() Returns the message carried by the specified threadchMsgWait() Suspends the thread and waits for an incoming
messagechMsgRelease() Releases a sender thread specifying a response
message
Enabling messages requires 6-12 extra bytes in the Thread structure
ChibiOS/RT Kernel services Hardware Abstraction Layer
Mailboxes
A mailbox is an asynchronous communication mechanism
A message is a variable of type msg t that has the size of a datapointer
To exchange large amount of data, memory can be allocated fromthe posting side and freed on the fetching side
Mailboxes operations:
chMBPost() Posts a message on the mailbox in FIFO orderchMBPostAhead() Posts a message on the mailbox with urgent
prioritychMBFetch() A message is fetched from the mailbox and removed
from the queuechMBReset() The mailbox is emptied and all the stored messages
are lost
ChibiOS/RT Kernel services Hardware Abstraction Layer
Core memory manager
The core memory manager is a simplified allocator
It only allows to allocate memory blocks without the possibility tofree them
This allocator is meant as a memory blocks provider for the otherallocators
By having a centralized memory provider the various allocators cancoexist and share the main memory
Core memory manager operations:
chCoreAlloc() Allocates a memory blockchCoreStatus() Reports the core memory status
ChibiOS/RT Kernel services Hardware Abstraction Layer
Heaps
The heap allocator implements a first-fit strategy
Its APIs are functionally equivalent to the usual malloc() and free()functions
Heap APIs are guaranteed to be thread safe
Heap operations:
chHeapInit() Initializes a memory heap from a static memory areachHeapAlloc() Allocates a block of memory from the heap by using
the first-fit algorithmchHeapFree() Frees a previously allocated memory blockchHeapStatus() Reports the heap status
ChibiOS/RT Kernel services Hardware Abstraction Layer
Memory pools
Memory pools allow to allocate/free fixed size objects in constanttime and reliably without memory fragmentation problems
Memory pools can grow in size asking for memory to a memoryprovider
Memory pools are initalized with the MEMORYPOOL DECL()macro:MEMORYPOOL DECL(name, size, provider)
Memory pool operations:
chPoolInit() : Initializes an empty memory poolchPoolAlloc() : Allocates an object from a memory poolchPoolFree() : Releases an object into a memory pool
ChibiOS/RT Kernel services Hardware Abstraction Layer
Dynamic threads
If one of the memory allocators is available, threads can be declareddynamically
Thread working area can be allocated from both heaps and memorypools
The memory is not freed when the thread terminates
The spawning thread has to collect the thread final status, e.g., withchThdWait(), to free the memory
Dynamic threads operations:
chThdCreateFromHeap() Creates a new thread allocating thememory from the heap
chThdCreateFromMemoryPool() Creates a new thread allocatingthe memory from the specified memory pool
ChibiOS/RT Kernel services Hardware Abstraction Layer
Abstract Streams
Abstract streams are abstract interface for generic data streams
They make the access to streams independent from theimplementation logic
No code is present, streams are just abstract interfaces
The stream interface can be used as base class for high level objecttypes such as files, sockets, serial ports, pipes etc
Methods are defined in BaseSequentialStreamVMT virtual methodstable
Methods are then called through macros:#define chSequentialStreamWrite(ip, bp, n) ((ip)→vmt→write(ip,bp, n))#define chSequentialStreamRead(ip, bp, n) ((ip)→vmt→read(ip,bp, n))
ChibiOS/RT Kernel services Hardware Abstraction Layer
I/O queues
ChibiOS/RT queues are mostly used in serial-like device drivers
Input queues and output queues are defined
Bidirectional queue are implemented pairing an input and an outputqueue together
I/O queues operations:
chIQInit() Initializes an input queuechIQReset() Resets an input queue
chIQPutI() Input queue writechIQGetTimeout() Input queue read with timeoutchOQPutTimeout() Output queue write with timeoutchOQGetI() Output queue read
ChibiOS/RT Kernel services Hardware Abstraction Layer
Outline
1 ChibiOS/RTIntroductionArchitectureSource organization
2 Kernel servicesBase kernel servicesSynchronizationMemory managementI/O support
3 Hardware Abstraction LayerIntroductionADC driverSerial driver
ChibiOS/RT Kernel services Hardware Abstraction Layer
Introduction
The HAL is the abstract interface between ChibiOS/RT applicationand hardware
A device driver is usually split in two layers
The high level device driver contains the definitions of the driver’sAPIs and the platform independent part of the driver
The low level device driver (LLD) contains the platform dependentpart of the driver
The LLD may be not present in those drivers that do not access thehardware directly but through other device drivers (e.g., MMC SPI)
ChibiOS/RT Kernel services Hardware Abstraction Layer
ADC driver
This driver defines a generic Analog to Digital Converter driver
The driver supports several conversion modes:
one shot: the driver performs a single group conversionlinear buffer: the driver performs a series of group conversions thenstopscircular buffer: when the buffer is filled, it is automatically restartedfrom the buffer base
The driver is able to invoke callbacks during the conversion process
It is not thread safe for performance reasons
adcAcquireBus() and adcReleaseBus() to gain exclusive access
Two main structures are used:
ADCDriver is the generic driver structureADCConfig is the platform dependent configuration structure
ChibiOS/RT Kernel services Hardware Abstraction Layer
ADC driver operations
adcStart() Configures and activates the ADC peripheral
adcStop() Deactivates the ADC peripheral and enters low power mode
adcStartConversion() Starts an ADC conversion
adcStopConversion() Stops an ongoing conversion
adcAcquireBus() Gains exclusive access to the ADC peripheral
adcReleaseBus() Releases exclusive access to the ADC peripheral
ChibiOS/RT Kernel services Hardware Abstraction Layer
Serial driver
This driver defines a generic full duplex serial driver
The driver implements a implements a SerialDriver interface (VMT)
It uses I/O Queues for communication between the upper and thelower driver
Event flags are used to notify the application about incoming data,outgoing data and other I/O events
Two main structures are used:
SerialDriver is the generic driver structureSerialConfig is the platform dependent configuration structure
ChibiOS/RT Kernel services Hardware Abstraction Layer
Serial driver operations
sdStart() Configures and starts the driver
sdStop() Stops the driver
sdWrite() Direct blocking write to a SerialDriver
sdWriteTimeout() Direct blocking write to a SerialDriver with timeoutspecification
sdAsynchronousWrite() Direct non-blocking write to a SerialDriver
sdRead() Direct blocking read from a SerialDriver
sdReadTimeout() Direct blocking read from a SerialDriver with timeoutspecification
sdAsynchronousRead() Direct non-blocking read from a SerialDriver