Greetings!
Here’s another tidbit from my research into multi-booting the Pi. Though I could put it in those sections, it’s sufficiently interesting that I decided to break it out into its own posting.
Issue:
There may be times when - while booting - you may want to make configuration changes based on the boot environment.
For example:
-
Booting a Pi-4 is different than booting earlier versions because the GPU handles memory allocation differently - so you may want to set a different value.
-
If a particular monitor is attached, you may want to configure the HDMI video out differently to accommodate a quirk in the monitor.
-
You have set internal settable configuration bits on one particular board to change some fundamental aspect of how the board works, essentially making it unique.
-
Or, as in my case, you may want to allow GPIO pins to change something about the way it boots when you apply power.
The Raspberry Pi has a way to accommodate things like this by the use of simple “conditional” statements. You’ve already seen one if you’ve looked at your Pi’s config.txt file - the part that starts with [pi4], followed by the one that says [all]
The “official” documentation on the config.txt file, (and all the fun things you can do with it!), can be found here: config.txt - Raspberry Pi Documentation
To summarize, (and point out an important “gotcha!”):
Conditional parts of the config.txt file are special conditional statements enclosed in square brackets, like this:
-
[gpio19=0] which works if Broadcomm GPIO pin 19 is pulled low.
-
[0x12345678] which ONLY works with the one, unique, board with serial number 0x12345678.
-
[EDID=VSC-TD2220] which works if a specific monitor is plugged in - maybe it needs audio forced, or a specific resolution that is not auto-detected?
There’s one big “gotcha!”
The documentation on config,.txt conditional statements implies strongly that groups of conditional statements, when grouped together, act as the logical AND of ALL the statements taken together.
Viz.:
[gpio19=0]
[pi4]
[EDID=VSC-TD2220]
do this specific thing. . . .
According to the documentation, this should work like this:
IF
gpio pin 19 is pulled low
AND
this is a Pi-4
AND
a specific monitor is plugged in
THEN
do this specific thing.
This is NOT true.
What actually happens is that:
-
each conditional statement is its own logical group of statements, independent of all others
-
The conditional’s logical scope ends when
- Another conditional statement occurs
or - The end of the config.txt file is reached.
(Note that you can combine/merge config.txt type files using the special include statement, so this may not be entirely true.)
- Another conditional statement occurs
Because of this, the group of conditional statements given before:
[gpio19=0]
[pi4]
[EDID=VSC-TD2220]
do this. . . .
actually works like this:
[gpio19=0]
(if true, then do nothing because there’s nothing here)
[pi4]
(there’s nothing here either, so nothing happens)
[EDID=VSC-TD2220]
do this. . . .
(because there’s something here, that gets done, but ONLY if that particular monitor is plugged in, without any input from the other two conditions.
Note what I said before - a conditional block ends ONLY when another conditional block is reached, (or, maybe, the end of the file.)
This has important consequences.
For the sake of argument, assume you have a config.txt file like this:
and (for orginazitional reasons), you want to add a special group of statements that ONLY happen when it’s run on a PI-4, so you do this:
Do you see the problem? (Hint: I got caught by this very thing yesterday and it drove me crazy for a day and a half!)
Answer: The conditional statement NEVER ends, so ALL of the statements after the [pi4] ONLY happen if a Pi-4 is plugged in, which is not what we want.
The solution is a special conditional statement - [all] - which translates to “if (true)” which ends the previous conditional statement and starts reading configurations for everyone again.
This is how you fix that particular problem:
In my case, I inadvertently disabled the robot’s camera unless a specific switch was thrown and I wasted a day and a half taking my poor 'bot apart because I thought either the camera or the cable had died. What actually happened is that I forgot to end a conditional statement with an [all], and it included the rest of the entire config.txt as part of the condition! -
Of course, you could have put the [pi] at the end, but it’s easier to understand if you group statements logically by putting configuration statements that are similar together in a compact group. You can do that by creating conditional blocks and ending each block with an [all] condition.
The official documentation for conditional statements strongly advises ending conditional blocks with an [all], even if you think they’re not necessary, just to avoid this kind of confusion.
Enjoy!