From 3f56c202f76e348573db8c7c424f39634016be0a Mon Sep 17 00:00:00 2001 From: Sebastian Hildebrandt Date: Sun, 8 Nov 2020 12:55:04 +0100 Subject: [PATCH] cpu(), system() better parsing Raspberry Pi revision codes --- CHANGELOG.md | 1 + docs/history.html | 5 + docs/index.html | 2 +- lib/cpu.js | 16 +++- lib/index.d.ts | 7 ++ lib/system.js | 226 ++++++++++++++++++++++++---------------------- lib/util.js | 208 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 357 insertions(+), 108 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3853de..4b59cc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ For major (breaking) changes - version 3 and 2 see end of page. | Version | Date | Comment | | -------------- | -------------- | -------- | +| 4.29.1 | 2020-11-08 | `cpu()`, `system()` better parsing Raspberry Pi revision codes | | 4.29.0 | 2020-11-08 | `fsSize()` correct fs type detection macOS (HFS, APFS, NFS) | | 4.28.1 | 2020-11-05 | code cleanup, removing debug console.log() | | 4.28.0 | 2020-11-04 | `graphics()` added deviceName (windows) | diff --git a/docs/history.html b/docs/history.html index a9db895..9d2c5fd 100644 --- a/docs/history.html +++ b/docs/history.html @@ -83,6 +83,11 @@ + + 4.29.1 + 2020-11-08 + system() better parsing Raspberry Pi revision codes + 4.29.0 2020-11-08 diff --git a/docs/index.html b/docs/index.html index 293c193..7782f43 100644 --- a/docs/index.html +++ b/docs/index.html @@ -168,7 +168,7 @@
systeminformation
-
Current Version: 4.29.0
+
Current Version: 4.29.1
diff --git a/lib/cpu.js b/lib/cpu.js index 497d7a9..2371b18 100644 --- a/lib/cpu.js +++ b/lib/cpu.js @@ -468,6 +468,7 @@ function getCpu() { result = cpuBrandManufacturer(result); result.vendor = util.getValue(lines, 'vendor id'); // if (!result.vendor) { result.vendor = util.getValue(lines, 'anbieterkennung'); } + result.family = util.getValue(lines, 'cpu family'); // if (!result.family) { result.family = util.getValue(lines, 'prozessorfamilie'); } result.model = util.getValue(lines, 'model:'); @@ -492,12 +493,25 @@ function getCpu() { result.processors = processorsInt; result.governor = util.getValue(lines, 'governor') || ''; + // Test Raspberry + if (result.vendor === 'ARM') { + const linesRpi = fs.readFileSync('/proc/cpuinfo').toString().split('\n'); + const rPIRevision = util.decodePiCpuinfo(linesRpi); + if (rPIRevision.model.toLowerCase().indexOf('raspberry') >= 0) { + result.family = result.manufacturer + result.manufacturer = rPIRevision.manufacturer; + result.brand = rPIRevision.processor; + result.revision = rPIRevision.revisionCode; + result.socket = 'SOC'; + } + } + // socket type let lines2 = []; exec('export LC_ALL=C; dmidecode –t 4 2>/dev/null | grep "Upgrade: Socket"; unset LC_ALL', function (error2, stdout2) { lines2 = stdout2.toString().split('\n'); if (lines2 && lines2.length) { - result.socket = util.getValue(lines2, 'Upgrade').replace('Socket', '').trim(); + result.socket = util.getValue(lines2, 'Upgrade').replace('Socket', '').trim() || result.socket; } resolve(result); }); diff --git a/lib/index.d.ts b/lib/index.d.ts index 5450881..e3b96be 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -15,6 +15,12 @@ export namespace Systeminformation { // 2. System (HW) + interface RaspberryRevisionData { + manufacturer: string; + processor: string; + type: string; + revision: string; + } interface SystemData { manufacturer: string; model: string; @@ -22,6 +28,7 @@ export namespace Systeminformation { serial: string; uuid: string; sku: string; + raspberry?: RaspberryRevisionData; } interface BiosData { diff --git a/lib/system.js b/lib/system.js index 821fcce..4688047 100644 --- a/lib/system.js +++ b/lib/system.js @@ -94,116 +94,130 @@ function system(callback) { result.model = util.getValue(lines, 'hardware', ':', true).toUpperCase(); result.version = util.getValue(lines, 'revision', ':', true).toLowerCase(); result.serial = util.getValue(lines, 'serial', ':', true); - + const model = util.getValue(lines, 'model:', ':', true); // reference values: https://elinux.org/RPi_HardwareHistory // https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md - if (result.model === 'BCM2835' || result.model === 'BCM2708' || result.model === 'BCM2709' || result.model === 'BCM2835' || result.model === 'BCM2837') { - - // Pi 4 - if (['d03114'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi 4 Model B'; - result.version = result.version + ' - Rev. 1.4'; - } - if (['b03112', 'c03112'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi 4 Model B'; - result.version = result.version + ' - Rev. 1.2'; - } - if (['a03111', 'b03111', 'c03111'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi 4 Model B'; - result.version = result.version + ' - Rev. 1.1'; - } - // Pi 3 - if (['a02082', 'a22082', 'a32082', 'a52082'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi 3 Model B'; - result.version = result.version + ' - Rev. 1.2'; - } - if (['a22083'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi 3 Model B'; - result.version = result.version + ' - Rev. 1.3'; - } - if (['a020d3'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi 3 Model B+'; - result.version = result.version + ' - Rev. 1.3'; - } - if (['9020e0'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi 3 Model A+'; - result.version = result.version + ' - Rev. 1.3'; - } - // Pi 2 Model B - if (['a01040'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi 2 Model B'; - result.version = result.version + ' - Rev. 1.0'; - } - if (['a01041', 'a21041'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi 2 Model B'; - result.version = result.version + ' - Rev. 1.1'; - } - if (['a22042', 'a02042'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi 2 Model B'; - result.version = result.version + ' - Rev. 1.2'; - } - - // Compute Model - if (['a02100'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi CM3+'; - result.version = result.version + ' - Rev 1.0'; - } - if (['a020a0', 'a220a0'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi CM3'; - result.version = result.version + ' - Rev 1.0'; - } - if (['900061'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi CM'; - result.version = result.version + ' - Rev 1.1'; - } - - // Pi Zero - if (['900092', '920092'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi Zero'; - result.version = result.version + ' - Rev 1.2'; - } - if (['900093', '920093'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi Zero'; - result.version = result.version + ' - Rev 1.3'; - } - if (['9000c1'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi Zero W'; - result.version = result.version + ' - Rev 1.1'; - } - - // A, B, A+ B+ - if (['0002', '0003'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi Model B'; - result.version = result.version + ' - Rev 1.0'; - } - if (['0004', '0005', '0006', '000d', '000e', '000f'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi Model B'; - result.version = result.version + ' - Rev 2.0'; - } - if (['0007', '0008', '0009'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi Model A'; - result.version = result.version + ' - Rev 2.0'; - } - if (['0010'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi Model B+'; - result.version = result.version + ' - Rev 1.0'; - } - if (['0012'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi Model A+'; - result.version = result.version + ' - Rev 1.0'; - } - if (['0013', '900032'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi Model B+'; - result.version = result.version + ' - Rev 1.2'; - } - if (['0015', '900021'].indexOf(result.version) >= 0) { - result.model = result.model + ' - Pi Model A+'; - result.version = result.version + ' - Rev 1.1'; - } - if (result.model.indexOf('Pi') !== -1 && result.version) { // Pi, Pi Zero - result.manufacturer = 'Raspberry Pi Foundation'; + if ((result.model === 'BCM2835' || result.model === 'BCM2708' || result.model === 'BCM2709' || result.model === 'BCM2835' || result.model === 'BCM2837') && model.toLowerCase().indexOf('raspberry') >= 0) { + const rPIRevision = util.decodePiCpuinfo(lines); + result.model = rPIRevision.model; + result.version = rPIRevision.revisionCode; + result.manufacturer = 'Raspberry Pi Foundation'; + result.raspberry = { + manufacturer: rPIRevision.manufacturer, + processor: rPIRevision.processor, + type: rPIRevision.type, + revision: rPIRevision.revision } } + + // if (result.model === 'BCM2835' || result.model === 'BCM2708' || result.model === 'BCM2709' || result.model === 'BCM2835' || result.model === 'BCM2837') { + + + // // Pi 4 + // if (['d03114'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi 4 Model B'; + // result.version = result.version + ' - Rev. 1.4'; + // } + // if (['b03112', 'c03112'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi 4 Model B'; + // result.version = result.version + ' - Rev. 1.2'; + // } + // if (['a03111', 'b03111', 'c03111'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi 4 Model B'; + // result.version = result.version + ' - Rev. 1.1'; + // } + // // Pi 3 + // if (['a02082', 'a22082', 'a32082', 'a52082'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi 3 Model B'; + // result.version = result.version + ' - Rev. 1.2'; + // } + // if (['a22083'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi 3 Model B'; + // result.version = result.version + ' - Rev. 1.3'; + // } + // if (['a020d3'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi 3 Model B+'; + // result.version = result.version + ' - Rev. 1.3'; + // } + // if (['9020e0'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi 3 Model A+'; + // result.version = result.version + ' - Rev. 1.3'; + // } + // // Pi 2 Model B + // if (['a01040'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi 2 Model B'; + // result.version = result.version + ' - Rev. 1.0'; + // } + // if (['a01041', 'a21041'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi 2 Model B'; + // result.version = result.version + ' - Rev. 1.1'; + // } + // if (['a22042', 'a02042'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi 2 Model B'; + // result.version = result.version + ' - Rev. 1.2'; + // } + + // // Compute Model + // if (['a02100'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi CM3+'; + // result.version = result.version + ' - Rev 1.0'; + // } + // if (['a020a0', 'a220a0'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi CM3'; + // result.version = result.version + ' - Rev 1.0'; + // } + // if (['900061'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi CM'; + // result.version = result.version + ' - Rev 1.1'; + // } + + // // Pi Zero + // if (['900092', '920092'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi Zero'; + // result.version = result.version + ' - Rev 1.2'; + // } + // if (['900093', '920093'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi Zero'; + // result.version = result.version + ' - Rev 1.3'; + // } + // if (['9000c1'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi Zero W'; + // result.version = result.version + ' - Rev 1.1'; + // } + + // // A, B, A+ B+ + // if (['0002', '0003'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi Model B'; + // result.version = result.version + ' - Rev 1.0'; + // } + // if (['0004', '0005', '0006', '000d', '000e', '000f'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi Model B'; + // result.version = result.version + ' - Rev 2.0'; + // } + // if (['0007', '0008', '0009'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi Model A'; + // result.version = result.version + ' - Rev 2.0'; + // } + // if (['0010'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi Model B+'; + // result.version = result.version + ' - Rev 1.0'; + // } + // if (['0012'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi Model A+'; + // result.version = result.version + ' - Rev 1.0'; + // } + // if (['0013', '900032'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi Model B+'; + // result.version = result.version + ' - Rev 1.2'; + // } + // if (['0015', '900021'].indexOf(result.version) >= 0) { + // result.model = result.model + ' - Pi Model A+'; + // result.version = result.version + ' - Rev 1.1'; + // } + // if (result.model.indexOf('Pi') !== -1 && result.version) { // Pi, Pi Zero + // result.manufacturer = 'Raspberry Pi Foundation'; + // } + // } } if (callback) { callback(result); } resolve(result); diff --git a/lib/util.js b/lib/util.js index 568625d..0286a57 100644 --- a/lib/util.js +++ b/lib/util.js @@ -513,6 +513,213 @@ function sanitizeShellString(str) { return result; } +function hex2bin(hex) { + return ("00000000" + (parseInt(hex, 16)).toString(2)).substr(-8); +} + +function decodePiCpuinfo(lines) { + + // https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md + + const oldRevisionCodes = { + '0002': { + type: 'B', + revision: '1.0', + memory: 256, + manufacturer: 'Egoman', + processor: 'BCM2835' + }, + '0003': { + type: 'B', + revision: '1.0', + memory: 256, + manufacturer: 'Egoman', + processor: 'BCM2835' + }, + '0004': { + type: 'B', + revision: '2.0', + memory: 256, + manufacturer: 'Sony UK', + processor: 'BCM2835' + }, + '0005': { + type: 'B', + revision: '2.0', + memory: 256, + manufacturer: 'Qisda', + processor: 'BCM2835' + }, + '0006': { + type: 'B', + revision: '2.0', + memory: 256, + manufacturer: 'Egoman', + processor: 'BCM2835' + }, + '0007': { + type: 'A', + revision: '2.0', + memory: 256, + manufacturer: 'Egoman', + processor: 'BCM2835' + }, + '0008': { + type: 'A', + revision: '2.0', + memory: 256, + manufacturer: 'Sony UK', + processor: 'BCM2835' + }, + '0009': { + type: 'A', + revision: '2.0', + memory: 256, + manufacturer: 'Qisda', + processor: 'BCM2835' + }, + '000d': { + type: 'B', + revision: '2.0', + memory: 512, + manufacturer: 'Egoman', + processor: 'BCM2835' + }, + '000e': { + type: 'B', + revision: '2.0', + memory: 512, + manufacturer: 'Sony UK', + processor: 'BCM2835' + }, + '000f': { + type: 'B', + revision: '2.0', + memory: 512, + manufacturer: 'Egoman', + processor: 'BCM2835' + }, + '0010': { + type: 'B+', + revision: '1.2', + memory: 512, + manufacturer: 'Sony UK', + processor: 'BCM2835' + }, + '0011': { + type: 'CM1', + revision: '1.0', + memory: 512, + manufacturer: 'Sony UK', + processor: 'BCM2835' + }, + '0012': { + type: 'A+', + revision: '1.1', + memory: 256, + manufacturer: 'Sony UK', + processor: 'BCM2835' + }, + '0013': { + type: 'B+', + revision: '1.2', + memory: 512, + manufacturer: 'Embest', + processor: 'BCM2835' + }, + '0014': { + type: 'CM1', + revision: '1.0', + memory: 512, + manufacturer: 'Embest', + processor: 'BCM2835' + }, + '0015': { + type: 'A+', + revision: '1.1', + memory: 256, + manufacturer: '512MB Embest', + processor: 'BCM2835' + } + } + + const processorList = [ + 'BMC2835', + 'BMC2836', + 'BMC2837', + 'BMC2711', + ]; + const manufacturerList = [ + 'Sony UK', + 'Egoman', + 'Embest', + 'Sony Japan', + 'Embest', + 'Stadium' + ]; + const typeList = { + '00': 'A', + '01': 'B', + '02': 'A+', + '03': 'B+', + '04': '2B', + '05': 'Alpha (early prototype)', + '06': 'CM1', + '08': '3B', + '09': 'Zero', + '0a': 'CM3', + '0c': 'Zero W', + '0d': '3B+', + '0e': '3A+', + '0f': 'Internal use only', + '10': 'CM3+', + '11': '4B', + '13': '400', + '14': 'CM4' + }; + + const revisionCode = getValue(lines, 'revision', ':', true); + const model = getValue(lines, 'model:', ':', true); + const serial = getValue(lines, 'serial', ':', true); + + let result = {}; + if (oldRevisionCodes.hasOwnProperty(revisionCode)) { + // old revision codes + result = { + model, + serial, + revisionCode, + memory: oldRevisionCodes[revisionCode].memory, + manufacturer: oldRevisionCodes[revisionCode].manufacturer, + processor: oldRevisionCodes[revisionCode].processor, + type: oldRevisionCodes[revisionCode].type, + revision: oldRevisionCodes[revisionCode].revision, + } + + } else { + // new revision code + const revision = ('00000000' + getValue(lines, 'revision', ':', true).toLowerCase()).substr(-8); + // const revisionStyleNew = hex2bin(revision.substr(2, 1)).substr(4, 1) === '1'; + const memSizeCode = parseInt(hex2bin(revision.substr(2, 1)).substr(5, 3), 2) || 0; + const manufacturer = manufacturerList[parseInt(revision.substr(3, 1), 10)]; + const processor = processorList[parseInt(revision.substr(4, 1), 10)]; + const typeCode = revision.substr(5, 2); + + + result = { + model, + serial, + revisionCode, + memory: 256 * Math.pow(2, memSizeCode), + manufacturer, + processor, + type: typeList.hasOwnProperty(typeCode) ? typeList[typeCode] : '', + revision: '1.' + revision.substr(7, 1), + } + } + return result; +} + function noop() { } exports.toInt = toInt; @@ -540,3 +747,4 @@ exports.noop = noop; exports.isRaspberry = isRaspberry; exports.isRaspbian = isRaspbian; exports.sanitizeShellString = sanitizeShellString; +exports.decodePiCpuinfo = decodePiCpuinfo;