Skip to content

Commit 62ff442

Browse files
committed
raspberry detection in line with official steer
1 parent 751e6f0 commit 62ff442

1 file changed

Lines changed: 122 additions & 75 deletions

File tree

Source/Utilities/Helper.cpp

Lines changed: 122 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -168,17 +168,131 @@ namespace Util
168168
return "Mac";
169169

170170
#elif __linux__
171-
std::string line, model_name, revision;
171+
std::string line, model_name;
172172

173-
// Try device-tree first (works for Raspberry Pi and other ARM boards)
173+
// Raspberry Pi: prefer device-tree compatible (recommended by Raspberry Pi docs)
174+
// Ref: https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#raspberry-pi-revision-codes
174175
{
175-
std::ifstream inFile("/proc/device-tree/model");
176-
if (inFile.is_open() && std::getline(inFile, line))
176+
auto normalize_rpi_model = [](const std::string &model) -> std::string
177177
{
178-
// Remove null terminator if present
179-
if (!line.empty() && line[line.length() - 1] == '\0')
180-
line.resize(line.length() - 1);
178+
// Keep it intentionally simple: map device-tree models into stable product families.
179+
if (model == "5-model-b")
180+
return "Raspberry Pi 5";
181+
if (model == "4-model-b")
182+
return "Raspberry Pi 4";
183+
if (model == "500")
184+
return "Raspberry Pi 500";
185+
if (model == "400")
186+
return "Raspberry Pi 400";
187+
if (model == "3-model-b" || model == "3-model-b-plus" || model == "3-model-a-plus")
188+
return "Raspberry Pi 3";
189+
if (model == "2-model-b")
190+
return "Raspberry Pi 2";
191+
// Compute Modules
192+
if (model == "compute-module")
193+
return "Raspberry Pi Compute Module 1";
194+
if (model == "3-compute-module")
195+
return "Raspberry Pi Compute Module 3";
196+
if (model == "3-plus-compute-module")
197+
return "Raspberry Pi Compute Module 3+";
198+
if (model == "4-compute-module" || model == "4s-compute-module")
199+
return "Raspberry Pi Compute Module 4";
200+
if (model == "5-compute-module")
201+
return "Raspberry Pi Compute Module 5";
202+
// Future-proofing: some distros/DTs may append qualifiers.
203+
if (model.find("5-compute-module") == 0)
204+
{
205+
if (model.find("lite") != std::string::npos)
206+
return "Raspberry Pi Compute Module 5 Lite";
207+
return "Raspberry Pi Compute Module 5";
208+
}
209+
if (model == "model-zero" || model == "model-zero-w" || model == "model-zero-2-w")
210+
return "Raspberry Pi Zero";
211+
if (model == "model-a" || model == "model-a-plus" || model == "model-b" || model == "model-b-plus" ||
212+
model == "model-b-rev2")
213+
return "Raspberry Pi 1";
214+
return "";
215+
};
216+
217+
auto parse_dt_compatible = [&](const std::string &path) -> std::string
218+
{
219+
std::ifstream inFile(path, std::ios::in | std::ios::binary);
220+
if (!inFile.is_open())
221+
return "";
222+
223+
std::string token;
224+
while (std::getline(inFile, token, '\0'))
225+
{
226+
// token looks like: "raspberrypi,5-model-b" or "brcm,bcm2712"
227+
static const std::string prefix = "raspberrypi,";
228+
if (token.compare(0, prefix.size(), prefix) == 0)
229+
{
230+
std::string model = token.substr(prefix.size());
231+
std::string mapped = normalize_rpi_model(model);
232+
if (!mapped.empty())
233+
return mapped;
234+
}
235+
}
236+
return "";
237+
};
238+
239+
std::string rpi = parse_dt_compatible("/proc/device-tree/compatible");
240+
if (rpi.empty())
241+
rpi = parse_dt_compatible("/sys/firmware/devicetree/base/compatible");
242+
if (!rpi.empty())
243+
return rpi;
244+
}
245+
246+
// Try device-tree model as a fallback (works for Raspberry Pi and other ARM boards)
247+
{
248+
auto read_model = [&](const std::string &path) -> std::string
249+
{
250+
std::ifstream inFile(path, std::ios::in | std::ios::binary);
251+
if (!inFile.is_open() || !std::getline(inFile, line, '\0'))
252+
return "";
253+
if (!line.empty() && line.back() == '\0')
254+
line.pop_back();
181255
return line;
256+
};
257+
258+
std::string model = read_model("/proc/device-tree/model");
259+
if (model.empty())
260+
model = read_model("/sys/firmware/devicetree/base/model");
261+
if (!model.empty())
262+
{
263+
// Normalize common Raspberry Pi strings to the simple families requested.
264+
if (model.find("Raspberry Pi 5") != std::string::npos)
265+
return "Raspberry Pi 5";
266+
if (model.find("Raspberry Pi 500") != std::string::npos)
267+
return "Raspberry Pi 500";
268+
if (model.find("Raspberry Pi 400") != std::string::npos)
269+
return "Raspberry Pi 400";
270+
if (model.find("Raspberry Pi 4") != std::string::npos)
271+
return "Raspberry Pi 4";
272+
if (model.find("Raspberry Pi 3") != std::string::npos)
273+
return "Raspberry Pi 3";
274+
if (model.find("Raspberry Pi 2") != std::string::npos)
275+
return "Raspberry Pi 2";
276+
if (model.find("Compute Module 5") != std::string::npos)
277+
{
278+
if (model.find("Lite") != std::string::npos || model.find("lite") != std::string::npos)
279+
return "Raspberry Pi Compute Module 5 Lite";
280+
return "Raspberry Pi Compute Module 5";
281+
}
282+
if (model.find("Compute Module 4") != std::string::npos)
283+
return "Raspberry Pi Compute Module 4";
284+
if (model.find("Compute Module 3+") != std::string::npos)
285+
return "Raspberry Pi Compute Module 3+";
286+
if (model.find("Compute Module 3") != std::string::npos)
287+
return "Raspberry Pi Compute Module 3";
288+
if (model.find("Compute Module") != std::string::npos)
289+
return "Raspberry Pi Compute Module 1";
290+
if (model.find("Raspberry Pi Zero") != std::string::npos)
291+
return "Raspberry Pi Zero";
292+
if (model.find("Raspberry Pi Model") != std::string::npos)
293+
return "Raspberry Pi 1";
294+
295+
return model;
182296
}
183297
}
184298

