五.电源供电框架(kernel)与电源管理 (app)
事实上,我们还遗漏了一个问题,对于使用电源供电和电池供电的电源管理分析。在前面提到过,client会为维护一个线程,用于处理应用与server之间的工作,同时提供库和接口。而电源状态的变化这个过程除了人为的设置之外,还受所使用的电源的影响。
电源状态的监控是用uevent事件实现的。Linux内核中,供电部分的框架(drivers/power目录下,power_supply_core,power_supply_sysfs)提供了uevent机制,驱动可以在电源状态发生变化时发送uevent事件到用户空间,从而通知系统做相应的处理。(对于内核空间与用户空间的uevent通信,用的始终是NETLINK_KOBJECT_UEVENT这个socket通道)。
目前在下面这些情况下产生UEVENT事件:
(1)电池电量等级变化:电池电量等级包括满、高电量、普通电量、低电量、电量不足
(2)外电插入、拔出
(3)充电状态改变:包括充电中、禁止充电、不在充电、充饱等状态
所以,我们启动给一个电源状态维护线程,监控UEVENT事件发生,同时对不同的uevent事件调用不同的电源管理接口。比如在外电插入的情况下禁止进入休眠,在电池低电量的时候允许进入休眠等设置。
六.一些细节
1.以前提到过系统调用的用法,在电源管理中定时器也用到了系统调用,下载timerfd.patch,实现部分如下,
#if defined(__arm__)
#define __NR_timerfd_create(__NR_SYSCALL_BASE+350)
#define __NR_timerfd_settime(__NR_SYSCALL_BASE+353)
#define __NR_timerfd_gettime(__NR_SYSCALL_BASE+354)
#define TFD_TIMER_ABSTIME (1 << 0)
#endif
//#endif /* __NR_timerfd_create */
static int timerfd_create(int clockid, int flags)
{
return syscall(__NR_timerfd_create, clockid, flags);
}
static int timerfd_settime(int ufc, int flags, const struct itimerspec *utmr, struct itimerspec *otmr)
{
return syscall(__NR_timerfd_settime, ufc, flags, utmr, otmr);
}
2.__attribute__ ((constructor))
Gcc为函数提供了几种类型的属性,其中有构造函数constructor和析构函数destructors
Static void start(void) __attribute__ ((constructor))
Static void stop(void) __attribute__ ((destructors))
带有构造函数属性的函数会在main函数之前执行,而析构函数会在_after_main()退出时执行,具体的问题分析可以参见
转载博客
__attribute__ ((__format__(__printf__,m,n)))
This指针,继承概念
3.在client中涉及到threadWakeup_fd,因为它是创建的一个事件fd,用于socket更新时,通知系统重新poll,所以比较简单
调用threadWakeup_fd=eventfd(0);
Fcntl(threadWakeup_fd,F_SETFD,FD_CLOEXEC);
当需要通知系统重新poll时,只要向该fd中写入一些数据,原来的poll会有事件上报,在该处理函数中,通知重新poll。
4.关于用户空间定时器的一些操作
内核空间的定时器的使用在linux内核一些机制中提到过。
这里说的用户空间的定时器的操作,到最终的操作肯定为内核定时器。
Timer_fd=timerfd_create(CLOCK_MONOTONIC,0); //
Timerfd_settime(timer_fd,0,&tmr,NULL) //启动定时器
定时时间在struct itimerspec tmr结构中,这个定时器不像内核定时器,可以在时间到时调用定时处理函数,所以我们需要将此fd加入select或者poll中,从而在时间超时时做相应的处理。
5. static int close_socket(int fd)
{
Shutdown(fd,SHUT_RDWR);
Return close(fd);
}
读取一个文件有多少数据可读
Ioctl(fd,FIONREAD,&ibytestoread);