2011-02-01 8 views
13

मैं एक लिनक्स कर्नेल मॉड्यूल के अंदर बैटरी स्तर प्राप्त करने की कोशिश कर रहा हूं (मॉड्यूल modprobe के माध्यम से डाला गया है)। मैं बैटरी जानकारी प्राप्त करने के लिए आदर्श रूप से एक कर्नेल एपीआई कॉल का उपयोग करना चाहता हूं। मैंने समाधान के लिए वेब पर खोज की है, और मैंने लिनक्स कर्नेल स्रोत और विचारों के लिए माइकल मेसेक्स द्वारा "एसीपीआई" कार्यक्रम का स्रोत भी खोजा है।मैं लिनक्स कर्नेल मॉड्यूल के अंदर बैटरी स्तर कैसे प्राप्त कर सकता हूं?

इन तकनीकों में मुझे लगता है कि मैं उपयोग कर सकते हैं में से कुछ हैं:

  1. पढ़ें और कोई शामिल पार्स साथ /sys/class/power_supply/BAT0/charge_now और charge_full से पार्स /proc/acpi/battery/BAT0/state और /proc/acpi/battery/BAT0/info
  2. पढ़ें।
  3. यदि मैं इंटरफ़ेस का पर्दाफाश करने का तरीका समझ सकता हूं तो मैं लिनक्स कर्नेल स्रोत ड्राइवर/एसीपीआई/बैटरी.c से कॉल का उपयोग करने का प्रयास कर सकता हूं। मुझे शायद acpi_battery_get_status और acpi_battery_get_info
  4. मैंने यह भी देखा कि ड्राइवरों/एसीपीआई/एसबीएस.c के अंदर एक विधि acpi_battery_read है और इसके ठीक ऊपर "ड्राइवर इंटरफ़ेस" कहने वाली एक टिप्पणी है। अगर कोई जानता है कि इसका उपयोग कैसे किया जाए तो यह एक और तरीका हो सकता है।

मुझे लगता है कि कर्नेल मॉड्यूल के अंदर फ़ाइलों को पढ़ने के लिए शायद यह एक बुरा विचार है, लेकिन मुझे बिल्कुल यकीन नहीं है कि ये फ़ाइलें कर्नेल फ़ंक्शन कॉल को कैसे मैप करती हैं, इसलिए यह ठीक हो सकता है।

तो, क्या आप मुझे कुछ सुझाव/सिफारिशें दे सकते हैं?

संपादित करें: मैंने नीचे दिए गए उत्तर में अपना समाधान शामिल किया है।

+0

आप ऐसा क्यों करना चाहते हैं, बिल्कुल? –

+0

@Andy कुछ बैटरी स्तर निर्भर कार्यक्षमता है। – razvanlupusoru

उत्तर

10

मैं एक समाधान है कि मेरे लिए काम करता मिल गया है। सबसे पहले सुनिश्चित करें कि #लिनक्स/power_supply.h>

मान लें कि आप बैटरी का नाम जानते हैं, यह कोड वर्तमान बैटरी क्षमता को प्राप्त करने का एक उदाहरण देता है।

char name[]= "BAT0"; 
int result = 0; 
struct power_supply *psy = power_supply_get_by_name(name); 
union power_supply_propval chargenow, chargefull; 
result = psy->get_property(psy,POWER_SUPPLY_PROP_CHARGE_NOW,&chargenow); 
if(!result) { 
    printk(KERN_INFO "The charge level is %d\n",chargenow.intval); 
} 
result = psy->get_property(psy,POWER_SUPPLY_PROP_CHARGE_FULL,&chargefull); 
if(!result) { 
    printk(KERN_INFO "The charge level is %d\n",chargefull.intval); 
} 
0

बैटरी.c, sbs.c पर देखकर, मुझे लगता है कि आप सीधे अपने एलकेएम में इंटरफेस एपीआई (acpi_battery_read, acpi_battery_get_state) को कॉल कर सकते हैं।
क्या आपने अभी तक कोशिश की है?

+0

मैंने उन्हें अपने मॉड्यूल में एक बाहरी के साथ घोषित करके उन स्थिर तरीकों का उपयोग करने की कोशिश की। हालांकि, मॉड्यूल लोड समय पर वे अपरिभाषित बने रहे। मुझे नहीं लगता कि स्थैतिक विधियों का उपयोग उस फाइल के बाहर किया जा सकता है जहां उन्हें परिभाषित किया गया है। हालांकि मैं यह जोड़ना चाहता हूं कि कर्नेल प्रतीक तालिका में स्थिर विधियां मौजूद हैं (मैंने/proc/kallsyms के माध्यम से देखा) – razvanlupusoru

0

मुझे एक ही दुविधा है! : - \ यदि यह एक हार्डवेयर विशिष्ट चीज है जो आप कर रहे हैं, तो आप देख सकते हैं कि आपके विशेष लैपटॉप पर आप SMBus लिंक पर स्मार्ट बैटरी का पता लगा सकते हैं या नहीं। यदि आप कर सकते हैं, तो आप अपने एलकेएम के भीतर से केवल i2c/SMBus कॉल कर सकते हैं। अधिकांश नए सिस्टम (कुछ फुजीत्सु लैपटॉप को छोड़कर) इसके बजाय एक एम्बेडेड नियंत्रक से बात करते हैं, जो बैटरी को कॉन्फ़िगर करने के लिए समाप्त होता है (एसएमबीस के माध्यम से मुझे लगता है) .... "एलएम-सेंसर" स्थापित करने का प्रयास करें और देखें कि यह आपकी स्मार्ट बैटरी का पता लगाता है या नहीं। यदि ऐसा है तो आप सीधे बैटरी से बात करने में सक्षम होना चाहिए (आमतौर पर i2c पता 0xb पर)।

यदि यह एक हार्डवेयर विशिष्ट बात आप कर रहे हैं नहीं है, तो उपेक्षा मैं क्या कहा :)

संबंधित मुद्दे