Files
Embedded-Hacking/WEEKS/WEEK10/QUIZ10.md
T
2026-04-15 17:23:21 -04:00

187 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Week 10 Quiz: Static & Dynamic Conditionals, PWM, Servo Motor, and Stealth Hacking
## Instructions
Choose the best answer for each question. There is only one correct answer per question.
---
## Questions
### Question 1
What is the key difference between a static conditional and a dynamic conditional in the context of this week's programs?
A) Static conditionals use `switch` statements; dynamic conditionals use `if/else`
B) Static conditionals have a variable set once that never changes (`int choice = 1`), so the same path always executes; dynamic conditionals use `getchar()` so the path depends on runtime user input
C) Static conditionals are evaluated at compile time and removed; dynamic conditionals remain in the binary
D) Static conditionals only work with integers; dynamic conditionals work with all types
> 📖 **Reference:** Week 10, Part 2 "A static conditional is one where the outcome is predetermined because the condition variable never changes" and Part 3 "A dynamic conditional is one where the condition variable changes based on runtime input"
**Correct Answer: B**
---
### Question 2
The SG90 servo motor requires a PWM signal at 50 Hz. Given the RP2350's 150 MHz system clock, what clock divider and wrap value are used to achieve this frequency?
A) Divider = 75, wrap = 39,999 — for a 2 MHz tick rate with 40,000 ticks per period
B) Divider = 150, wrap = 19,999 — divides to 1 MHz tick rate, then counts 20,000 ticks for a 20ms (50 Hz) period
C) Divider = 300, wrap = 9,999 — divides to 500 kHz with 10,000 ticks per period
D) Divider = 3000, wrap = 999 — divides to 50 kHz with 1,000 ticks per period
> 📖 **Reference:** Week 10, Part 5 "PWM Tick Rate = 150,000,000 Hz ÷ 150 = 1,000,000 Hz" and "Period = (Wrap Value + 1) × Tick Duration; 20 ms = 20,000 ticks × 1 µs/tick"
**Correct Answer: B**
---
### Question 3
Why must the servo motor be powered from VBUS (5V) through a 1000µF capacitor instead of directly from the Pico's 3.3V pin?
A) The servo requires exactly 3.3V but the capacitor boosts voltage to 5V
B) Servos can draw over 1000mA during movement spikes; the 3.3V regulator cannot handle this and would cause brownouts, damage the regulator, or damage the USB port — the capacitor absorbs current spikes
C) The 3.3V pin only provides PWM output, not power
D) The capacitor converts DC to AC for the servo motor
> 📖 **Reference:** Week 10, Part 7 "NEVER power the servo directly from the Pico's 3.3V pin! Servos can draw over 1000mA" and "The 1000µF capacitor acts as a tiny battery: Absorbs sudden current demands"
**Correct Answer: B**
---
### Question 4
In the `0x001d_static-conditionals` program, the string "one" appears in memory as bytes `6f 6e 65`. To change it to "fun", what bytes do you write?
A) `66 75 6e` — 'f' = 0x66, 'u' = 0x75, 'n' = 0x6e
B) `66 75 6d` — 'f' = 0x66, 'u' = 0x75, 'm' = 0x6d
C) `46 55 4e` — uppercase "FUN" in ASCII
D) `66 75 6e 00` — need to append a null terminator
> 📖 **Reference:** Week 10, Part 13, Step 30 "Find bytes 6f 6e 65 ('one' in ASCII), Change to 66 75 6e ('fun' in ASCII)" with the ASCII reference table
**Correct Answer: A**
---
### Question 5
The `getchar()` function in the dynamic conditionals program returns `0x31` when the user presses '1'. What does this value represent, and how does the assembly check it?
A) `0x31` is the scan code from the keyboard; the assembly uses `tst r4, #0x31`
B) `0x31` is the ASCII code for the character '1'; the assembly uses `cmp r4, #0x31` followed by `beq` to branch if equal
C) `0x31` is the UART register address; the assembly uses `ldr r4, [r0, #0x31]`
D) `0x31` is the NEC IR protocol code for button 1
> 📖 **Reference:** Week 10, Part 3 "getchar() reads a single character; '1' = 0x31, '2' = 0x32" and Part 17, Step 44 and Step 55 "cmp r4, #0x31" comparison instruction
**Correct Answer: B**
---
### Question 6
When creating stealth commands, the tutorial changes the comparison values from `0x31`/'1' and `0x32`/'2' to `0x78`/'x' and `0x79`/'y'. What additional patch is needed to make the stealth keys truly silent?
A) Change the `printf` format strings to empty strings
B) NOP out the `bl puts` and `bl printf` calls using `00 bf 00 bf` (two Thumb NOPs replacing each 4-byte `bl` instruction) and redirect branch targets to skip past the print calls
C) Change the UART baud rate to 0 so output is suppressed
D) Patch the `sleep_ms` calls to 0 so the output flashes too fast to read
> 📖 **Reference:** Week 10, Part 18, Steps 55-58 "NOP (No Operation) is an instruction that does nothing. ARM Thumb NOP encoding: 00 bf" and the patch table showing NOP-ing puts calls and redirecting branch targets
**Correct Answer: B**
---
### Question 7
The servo angle `180.0f` is encoded as `0x43340000` in IEEE-754. What are the sign, exponent, and stored mantissa fields?
A) Sign = 0, exponent = `0x86` (134, bias-adjusted = 7), mantissa = `0x340000` — value = 1.40625 × 2^7 = 180
B) Sign = 0, exponent = `0x43` (67), mantissa = `0x340000` — the first byte is always the exponent
C) Sign = 1, exponent = `0x43` (67), mantissa = `0x340000` — negative because servo goes clockwise
D) Sign = 0, exponent = `0x34` (52), mantissa = `0x430000` — bytes are swapped in the fields
> 📖 **Reference:** Week 10, Part 18, Step 59 IEEE-754 encoding example and Key Memory Addresses table showing `0x43340000` = 180.0f. Binary: `0 10000110 01101000...` → sign=0, exp=134 (134127=7), mantissa=1.40625, value=1.40625×128=180
**Correct Answer: A**
---
### Question 8
In the static conditionals program, the `sleep_ms(500)` delay value `0x1f4` is stored in the literal pool rather than as an instruction immediate. Why?
A) The literal pool is faster to access than immediates
B) `movs` can only encode immediates 0-255 (8-bit); since 500 exceeds 255, it must be loaded from the literal pool via `ldr r0, [pc, #offset]`
C) All function arguments must come from the literal pool in Thumb mode
D) The compiler always uses literal pools for `sleep_ms` arguments
> 📖 **Reference:** Week 10, Part 12, Step 27 "ldr r0, =0x1f4 ; 500 milliseconds" showing literal pool usage, and Week 9 exercise tips "movs can only encode immediates 0-255; values larger than 255 must be loaded from the literal pool"
**Correct Answer: B**
---
### Question 9
The `servo_set_angle` function contains the values `0x7D0` (2000) and `0x3E8` (1000). What do these represent in the PWM servo control calculation?
A) Maximum and minimum servo rotation speeds in RPM
B) Maximum (2000µs) and minimum (1000µs) pulse widths — the formula is `pulse = 1000 + (angle/180) × 1000`, mapping 0°-180° to 1000-2000 PWM ticks
C) The wrap value and clock divider for the PWM hardware
D) Maximum and minimum current limits in milliamps
> 📖 **Reference:** Week 10, Part 5 "Pulse = 1000 + (angle/180) × (2000 1000)" and Part 12, Step 26 "Inside the servo_set_angle function: 0x7D0 (2000) = max pulse width, 0x3E8 (1000) = min pulse width"
**Correct Answer: B**
---
### Question 10
After patching the static conditionals binary to change "1" to "2", "one" to "fun", and both `sleep_ms(500)` values to `sleep_ms(100)`, what is the observed behavior on hardware?
A) Serial output shows "2" and "fun" repeating; servo sweeps at the original speed
B) Serial output shows "2" and "fun" repeating; servo sweeps 5x faster (100ms delays instead of 500ms) — the servo is "spinning like crazy"
C) Serial output shows "1" and "one" unchanged; only the servo speed changes
D) The program crashes because "fun" is a reserved keyword in C
> 📖 **Reference:** Week 10, Part 13, Steps 29-33 "Serial output now shows: 2, fun, 2, fun..." and "The servo now moves 5x faster! It's spinning like crazy!"
**Correct Answer: B**
---
## Answer Key
1. B - Static: variable set once, same path always; Dynamic: `getchar()` changes the path based on runtime input
2. B - 150 MHz ÷ 150 = 1 MHz tick rate; 20,000 ticks (wrap 19,999) = 20ms period = 50 Hz
3. B - Servos spike over 1000mA; 3.3V regulator can't handle it; capacitor absorbs current spikes
4. A - 'f'=0x66, 'u'=0x75, 'n'=0x6e — same length as "one" (3 bytes)
5. B - `0x31` is ASCII '1'; assembly uses `cmp r4, #0x31` then `beq` to branch on match
6. B - NOP out print calls with `00 bf 00 bf` and redirect branch targets past the printf code
7. A - Sign=0 (positive), exponent field=134 (bias-adjusted 134127=7), mantissa=1.40625 → 1.40625×2^7=180
8. B - `movs` only encodes 8-bit immediates (0-255); 500 > 255 so `ldr` loads from literal pool
9. B - 2000µs max and 1000µs min pulse widths for the servo angle-to-pulse mapping formula
10. B - Output shows "2" and "fun"; servo runs at 100ms delays (5x faster than 500ms original)
---
## Scoring Guide
- **10 correct**: Excellent! You have a strong grasp of Week 10 concepts
- **8-9 correct**: Very good! Review the topics you missed
- **6-7 correct**: Good start. Go back and review the key concepts
- **5 or fewer**: Review the Week 10 material again and try the practice exercises
---
## Topics Covered
This quiz tests your understanding of:
- Static vs dynamic conditionals: fixed vs runtime-determined branching behavior
- PWM timing chain: 150 MHz → 1 MHz (÷150 divider) → 50 Hz (20,000 tick wrap)
- Servo power safety: VBUS usage, capacitor for current spike absorption
- ASCII string patching: byte-level character encoding in binary firmware
- `getchar()` return values and `cmp`/`beq` assembly comparison patterns
- Stealth command creation: NOP encoding (`00 bf`), branch target redirection
- IEEE-754 single-precision float field breakdown: sign, exponent, mantissa
- Thumb `movs` 8-bit immediate limitation and literal pool usage for larger values
- Servo pulse width mapping: `pulse = 1000 + (angle/180) × 1000`
- Combined multi-patch verification: string, timing, and behavioral changes