@@ -208,7 +322,7 @@ namespace Util
208322
}
209323
}
210324

211-
// Parse cpuinfo for Raspberry Pi revision codes and CPU model
325+
// Parse cpuinfo for CPU model name (best-effort fallback)
212326
{
213327
std::ifstream inFile("/proc/cpuinfo");
214328
if (inFile.is_open())
@@ -219,79 +333,12 @@ namespace Util
219333
{
220334
std::size_t pos = line.find(": ");
221335
if (pos != std::string::npos)
222-
{
223336
model_name = line.substr(pos + 2);
224-
}
225-
}
226-
else if (line.substr(0, 8) == "Revision")
227-
{
228-
std::size_t pos = line.find(": ");
229-
if (pos != std::string::npos)
230-
{
231-
revision = line.substr(pos + 2);
232-
}
233337
}
234338
}
235339
}
236340
}
237341

238-
// Raspberry Pi revision lookup table
239-
if (!revision.empty())
240-
{
241-
static const std::unordered_map<std::string, std::string> rpi_revisions = {
242-
{"900021", "Raspberry Pi A+ 1.1"},
243-
{"900032", "Raspberry Pi B+ 1.2"},
244-
{"900092", "Raspberry Pi Zero 1.2"},
245-
{"900093", "Raspberry Pi Zero 1.3"},
246-
{"9000c1", "Raspberry Pi Zero W 1.1"},
247-
{"9020e0", "Raspberry Pi 3A+ 1.0"},
248-
{"920092", "Raspberry Pi Zero 1.2"},
249-
{"920093", "Raspberry Pi Zero 1.3"},
250-
{"900061", "Raspberry Pi CM1 1.1"},
251-
{"a01040", "Raspberry Pi 2B 1.0"},
252-
{"a01041", "Raspberry Pi 2B 1.1"},
253-
{"a02082", "Raspberry Pi 3B 1.2"},
254-
{"a020a0", "Raspberry Pi CM3 1.0"},
255-
{"a020d3", "Raspberry Pi 3B+ 1.3"},
256-
{"a02042", "Raspberry Pi 2B (with BCM2837) 1.2"},
257-
{"a21041", "Raspberry Pi 2B 1.1"},
258-
{"a22042", "Raspberry Pi 2B (with BCM2837) 1.2"},
259-
{"a22082", "Raspberry Pi 3B 1.2"},
260-
{"a220a0", "Raspberry Pi CM3 1.0"},
261-
{"a32082", "Raspberry Pi 3B 1.2"},
262-
{"a52082", "Raspberry Pi 3B 1.2"},
263-
{"a22083", "Raspberry Pi 3B 1.3"},
264-
{"a02100", "Raspberry Pi CM3+ 1.0"},
265-
{"a03111", "Raspberry Pi 4B 1.1"},
266-
{"b03111", "Raspberry Pi 4B 1.1"},
267-
{"b03112", "Raspberry Pi 4B 1.2"},
268-
{"b03114", "Raspberry Pi 4B 1.4"},
269-
{"b03115", "Raspberry Pi 4B 1.5"},
270-
{"c03111", "Raspberry Pi 4B 1.1"},
271-
{"c03112", "Raspberry Pi 4B 1.2"},
272-
{"c03114", "Raspberry Pi 4B 1.4"},
273-
{"c03115", "Raspberry Pi 4B 1.5"},
274-
{"d03114", "Raspberry Pi 4B 1.4"},
275-
{"d03115", "Raspberry Pi 4B 1.5"},
276-
{"c03130", "Raspberry Pi 400 1.0"},
277-
{"a03140", "Raspberry Pi CM4 1.0"},
278-
{"b03140", "Raspberry Pi CM4 1.0"},
279-
{"c03140", "Raspberry Pi CM4 1.0"},
280-
{"d03140", "Raspberry Pi CM4 1.0"},
281-
{"902120", "Raspberry Pi Zero 2 W 1.0"},
282-
{"c04170", "Raspberry Pi 5 8GB"},
283-
{"d04170", "Raspberry Pi 5 4GB"},
284-
{"c04171", "Raspberry Pi 5 8GB"},
285-
{"d04171", "Raspberry Pi 5 4GB"},
286-
{"902121", "Raspberry Pi Zero 2 W 1.0"}};
287-
288-
std::unordered_map<std::string, std::string>::const_iterator it = rpi_revisions.find(revision);
289-
if (it != rpi_revisions.end())
290-
{
291-
return it->second;
292-
}
293-
}
294-
295342
// Return CPU model name if available
296343
if (!model_name.empty())
297344
return model_name;

0 commit comments

Comments
 (0)