I was able to convert a C program "osx-cpu-temp" from Sébastien Lavoie on GitHub.
https://github.com/lavoiesl/osx-cpu-temp
Code: Select all
; Converted from C source code on
; https://github.com/lavoiesl/osx-cpu-temp/blob/master/smc.c
; https://github.com/acidanthera/VirtualSMC/blob/master/Docs/SMCKeys.txt - list of SMC Keys
; https://alwinesch.github.io/test-xbmc/Leia/kodi-base/d6/d33/struct_s_m_c_key_data__t.html - struct definitions
; Copyright (C) 2006 devnull
; Portions © RMF Solutions - Robert Fernandez, 2023. also under the GPL
EnableExplicit
#KERNEL_INDEX_SMC = 2
#SMC_KEY_CPU_TEMP = "TC0P" ;"TC4C"
#SMC_CMD_READ_BYTES = 5
#SMC_CMD_READ_KEYINFO = 9
#kIOReturnSuccess = 0
Structure SMCVal_t Align #PB_Structure_AlignC
key.l
dataSize.l
dataType.l
bytes.b[32]
EndStructure
Structure SMCKeyData_vers_t Align #PB_Structure_AlignC
major.b
minor.b
build.b
reserved.b[1]
release.w
EndStructure
Structure SMCKeyData_pLimitData_t Align #PB_Structure_AlignC
version.w
length.w
cpuPLimit.l
gpuPLimit.l
memPLimit.l
EndStructure
Structure SMCKeyData_keyInfo_t Align #PB_Structure_AlignC
dataSize.l
dataType.l
dataAttributes.b
EndStructure
Structure SMCKeyData_t Align #PB_Structure_AlignC
key.l
vers.SMCKeyData_vers_t
pLimitData.SMCKeyData_pLimitData_t
keyInfo.SMCKeyData_keyInfo_t
result.b
status.b
data8.b
data32.l
bytes.b[32]
EndStructure
ImportC "-framework IOKit"
IOServiceGetMatchingServices(mainPort.i, MatchingDictionary.i, *iterator)
IOServiceMatching(*name)
IOIteratorNext(iterator)
IOObjectRelease(object)
IOServiceOpen(service, owningTask, type, *connect)
IOServiceClose(connect)
IOConnectCallStructMethod(connection, selector, *inputStruct, inputStructCnt, *outputStruct, *outputStructCnt)
EndImport
ImportC ""
mach_task_self()
EndImport
Define matchingDictionary.i
Define iterator.i, k.l, device.i, connection.i, temperature.f, kern_return_t.i
;Define inputStructure.SMCKeyData_t, outputStructure.SMCKeyData_t ;, val.SMCVal_t
Define structureInputSize.i, structureOutputSize.i
Procedure.l _strtoul(str.s)
Protected total.l = 0, i.l, size.l
size = Len(str)
For i = 0 To size - 1
total = (total << 8) + PeekB(@str + (i * 2))
Next i
ProcedureReturn total
EndProcedure
Procedure.s _ultostr(smcval.l)
Protected strng.s = "????"
PokeB(@strng, PeekB(@smcval))
PokeB(@strng + 2,PeekB(@smcval + 1))
PokeB(@strng + 4,PeekB(@smcval + 2))
PokeB(@strng + 6,PeekB(@smcval + 3))
Debug "_ultostr string = " + strng
ProcedureReturn strng
EndProcedure
Procedure.f get_SMCKey(key.s)
Protected inputStructure.SMCKeyData_t, outputStructure.SMCKeyData_t, kern_return_t.i
Shared connection.i, structureInputSize.i, structureOutputSize.i
inputStructure\key = _strtoul(key)
inputStructure\data8 = #SMC_CMD_READ_KEYINFO
Debug Str(inputStructure\key)
kern_return_t = IOConnectCallStructMethod(connection, #KERNEL_INDEX_SMC, @inputStructure, structureInputSize, @outputStructure, @structureOutputSize)
If kern_return_t <> #kIOReturnSuccess
Debug "Error: IOConnectCallStructMethod() = " + Str(kern_return_t)
PrintN("Error: IOConnectCallStructMethod() = " + Str(kern_return_t))
End
EndIf
inputStructure\keyInfo\dataSize = outputStructure\keyInfo\dataSize ;val\dataSize
inputStructure\data8 = #SMC_CMD_READ_BYTES
kern_return_t = IOConnectCallStructMethod(connection, #KERNEL_INDEX_SMC, @inputStructure, structureInputSize, @outputStructure, @structureOutputSize)
If kern_return_t <> #kIOReturnSuccess
Debug "Error: IOConnectCallStructMethod() = " + Str(kern_return_t)
PrintN("Error: IOConnectCallStructMethod() = " + Str(kern_return_t))
End
EndIf
ProcedureReturn (outputStructure\bytes[0] * 256.0 + outputStructure\bytes[1]) / 256.0
EndProcedure
structureInputSize = SizeOf(SMCKeyData_t)
structureOutputSize = SizeOf(SMCKeyData_t)
If OpenConsole()
matchingDictionary = IOServiceMatching(UTF8("AppleSMC"))
Debug "SMC = " + Str(matchingDictionary)
kern_return_t = IOServiceGetMatchingServices(#Null, matchingDictionary, @iterator)
If kern_return_t <> #kIOReturnSuccess
Debug "Error: IOServiceGetMatchingServices() = " + Str(kern_return_t)
PrintN("Error: IOServiceGetMatchingServices() = " + Str(kern_return_t))
End
EndIf
device = IOIteratorNext(iterator)
IOObjectRelease(iterator)
If device = 0
Debug "Error: no SMC found"
PrintN("Error: no SMC found")
End
EndIf
kern_return_t = IOServiceOpen(device, mach_task_self(), 0, @connection)
If kern_return_t <> #kIOReturnSuccess
Debug "Error: IOServiceOpen() = " + Str(kern_return_t)
PrintN("Error: IOServiceOpen() = " + Str(kern_return_t))
End
EndIf
Debug "variable structureInputSize = " + Str(structureInputSize)
Debug "variable structureOutputSize = " + Str(structureOutputSize)
Debug "variable SMCKeyData_vers_t = " + Str(SizeOf(SMCKeyData_vers_t))
Debug "variable SMCKeyData_pLimitData_t = " + Str(SizeOf(SMCKeyData_pLimitData_t))
Debug "variable SMCKeyData_keyInfo_t = " + Str(SizeOf(SMCKeyData_keyInfo_t))
temperature = get_SMCKey(#SMC_KEY_CPU_TEMP)
Debug "CPU temp = " + StrF(temperature,1) + " ºC"
PrintN("CPU temp = " + StrF(temperature,1) + " ºC")
; some Macs the CPU count starts at 0, some at 1. So we check if result is 0.0
For k = 0 To CountCPUs(#PB_System_ProcessCPUs)
temperature = get_SMCKey("TC" + Str(k) + "C")
If temperature > 0.0
PrintN("CPU core " + Str(k) + " temp = " + StrF(temperature,1) + " ºC")
EndIf
Next
kern_return_t = IOServiceClose(connection)
If kern_return_t <> #kIOReturnSuccess
Debug "Error: IOServiceClose() = " + Str(kern_return_t)
PrintN("Error: IOServiceClose() = " + Str(kern_return_t))
End
EndIf
CloseConsole()
EndIf
End