From 5604e769b9bf5cc0a5ee6f0c6f99ecca570f1b37 Mon Sep 17 00:00:00 2001 From: Yuji Date: Mon, 25 Jan 2021 13:49:06 +0900 Subject: [PATCH] Temperature on Apple M1 macs. Should fix https://github.com/yujitach/MenuMeters/issues/221 . --- MenuExtras/MenuMeterCPU/MenuMeterCPUStats.h | 1 - MenuExtras/MenuMeterCPU/MenuMeterCPUStats.m | 13 +++ MenuMeters.xcodeproj/project.pbxproj | 14 +++- .../applesilicon_hardware_reader.h | 13 +++ .../applesilicon_hardware_reader.m | 83 +++++++++++++++++++ {smc_reader => hardware_reader}/smc_reader.c | 0 {smc_reader => hardware_reader}/smc_reader.h | 0 7 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 hardware_reader/applesilicon_hardware_reader.h create mode 100644 hardware_reader/applesilicon_hardware_reader.m rename {smc_reader => hardware_reader}/smc_reader.c (100%) rename {smc_reader => hardware_reader}/smc_reader.h (100%) diff --git a/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.h b/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.h index 18d8b681..a68843cd 100644 --- a/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.h +++ b/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.h @@ -29,7 +29,6 @@ #import #import #import "MenuMeterCPU.h" -#import "../../smc_reader/smc_reader.h" #import "LocalizedStrings.h" @interface MenuMeterCPULoad : NSObject diff --git a/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.m b/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.m index 72e80877..d6eb9cc2 100644 --- a/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.m +++ b/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.m @@ -23,6 +23,9 @@ #import "MenuMeterCPUStats.h" #import +#import "../../hardware_reader/smc_reader.h" +#import "../../hardware_reader/applesilicon_hardware_reader.h" +#include @implementation MenuMeterCPULoad @end @@ -325,6 +328,7 @@ - (NSArray *)currentLoadBySorting: (BOOL)sorted { - (float_t)cpuProximityTemperature { float_t celsius = -273.15F; +#if TARGET_CPU_X86_64 if (kIOReturnSuccess == SMCOpen()) { SMCKeyValue value; //use harcoded value for a while @@ -334,6 +338,15 @@ - (float_t)cpuProximityTemperature { } SMCClose(); } +#elif TARGET_CPU_ARM64 + NSDictionary*dict=AppleSiliconTemperatureDictionary(); + //use harcoded value for a while + //TODO: implement tab to select which sensor to display + NSNumber*temp=dict[@"SOC MTR Temp Sensor0"]; + if(temp){ + celsius=[temp floatValue]; + } +#endif return celsius; } // cpuProximityTemperature diff --git a/MenuMeters.xcodeproj/project.pbxproj b/MenuMeters.xcodeproj/project.pbxproj index b5ba9a22..43114e35 100644 --- a/MenuMeters.xcodeproj/project.pbxproj +++ b/MenuMeters.xcodeproj/project.pbxproj @@ -11,6 +11,8 @@ 330247672366CEA800F88D61 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = 330247662366CEA800F88D61 /* dsa_pub.pem */; }; 3302476A2366CF7F00F88D61 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 330247642366CB7A00F88D61 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 330611032367EA4C0016E763 /* MenuMetersMainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 330611022367EA4C0016E763 /* MenuMetersMainMenu.xib */; }; + 3325978C25BE7DB10070CE37 /* applesilicon_hardware_reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 3325978B25BE7DB10070CE37 /* applesilicon_hardware_reader.m */; }; + 3325979325BE7DD00070CE37 /* applesilicon_hardware_reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 3325978B25BE7DB10070CE37 /* applesilicon_hardware_reader.m */; }; 3330C5B4257DFAED00BD5164 /* LocalizedStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = 3330C5B2257DFAED00BD5164 /* LocalizedStrings.h */; }; 3330C5B5257DFAED00BD5164 /* LocalizedStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = 3330C5B2257DFAED00BD5164 /* LocalizedStrings.h */; }; 3330C5B6257DFAED00BD5164 /* LocalizedStrings.m in Sources */ = {isa = PBXBuildFile; fileRef = 3330C5B3257DFAED00BD5164 /* LocalizedStrings.m */; }; @@ -151,6 +153,8 @@ 330247662366CEA800F88D61 /* dsa_pub.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = dsa_pub.pem; sourceTree = ""; }; 330611022367EA4C0016E763 /* MenuMetersMainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MenuMetersMainMenu.xib; sourceTree = ""; }; 330D68B72105AB950041B689 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/DiskImageSet.strings"; sourceTree = ""; }; + 3325978B25BE7DB10070CE37 /* applesilicon_hardware_reader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = applesilicon_hardware_reader.m; sourceTree = ""; }; + 3325978F25BE7DCA0070CE37 /* applesilicon_hardware_reader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = applesilicon_hardware_reader.h; sourceTree = ""; }; 3330C5B2257DFAED00BD5164 /* LocalizedStrings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LocalizedStrings.h; sourceTree = ""; }; 3330C5B3257DFAED00BD5164 /* LocalizedStrings.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LocalizedStrings.m; sourceTree = ""; }; 3345DD2D1B6BEFDE003843FC /* MenuMetersMenuExtraBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MenuMetersMenuExtraBase.h; sourceTree = ""; }; @@ -343,7 +347,7 @@ children = ( 33F092172367387B00953CAB /* MenuMeters.entitlements */, 9023745A1E91612100B096A8 /* InfoPlistPreprocessor.h */, - F75EBE2D235B6F3600876CF7 /* smc_reader */, + F75EBE2D235B6F3600876CF7 /* hardware_reader */, 336B59401E03BA68006DA445 /* MenuMeters.pch */, D4510D7304F2F06100A87BC9 /* Docs */, D40DB4B303D25F9E00A87BC9 /* Common */, @@ -573,13 +577,15 @@ path = Common/Resources; sourceTree = ""; }; - F75EBE2D235B6F3600876CF7 /* smc_reader */ = { + F75EBE2D235B6F3600876CF7 /* hardware_reader */ = { isa = PBXGroup; children = ( F75EBE2E235B6F3600876CF7 /* smc_reader.h */, F75EBE2F235B6F3600876CF7 /* smc_reader.c */, + 3325978B25BE7DB10070CE37 /* applesilicon_hardware_reader.m */, + 3325978F25BE7DCA0070CE37 /* applesilicon_hardware_reader.h */, ); - path = smc_reader; + path = hardware_reader; sourceTree = ""; }; /* End PBXGroup section */ @@ -812,6 +818,7 @@ 3330C5B6257DFAED00BD5164 /* LocalizedStrings.m in Sources */, 33883CF723655C9900B8AC14 /* MenuMeterCPUStats.m in Sources */, 33883CF823655C9900B8AC14 /* MenuMetersMenuExtraBase.m in Sources */, + 3325978C25BE7DB10070CE37 /* applesilicon_hardware_reader.m in Sources */, 33883CF923655C9900B8AC14 /* MenuMeterUptime.m in Sources */, 33883CFA23655C9900B8AC14 /* smc_reader.c in Sources */, 33883CFB23655C9900B8AC14 /* MenuMeterCPUTopProcesses.m in Sources */, @@ -842,6 +849,7 @@ 3330C5B7257DFAED00BD5164 /* LocalizedStrings.m in Sources */, 6349C11124BB733300C6FC99 /* MenuMeterCPUStats.m in Sources */, 6349C11224BB733300C6FC99 /* MenuMetersMenuExtraBase.m in Sources */, + 3325979325BE7DD00070CE37 /* applesilicon_hardware_reader.m in Sources */, 6349C11324BB733300C6FC99 /* MenuMeterUptime.m in Sources */, 6349C11424BB733300C6FC99 /* smc_reader.c in Sources */, 6349C11524BB733300C6FC99 /* MenuMeterCPUTopProcesses.m in Sources */, diff --git a/hardware_reader/applesilicon_hardware_reader.h b/hardware_reader/applesilicon_hardware_reader.h new file mode 100644 index 00000000..e5a5e94e --- /dev/null +++ b/hardware_reader/applesilicon_hardware_reader.h @@ -0,0 +1,13 @@ +// +// applesilicon_hardware_reader.h +// MenuMeters +// +// Created by Yuji on 1/25/21. +// + +#ifndef applesilicon_hardware_reader_h +#define applesilicon_hardware_reader_h + +extern NSDictionary*AppleSiliconTemperatureDictionary(void); + +#endif /* applesilicon_hardware_reader_h */ diff --git a/hardware_reader/applesilicon_hardware_reader.m b/hardware_reader/applesilicon_hardware_reader.m new file mode 100644 index 00000000..1b9ff40e --- /dev/null +++ b/hardware_reader/applesilicon_hardware_reader.m @@ -0,0 +1,83 @@ +// +// applesilicon_hardware_reader.m +// MenuMeters +// +// Created by Yuji on 1/25/21. +// + +#import +#import "applesilicon_hardware_reader.h" + +// This code is based on https://github.com/fermion-star/apple_sensors/blob/master/temp_sensor.m +// which was in turn based on https://github.com/freedomtan/sensors/blob/master/sensors/sensors.m +// whose detail can be found in https://www2.slideshare.net/kstan2/exploring-thermal-related-stuff-in-idevices-using-opensource-tool + + +#include + +// Declarations from other IOKit source code + +typedef struct __IOHIDEvent *IOHIDEventRef; +typedef struct __IOHIDServiceClient *IOHIDServiceClientRef; +#ifdef __LP64__ +typedef double IOHIDFloat; +#else +typedef float IOHIDFloat; +#endif + +IOHIDEventSystemClientRef IOHIDEventSystemClientCreate(CFAllocatorRef allocator); +int IOHIDEventSystemClientSetMatching(IOHIDEventSystemClientRef client, CFDictionaryRef match); +int IOHIDEventSystemClientSetMatchingMultiple(IOHIDEventSystemClientRef client, CFArrayRef match); +IOHIDEventRef IOHIDServiceClientCopyEvent(IOHIDServiceClientRef, int64_t , int32_t, int64_t); +CFStringRef IOHIDServiceClientCopyProperty(IOHIDServiceClientRef service, CFStringRef property); +IOHIDFloat IOHIDEventGetFloatValue(IOHIDEventRef event, int32_t field); + +//extern uint64_t my_mhz(void); +//extern void mybat(void); + // Primary Usage Page: + // kHIDPage_AppleVendor = 0xff00, + // kHIDPage_AppleVendorTemperatureSensor = 0xff05, + // kHIDPage_AppleVendorPowerSensor = 0xff08, + // + // Primary Usage: + // kHIDUsage_AppleVendor_TemperatureSensor = 0x0005, + // kHIDUsage_AppleVendorPowerSensor_Current = 0x0002, + // kHIDUsage_AppleVendorPowerSensor_Voltage = 0x0003, + // See IOHIDFamily/AppleHIDUsageTables.h for more information + // https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-701.60.2/IOHIDFamily/AppleHIDUsageTables.h.auto.html + + +#define IOHIDEventFieldBase(type) (type << 16) +#define kIOHIDEventTypeTemperature 15 +#define kIOHIDEventTypePower 25 + +NSDictionary*AppleSiliconTemperatureDictionary(void) +{ + NSDictionary*thermalSensors=@{@"PrimaryUsagePage":@(0xff00),@"PrimaryUsage":@(5)}; + + + IOHIDEventSystemClientRef system = IOHIDEventSystemClientCreate(kCFAllocatorDefault); // in CFBase.h = NULL + // ... this is the same as using kCFAllocatorDefault or the return value from CFAllocatorGetDefault() + IOHIDEventSystemClientSetMatching(system, (__bridge CFDictionaryRef)thermalSensors); + CFArrayRef matchingsrvs = IOHIDEventSystemClientCopyServices(system); // matchingsrvs = matching services + + + NSMutableDictionary*dict=[NSMutableDictionary dictionary]; + long count = CFArrayGetCount(matchingsrvs); + for (int i = 0; i < count; i++) { + IOHIDServiceClientRef sc = (IOHIDServiceClientRef)CFArrayGetValueAtIndex(matchingsrvs, i); + NSString* name = CFBridgingRelease(IOHIDServiceClientCopyProperty(sc, CFSTR("Product"))); // here we use ...CopyProperty + IOHIDEventRef event = IOHIDServiceClientCopyEvent(sc, kIOHIDEventTypeTemperature, 0, 0); // here we use ...CopyEvent + if (name && event) { + double temp = IOHIDEventGetFloatValue(event, IOHIDEventFieldBase(kIOHIDEventTypeTemperature)); + dict[name]=@(temp); + } + CFRelease(event); + } + + CFRelease(matchingsrvs); + CFRelease(system); + + return dict; + +} diff --git a/smc_reader/smc_reader.c b/hardware_reader/smc_reader.c similarity index 100% rename from smc_reader/smc_reader.c rename to hardware_reader/smc_reader.c diff --git a/smc_reader/smc_reader.h b/hardware_reader/smc_reader.h similarity index 100% rename from smc_reader/smc_reader.h rename to hardware_reader/smc_reader.h