linux 电源管理驱动编写
执行流程
驱动结构
1) 内核提供的接口
struct power_supply 在文件 include\linux\power_supply.h 中
2) 提供给用户的接口
sys/class/power_supply
通过 drivers\power\power_supply_core.c 中的
int power_supply_register(struct device *parent,struct power_supply *psy)
来创建.
power_supply_register() 在 K:\linux学习资料\bible\驱动程序开发\电源电池管理\电源电池管理.pdf中介绍
当电源变化时,调用:drivers\power\power_supply_core.c 中的
power_supply_changed()更新sysfs文件系统中的信息.
把握以上两点!
1. 填充 struct power_supply
路径: include/linux/power_supply.h
1.) 结构体含义
struct power_supply { const char *name; // 名字,例如: "usb", "battary", "ac" enum power_supply_type type; // 电源类型,在power_supply.h定义,分为usb,battery,ups,mains四种 enum power_supply_property *properties; // 电源属性,比较多,常用的在后面介绍.枚举类型数组 size_t num_properties; // 属性数量,假设为3,则回调get_property()3次 char **supplied_to; size_t num_supplicants; int (*get_property)(struct power_supply *psy, // 回调函数,执行power_supply_changed()后被 enum power_supply_property psp, // 调用,调用次数由num_properties决定 union power_supply_propval *val); int (*set_property)(struct power_supply *psy, enum power_supply_property psp, const union power_supply_propval *val); int (*property_is_writeable)(struct power_supply *psy, enum power_supply_property psp); void (*external_power_changed)(struct power_supply *psy); void (*set_charged)(struct power_supply *psy); /* For APM emulation, think legacy userspace. */ int use_for_apm; /* private */ struct device *dev; struct work_struct changed_work; // 工作队列,相当于一个线程,由它发起power_supply_changed() spinlock_t changed_lock; bool changed; struct wake_lock work_wake_lock; #ifdef CONFIG_LEDS_TRIGGERS struct led_trigger *charging_full_trig; char *charging_full_trig_name; struct led_trigger *charging_trig; char *charging_trig_name; struct led_trigger *full_trig; char *full_trig_name; struct led_trigger *online_trig; char *online_trig_name; #endif }; |
2) 常用的power_supply_propety
android下用到的:
# cat /sys/class/power_supply/ac/type Mains # cat /sys/class/power_supply/ac/online 1 # cd /sys/class/power_supply/battery/ # cat type status health present technology capacity Battery Charging Good 1 Li-ion 50 |
这些宏已经定义过:
enum { // 对应 POWER_SUPPLY_PROP_STATUS POWER_SUPPLY_STATUS_UNKNOWN = 0, POWER_SUPPLY_STATUS_CHARGING, POWER_SUPPLY_STATUS_DISCHARGING, POWER_SUPPLY_STATUS_NOT_CHARGING, POWER_SUPPLY_STATUS_FULL, }; enum { // 对应 POWER_SUPPLY_PROP_CHARGE_TYPE POWER_SUPPLY_CHARGE_TYPE_UNKNOWN = 0, POWER_SUPPLY_CHARGE_TYPE_NONE, POWER_SUPPLY_CHARGE_TYPE_TRICKLE, POWER_SUPPLY_CHARGE_TYPE_FAST, }; enum { // 对应 POWER_SUPPLY_PROP_HEALTH POWER_SUPPLY_HEALTH_UNKNOWN = 0, POWER_SUPPLY_HEALTH_GOOD, POWER_SUPPLY_HEALTH_OVERHEAT, POWER_SUPPLY_HEALTH_DEAD, POWER_SUPPLY_HEALTH_OVERVOLTAGE, POWER_SUPPLY_HEALTH_UNSPEC_FAILURE, POWER_SUPPLY_HEALTH_COLD, }; enum { // 对应 POWER_SUPPLY_PROP_TECHNOLOGY POWER_SUPPLY_TECHNOLOGY_UNKNOWN = 0, POWER_SUPPLY_TECHNOLOGY_NiMH, POWER_SUPPLY_TECHNOLOGY_LION, POWER_SUPPLY_TECHNOLOGY_LIPO, POWER_SUPPLY_TECHNOLOGY_LiFe, POWER_SUPPLY_TECHNOLOGY_NiCd, POWER_SUPPLY_TECHNOLOGY_LiMn, }; enum { // 对应 POWER_SUPPLY_PROP_CAPACITY_LEVEL POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN = 0, POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL, POWER_SUPPLY_CAPACITY_LEVEL_LOW, POWER_SUPPLY_CAPACITY_LEVEL_NORMAL, POWER_SUPPLY_CAPACITY_LEVEL_HIGH, POWER_SUPPLY_CAPACITY_LEVEL_FULL, }; |
一个struct power_supply的例子:
struct max17040_chip { struct power_supply battery; // 三种供电方式 struct power_supply ac; struct power_supply usb; struct timespec next_update_time; struct delayed_work work; // 两个队列 struct delayed_work battary_vol_state_wq; /* State Of Connect */ int online; /* battery voltage */ int vcell; /* battery capacity */ int soc; /* State Of Charge */ int status; /* usb online */ int usb_online; }; struct max17040_chip *chip; |
初始化:
chip->battery.name = "battery"; chip->battery.type = POWER_SUPPLY_TYPE_BATTERY; chip->battery.get_property = max17040_get_property; // 回调函数,执行power_supply_changed()后被调用,调用次数由battery.num_properties决定, 函数内容在下面. chip->battery.properties = max17040_battery_props; // 内容在下面 chip->battery.num_properties = ARRAY_SIZE(max17040_battery_props); chip->battery.external_power_changed = NULL; chip->ac.name = "ac"; chip->ac.type = POWER_SUPPLY_TYPE_MAINS; chip->ac.get_property = adapter_get_property; chip->ac.properties = adapter_get_props; chip->ac.num_properties = ARRAY_SIZE(adapter_get_props); chip->ac.external_power_changed = NULL; chip->usb.name = "usb"; chip->usb.type = POWER_SUPPLY_TYPE_USB; chip->usb.get_property = usb_get_property; chip->usb.properties = usb_get_props; chip->usb.num_properties = ARRAY_SIZE(usb_get_props); chip->usb.external_power_changed = NULL; // 两个队列 INIT_DELAYED_WORK_DEFERRABLE(&chip->work, work_max17040); INIT_DELAYED_WORK_DEFERRABLE(&chip->battary_vol_state_wq, work_battary_vol_sample); schedule_delayed_work(&chip->work, MAX17040_DELAY); schedule_delayed_work(&chip->battary_vol_state_wq, POLLING_BATTARY_VOL_MSEC); |
max17040_battery_props[] 枚举类型数组内容
static enum power_supply_property max17040_battery_props[] = { // 一共有7项, // 意味着max17040_get_property()将被回调7次 POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_STATUS, /*POWER_SUPPLY_PROP_ONLINE,*/ POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_TEMP, }; |
max17040_get_property() 函数:
static int max17040_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) { dev_info(dev,"%s \n", __func__); switch (psp) { // 一共有7项, 将被回调7次. 执行power_supply_changed()后被回调. case POWER_SUPPLY_PROP_STATUS: val->intval = chip->status; break; case POWER_SUPPLY_PROP_ONLINE: val->intval = 1; break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: case POWER_SUPPLY_PROP_PRESENT: val->intval = 3800;//chip->vcell; if(psp == POWER_SUPPLY_PROP_PRESENT) val->intval = 1; /* You must never run Odrioid1 without Battery. */ break; case POWER_SUPPLY_PROP_CAPACITY: val->intval = 80;//chip->soc; break; case POWER_SUPPLY_PROP_TECHNOLOGY: val->intval = POWER_SUPPLY_TECHNOLOGY_LION; break; case POWER_SUPPLY_PROP_HEALTH: // if(chip->vcell < 2850) // val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; // else val->intval = POWER_SUPPLY_HEALTH_GOOD; break; case POWER_SUPPLY_PROP_TEMP: break; default: return -EINVAL; } return 0; } |
work_queue队列
static void work_max17040(struct work_struct *work) { int old_usb_online, old_online, old_vcell, old_soc; int vol, level; old_online = chip->online; old_usb_online = chip->usb_online; old_vcell = chip->vcell; old_soc = chip->soc; max17040_update_values(); vol = battary_vol_average(); printk("+++ %s: vol = %d \n", __func__, vol); level = battary_level(vol); dev_info(dev,"%s, level = %d \n", __func__, level); // s3c_get_bat_level(); /* if((old_vcell != chip->vcell) || (old_soc != chip->soc)) power_supply_changed(&chip->battery); if(old_usb_online != chip->usb_online) power_supply_changed(&chip->usb); if(old_online != chip->online) power_supply_changed(&chip->ac); */ power_supply_changed(&chip->ac); // 回调ac 中的get_property() // for test power_supply_changed(&chip->battery); // 回调battery中的get_property() power_supply_changed(&chip->usb); // 回调usb中的get_property() // schedule_delayed_work(&chip->work, MAX17040_DELAY); } |
linux 电源管理驱动编写相关推荐
- linux驱动编写(电源管理驱动)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 对于嵌入式设备来说,合适的电源管理,不仅可以延长电池的寿命,而且可以省电,延长设备运行时间,在提 ...
- Linux电源管理(5)_Hibernate和Sleep功能介绍【转】
本文转载自:http://www.wowotech.net/pm_subsystem/std_str_func.html 1. 前言 Hibernate和Sleep两个功能是Linux Generic ...
- linux 电池管理软件,Linux电源管理(2)_Generic PM之基本概念和软件架构
Linux电源管理(2)_Generic PM之基本概念和软件架构 作者:wowo 发布于:2014-5-13 19:24 分类:电源管理子系统 1. 前言 这里的Generic PM,是蜗蜗自己起的 ...
- linux系统电源时钟,linux电源管理的一些梳理
由于项目产品需要过能源之星3.0,所以最近做了一些电源管理低功耗方面的工作,抽个时间正好梳理一下. 其实Linux 电源管理非常复杂,牵扯到很多方面,比如系统级的待机.频率电压变换.系统空闲时的处理以 ...
- Linux电源管理(2)_Generic PM之基本概念和软件架构(蜗窝科技,www.wowotech.net)
1. 前言 这里的Generic PM,是蜗蜗自己起的名字,指Linux系统中那些常规的电源管理手段,包括关机(Power off).待机(Standby or Hibernate).重启(Reboo ...
- linux 电源管理 Generic PM之Suspend功能
Linux电源管理(6)_Generic PM之Suspend功能 作者:wowo 发布于:2014-8-22 21:40 分类:电源管理子系统 1. 前言 Linux内核提供了三种Suspend: ...
- Linux电源管理(一)电源管理系统架构
概述 Linux 电源管理非常复杂,牵扯到系统级的待机.频率电压变换.系统空闲时的处理以及每个设备驱动对于系统待机的支持和每个设备的运行时电源管理,可以说和系统中的每个设备驱动都息息相关. 对于消费电 ...
- Linux电源管理(1)_整体架构 -- wowo
1. 前言 在这个世界中,任何系统的运转都需要能量.如树木依靠光能生长,如马儿依靠食物奔跑,如计算机系统依靠电能运行.而能量的获取是有成本的,因此如果能在保证系统运转的基础上,尽量节省对能量的消耗,就 ...
- Linux电源管理(6)_Generic PM之Suspend功能【重磅文章】-- wowo
文章目录 1. 前言 2. Suspend功能有关的代码分布 1)PM Core 2)Device PM 3)Platform dependent PM 3. suspend&resume过程 ...
最新文章
- Important table for SEGW
- 利用JQuery jsonp实现Ajax跨域请求 .Net 的*.handler 和 WebService,返回json数据
- matlab绘制星下点轨迹,MATLAB绘制GPS星下点轨迹图
- oracel 创建视图给某个用户
- 45岁,从中医转行云计算,年薪近百万...
- Machine Learning In Action 第二章学习笔记: kNN算法
- SWFUpload 2.5.0版 官方说明文档 中文翻译版
- C/C++编程笔记:C语言编程知识要点总结!大一C语言知识点(全)
- SwiftUI 高级用法之ForEach如何使用 enumerated() UserDefaults.standard(教程含源码)
- leetcode 刷题之路 70 earch Insert Position 二分查找插入位置
- 在c语言的switch 语句中,的case后面的表达式,什么值必须在switch语句中case后面
- tianchai 12023 水管工游戏(DFS搜索)
- R语言怎么批量进行fisher检验?
- 买的香港云服务器怎么用?云服务器使用教程
- for/in 循环遍历对象的属性
- Jenkins + fastlane + pgyer
- 先调用finish() 然后startActivity有什么区别?
- EdgeTX/OpenTX逻辑开关教程
- Evernote和有道云笔记的比较
- 听到别人发论文的感想
热门文章
- RTMP服务器搭建实时视频直播
- 欧拉路径和欧拉回路(Euler Path and Euler Circuit)解释
- OpenSUSE Ubuntu,使用OpenSUSE代替UBUNTU的若干理由
- flink sql 知其所以然(十):大家都用 cumulate window 计算累计指标啦
- Javaweb JAVA JSP大学生贷款管理系统贷款管理系统jsp大学生助学金贷款管理
- 删除已被禁用的启动项
- HDU2255-KM
- 公司年底裁员,程序员表示给赔偿就行,公司威胁:小心背景调查
- Windows 11 Insider Preview Build 22621.730/22623.730(KB5017385)发布!
- PEX8796等设计资料