mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-06-06 22:33:57 +02:00
187 lines
9.8 KiB
Markdown
187 lines
9.8 KiB
Markdown
# 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 (134−127=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 134−127=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
|