Lecture03 SoftwareDesignBasics
Lecture03 SoftwareDesignBasics
© 2021 Arm
1
Learning Objectives
At the end of this lecture, you should be able to:
• Outline the meaning of concurrency and give examples .
• Define the following terms: TRelease(i), TLatency(i), TResponsponse(i), TTask(i) and
TISR(i).
• Describe the following two scheduling approaches: hardware interrupt and software
scheduler.
• Explain static, dynamic run-to-completion and dynamic pre-emptive scheduling.
• Describe the following: Cyclic Executive with Interrupts, Run-To-Completion Scheduler
and Preemptive Scheduler.
• Identify the components of RTOS .
• Outline the steps in Waterfall V software development models.
2 © 2021 Arm
2
Overview
• Concurrency
• How do we make things happen at the right times?
• Software Engineering for Embedded Systems
• How do we develop working code quickly?
3 © 2021 Arm
3
CONCURRENCY
© 2021 Arm
4
MCU Hardware & Software for Concurrency
• CPU executes instructions from one or more thread Peripheral Bus
of execution
Timers
• Specialized hardware peripherals add dedicated
concurrent processing
• Watchdog timer ADC
• Analog interfacing Cortex-M
• Timers Core
• Communications with other devices GPIO
Interrupt
• Detecting external signal events
Controller
• LCD driver
I2C
5 © 2021 Arm
The MCU has extra hardware (besides the CPU core) to allow it to interface with the
outside world more easily, and to simplify processing multiple tasks concurrently.
5
Concurrent Hardware & Software Operation
Software Hardware Software Hardware Software
Timer
Main Peripheral Timer ISR A/D Converter Peripheral ADC ISR
Start timer Timer interrupt Start ADC
ADC interrupt
ADC interrupt
ADC interrupt
ADC_done = 1 ADC interrupt
Timer interrupt Start ADC
ADC interrupt
Time
ADC interrupt
ADC interrupt
ADC_done = 1 ADC interrupt
Timer interrupt Start ADC
ADC interrupt
ADC interrupt
ADC interrupt
ADC_done = 1 ADC interrupt
• Embedded systems rely on both MCU hardware peripherals and software to get
everything done on time
6 © 2021 Arm
We can use a sequence diagram to show how the different components in the system
interact with each other as time progresses.
Here we see that main function starts a hardware timer running, which in turn
generates an interrupt, which is serviced by another software function (timer ISR),
which starts another hardware component running (ADC), which results in several
additional interrupts, each of which is handled by yet another software function (ADC
ISR).
6
CPU Scheduling
• MCU’s Interrupt system provides a basic scheduling approach for CPU
• “Run this subroutine every time this hardware event occurs”
• Is adequate for simple systems
• How do we make the processor responsive? (How do we make it do the right things at
the right times?)
• If we have more software threads than hardware threads, we need to share the processor.
7 © 2021 Arm
7
Definitions
TRelease
Other
processing
Ttask
Scheduler
Task or ISR Code
Latency
Response
Time
Time
• TRelease(i) = Time at which task (or interrupt) i requests service/is released/is ready to run
• TLatency (i) = Delay between release and start of service for task i
• TResponse(i) = Delay between request for service and completion of service for task i
• TTask(i) = Time needed to perform computations for task i
• TISR(i) = Time needed to perform interrupt service routine i
8 © 2021 Arm
We define some terms to represent the individual steps the system takes in response
to an event. We will use these terms later to determine worst-case response time in a
system with many such events (and the corresponding handler code).
8
Scheduling Approaches
• Rely on MCU’s hardware interrupt system to run right code
• Event-triggered scheduling with interrupts
• Works well for many simple systems
9 © 2021 Arm
Here are two basic approaches to scheduling software. The CPU has a hardware
interrupt system which is then typically augmented with scheduler software. This has
various options.
9
Event-Triggered Scheduling using Interrupts
10 © 2021 Arm
Let’s take a look at scheduling the bike computer code using the MCU’s interrupt
system.
10
Bike Computer Functions
Reset ISR 1: ISR 2: ISR 3:
Wheel rotation Mode Key Time of Day Timer
Configure timer, rotations++; mode++; cur_time ++;
inputs and if(rotations> mode = mode % lcd_refresh--;
outputs R_PER_MILE/10) { NUM_MODES; if (lcd_refresh==0) {
tenth_miles++; return from interrupt; convert tenth_miles
cur_time = 0; rotations = 0; and display
rotations = 0; } convert speed
tenth_miles = 0; speed = and display
circumference / if (mode == 0)
while (1) { (cur_time – prev_time); convert cur_time
sleep; compute avg_speed; and display
} prev_time = cur_time; else
return from interrupt convert avg_speed
and display
lcd_refresh =
LCD_REF_PERIOD
}
11 © 2021 Arm
All of the code goes into these four handlers, which run in response to the events
listed above them. Breaking up the system software this way makes it very easy to
design, build, and test.
11
A More Complex Application
12 © 2021 Arm
12
Application Software Tasks
• Dec: Decode GPS sentence to find current vehicle position.
• Check: Check to see if approaching any pothole locations. Takes longer as the number of
potholes in database increases.
• Rec: Record position to flash memory. Takes a long time if erasing a block.
• Sw: Read user input switches. Run 10 times per second
• LCD: Update LCD with map. Run 4 times per second
Dec
Check
Rec
Sw
LCD
Time
13 © 2021 Arm
We break the software into five tasks in order to simplify its design and construction.
13
How do we schedule these tasks?
Dec • Task scheduling: Deciding which task should be
running now
Check
• Two fundamental questions:
Rec • Do we run tasks in the same order every time?
Yes: Static schedule (cyclic executive, round-robin)
No: Dynamic, prioritized schedule
Sw
• Can one task preempt another, or must it wait for
LCD completion?
Yes: Preemptive
No: Non-preemptive (cooperative, run-to-completion)
14 © 2021 Arm
Any scheduling approach we use will have to address two basic issues: task ordering
and preemption.
14
Static Schedule (Cyclic Executive)
Dec Check Rec Sw LCD Dec
15 © 2021 Arm
15
Static Schedule Example
GPS Data Arrives Checking complete
Response Time
16 © 2021 Arm
This approach doesn’t work so well in the worst case, since we have to do a lot of less
important processing before we get the pothole warning.
16
Dynamic Scheduling
• Allow schedule to be computed on-the-fly
• Based on importance or something else
• Simplifies creating multi-rate systems
17 © 2021 Arm
Instead of always running the tasks in the same order, we can change the order of the
tasks based on what’s more important.
17
Dynamic RTC Schedule
GPS Data Arrives Checking complete
Response Time
18 © 2021 Arm
Let’s start deciding which task to run next, and then running it to completion (RTC).
After the task finishes we check to see which task to run next, repeating the process.
18
Task State and Scheduling Rules
• Scheduler chooses among Ready
tasks for execution based on priority
• Scheduling Rules Task is released
Ready
• If no task is running, scheduler starts the (ready to run)
highest priority ready task
• Once started, a task runs until it Start
completes highest
• Tasks then enter waiting state until Waiting priority
triggered or released again ready task
19 © 2021 Arm
A task can be in one of three possible states with this scheduling approach: ready to
run, currently running, or waiting for something to happen.
19
Dynamic Preemptive Schedule
Response Time
20 © 2021 Arm
Let’s change the rules by allowing preemption. Instead of allowing a task to run to
completion, we allow it to be preempted if a higher-priority task is ready to run. This
will improve response time quite a bit.
20
Comparison of Response Times
Static
Rec Sw LCD Dec Check
Dynamic Run-to-Completion
Rec Dec Check
Dynamic Preemptive
Dec Check
• Pros
• Preemption offers best response time
Can do more processing (support more potholes, or higher vehicle speed)
Or can lower processor speed, saving money, power
• Cons
• Requires more complicated programming, more memory
• Introduces vulnerability to data race conditions
21 © 2021 Arm
Here we see that as we change the scheduling rules we reduce the response time for
higher priority tasks. This is done by deferring less important work until later.
However, we need to be more careful using the more responsive schedulers as they
introduce possible bugs and use more memory.
21
Common Schedulers
• Cyclic executive - non-preemptive and static
• Run-to-completion - non-preemptive and dynamic
• Preemptive and dynamic
22 © 2021 Arm
Let’s look at three common schedulers more closely to see how they are built and
used.
22
Cyclic Executive with Interrupts
BOOL DeviceARequest, DeviceBRequest,
• Two priority levels DeviceCRequest;
void interrupt HandleDeviceA() {
• main code – foreground
/* do A’s urgent work */
• Interrupts – background ...
DeviceARequest = TRUE;
• Example of a foreground / background }
void main(void) {
system while (TRUE) {
if (DeviceARequest) {
FinishDeviceA();
• Main user code runs in foreground }
if (DeviceBRequest) {
FinishDeviceB();
• Interrupt routines run in background (high }
priority) if (DeviceCRequest) {
FinishDeviceC();
• Run when triggered
}
• Handle most urgent work }
• Set flags to request processing by main loop }
23 © 2021 Arm
23
Run-To-Completion Scheduler
• Use a scheduler function to run task functions at the right rates
• Table stores information per task
Period: How many ticks between each task release
Release Time: how long until task is ready to run
ReadyToRun: task is ready to run immediately
• Scheduler runs forever, examining schedule table which indicates tasks which are ready to run (have been
“released”)
• A periodic timer interrupt triggers an ISR, which updates the schedule table
Decrements “time until next release”
If this time reaches 0, set that task’s Run flag and reload its time with the period
• Priority is typically static, so can use a table with highest priority tasks first for a fast, simple scheduler
implementation.
24 © 2021 Arm
The RTC scheduler is more complex but makes the application design much easier.
24
Preemptive Scheduler
• Task functions need not run to completion, but can be interleaved with each other
• Simplifies writing software
• Improves response time
• Introduces new potential problems
• Worst case response time for highest priority task does not depend on other tasks, only
ISRs and scheduler
• Lower priority tasks depend only on higher priority tasks
25 © 2021 Arm
A preemptive scheduler makes application design easier (mostly) and offers better
performance (response time).
25
Task State and Scheduling Rules
• Scheduler chooses among Ready tasks
for execution based on priority
What the Ready
task needs
• Scheduling Rules happens
• A task’s activities may lead it to waiting This is This isn’t
(blocked) highest highest
• A waiting task never gets the CPU. It must
be signaled by an ISR or another task.
Waiting priority priority
ready task ready task
• Only the scheduler moves tasks between
ready and running
Task needs
something Running
to happen
26 © 2021 Arm
26
What’s an RTOS?
• What does Real-Time mean?
• Can calculate and guarantee the maximum response time for each task and interrupt service routine
• This “bounding” of response times allows use in hard-real-time systems (which have deadlines which
must be met)
• What’s in the RTOS
• Task Scheduler
Preemptive, prioritized to minimize response times
Interrupt support
• Core Integrated RTOS services
Inter-process communication and synchronization (safe data sharing)
Time management
• Optional Integrated RTOS services
I/O abstractions?
memory management?
file system?
networking support?
GUI??
27 © 2021 Arm
27
SOFTWARE
ENGINEERING FOR
EMBEDDED SYSTEMS
© 2021 Arm
28
Good Enough Software, Soon Enough
• How do we make software correct enough without going bankrupt?
• Need to be able to develop (and test) software efficiently
• Follow a good plan
• Start with customer requirements
• Design architectures to define the building blocks of the systems (tasks, modules, etc.)
• Add missing requirements
Fault detection, management and logging
Real-time issues
Compliance to a firmware standards manual
Fail-safes
• Create detailed design
Implement the code, following a good development process
Perform frequent design and code reviews
Perform frequent testing (unit and system testing, preferably automated)
Use revision control to manage changes
• Perform postmortems to improve development process
29 © 2021 Arm
29
What happens when the plan meets reality?
• We want a robust plan which considers likely risks
• What if the code turns out to be a lot more complex than we expected?
• What if there is a bug in our code (or a library)?
• What if the system doesn’t have enough memory or throughput?
• What if the system is too expensive?
• What if the lead developer quits?
• What if the lead developer is incompetent, lazy, or both (and won’t quit!)?
• What if the rest of the team gets sick?
• What if the customer adds new requirements?
• What if the customer wants the product two months early?
• Successful software engineering depends on balancing many factors, many of which are
non-technical!
30 © 2021 Arm
30
Risk Reduction
• Plan the work to accommodate risks
31 © 2021 Arm
31
Software Lifecycle Concepts
• Coding is the most visible part of a software development process but is not the only
one
• The software will likely be enhanced over time - Extensive downstream modification
and maintenance!
• Corrections, adaptations, enhancements & preventive maintenance
32 © 2021 Arm
32
Requirements
• Ganssle’s Reason #5 for why embedded projects fail: Vague Requirements
• Types of requirements
• Functional - what the system needs to do
• Nonfunctional - emergent system behaviors such as response time, reliability, energy efficiency, safety, etc.
• Constraints - limit design choices
• Representations
• Text – Liable to be incomplete, bloated, ambiguous, even contradictory
• Diagrams (state charts, flow charts, message sequence charts)
– Concise
– Can often be used as design documents
• Traceability
• Each requirement should be verifiable with a test
• Stability
• Requirements churn leads to inefficiency and often “recency” problem (most recent requirement change is
assumed to be most important)
33 © 2021 Arm
33
Design Before Coding
Architectural Detailed
Coding Test the Code
Design Design
34 © 2021 Arm
34
Design Before Coding
• How much of the system do you design before coding?
AD DD C T
AD DD C T
AD DD C T
AD DD C T
AD DD C T
AD DD C T
AD Prototyping DD C T
AD DD C T
AD DD C T
35 © 2021 Arm
If we have three major subsystems (gray, blue, yellow) in the system, how should we
order our development tasks? After doing architectural design (AD) for all
subsystems, should we try to get one subsystem working and tested completely
before starting the next subsystem (top row)? Or should we take turns with each
subsystem? Or do some prototyping before detailed design? These decisions will
affect the speed and success of development.
35
Development Models
• How do we schedule these pieces?
36 © 2021 Arm
36
Waterfall (Idealized)
• Plan the work, and then Analysis
work the plan
• BUFD: Big Up-Front Design Specification
Operation and
Maintenance
37 © 2021 Arm
37
Waterfall (As Implemented)
• Reality: We are not omniscient,
Analysis
so there is plenty of
backtracking
Specification
Design
Implementation
Verification
Operation and
Maintenance
38 © 2021 Arm
38
V Model Overview
Requirements
Analysis
Requirements Validation provided by testing Functional
Specification Testing
Review
Architectural Integration
Design Testing
Review
Detailed Integration
Design Testing
Review
S/W Unit
Coding
Testing
Review
Code
• Themes:
• Link front and back ends of life-cycle for efficiency
• Provide “traceability” to ensure nothing falls through the cracks
39 © 2021 Arm
39
1. Requirements Specification and Validation Plan
• Result of Requirements Analysis
• Should contain:
• Introduction with goals and objectives of system
• Description of problem to solve
• Functional description
provides a “processing narrative” per function
lists and justifies design constraints
explains performance requirements
• Behavioral description shows how system reacts to internal or external events and situations
State-based behavior
General control flow
General data flow
• Validation criteria
tell us how we can decide that a system is acceptable. (Are we done yet?)
is the foundation for a validation test plan
• Bibliography and Appendix refer to all documents related to project and provide supplementary information
40 © 2021 Arm
40
2. Architectural (High-Level) Design
• Architecture defines the structure of the system
• Components
• Externally visible properties of components
• Relationships among components
41 © 2021 Arm
41
3. Detailed Design
• Describe aspects of how system behaves
• Flow charts for control or data
• State machine diagram
• Event sequences
42 © 2021 Arm
The third step is splitting each component in the architectural design into a detailed
design. There are several useful graphical representations.
42
State Machine for Parsing NMEA-0183
Any char. except *, \r or \n
Start $ Append char to buf.
Append char to buf. Talker + Inc. counter
*, \r or \n, Sentence
non-text, or Type
buf==$SDDBT, $VWVHW, or
counter>6 $YXXDR
Enqueue all chars. from buf
/r or /n
Sentence
Body Any char. except *
Enqueue char
*
Enqueue char
Checksum
1
Any char.
Save as checksum1
Checksum
2
Any char.
Save as checksum2
43 © 2021 Arm
A finite state machine is useful for defining state-based behavior. Conceptually, the
program waits in a state until a trigger event occurs, making the processor perform
the action on the corresponding edge (arrow, arc). The program then moves into the
next state (pointed to by the edge) and stops to await the next valid trigger event.
This approach makes software design, coding and testing much easier.
43
Flowcharts
44 © 2021 Arm
A flowchart shows the flow of control through a program with conditionals and loops.
Conceptually, the processor runs straight through blocks and transitions without
stopping until it is interrupted or switched to a different task (e.g. by the scheduler).
44
Sequence of Interactions between Components
Software Hardware Software Hardware Software
Main Timer Peripheral Timer ISR A/D Converter Peripheral ADC ISR
Start timer Timer interrupt Start ADC
ADC interrupt
ADC interrupt
ADC interrupt
ADC_done = 1 ADC interrupt
ADC interrupt
ADC interrupt
ADC_done = 1 ADC interrupt
45 © 2021 Arm
45
4. Coding and Code Inspections
• Coding driven directly by Detailed Design Specification
• Use a version control system while developing the code
• Follow a coding standard
• Eliminate stylistic variations which make understanding code more difficult
• Avoid known questionable practices
• Spell out best practices to make them easier to follow
46 © 2021 Arm
The fourth step is writing, reviewing, and testing the code at the fine-grain level.
46
Peer Code Review
• Inspect the code before testing it
47 © 2021 Arm
47
5. Software Testing
• Testing IS NOT “the process of verifying the program works correctly”
• The program probably won’t work correctly in all possible cases
Professional programmers have 1-3 bugs per 100 lines of code after it is “done”
• Testers shouldn’t try to prove the program works correctly (impossible)
If you want and expect your program to work, you’ll unconsciously miss failure because human beings are
inherently biased
48 © 2021 Arm
The fifth step is testing the system software as its components are integrated.
48
Approaches to Testing
• Incremental Testing
• Code a function and then test it (module/unit/element testing)
• Then test a few working functions together (integration testing)
Continue enlarging the scope of tests as you write new functions
– Incremental testing requires extra code for the test harness
A driver function calls the function to be tested
A stub function might be needed to simulate a function called by the function under test, and which returns or
modifies data.
The test harness can automate the testing of individual functions to detect later bugs
49 © 2021 Arm
49
Why Test Incrementally?
• Finding out what failed is much easier
• With Big Bang, since no function has been thoroughly tested, most probably have bugs
• Now the question is “Which bug in which module causes the failure I see?”
• Errors in one module can make it difficult to test another module
Errors in fundamental modules (e.g. kernel) can appear as bugs in other many other dependent modules
50 © 2021 Arm
50
6. Perform Project Retrospectives
• Goals – improve your engineering processes
• Extract all useful information learned from the just-completed project – provide “virtual experience”
to others
• Provide positive non-confrontational feedback
• Document problems and solutions clearly and concisely for future use
51 © 2021 Arm
The sixth step is to think about how to improve the development process to make the
next project run more smoothly.
51
Example Postmortem Structure
• Product • Support
• Bugs • Tools
• Software design • Team burnout
• Hardware design • Change orders
• Process • Personnel availability
• Code standards
• Code interfacing
• Change control
• How we did it
• Team coordination
52 © 2021 Arm
52