Linux电源管理(8)_Wakeup count功能

作者:wowo 发布于:2014-9-12 23:35

分类:电源管理子系统

1. 前言

Wakeup count是Wakeup events framework的组成部分,用于解决“system suspend和system wakeup events之间的同步问题”。本文将结合“Linux电源管理(6)_Generic PM之Suspend功能”和“Linux电源管理(7)_Wakeup events framework”两篇文章,分析wakeup count的功能、实现逻辑、背后的思考,同时也是对这两篇文章的复习和总结。

2. wakeup count在电源管理中的位置

wakeup count的实现位于wakeup events framework中(drivers/base/power/wakeup.c),主要为两个模块提供接口:通过PM core向用户空间提供sysfs接口;直接向autosleep(请参考下一篇文章)提供接口。

3. wakeup count的功能

wakeup count的功能是suspend同步,实现思路是这样的:

1)任何想发起电源状态切换的实体(可以是用户空间电源管理进程,也可以是内核线程,简称C),在发起状态切换前,读取系统的wakeup counts(该值记录了当前的wakeup event总数),并将读取的counts告知wakeup events framework。

2)wakeup events framework记录该counts到一个全局变量中(saved_count)。

3)随后C发起电源状态切换(如STR),执行suspend过程。

4)在suspend的过程中,wakeup events framework照旧工作(直到系统中断被关闭),上报wakeup events,增加wakeup events counts。

5)suspend执行的一些时间点(可参考“Linux电源管理(6)_Generic PM之Suspend功能”),会调用wakeup  events framework提供的接口(pm_wakeup_pending),检查是否有wakeup没有处理。

6)检查逻辑很简单,就是比较当前的wakeup counts和saved wakeup counts(C发起电源状态切换时的counts),如果不同,就要终止suspend过程。

4. wakeup count的实现逻辑

4.1 一个例子

在进行代码分析之前,我们先用伪代码的形式,写出一个利用wakeup count进行suspend操作的例子,然后基于该例子,分析相关的实现。

1: do {

2: ret = read(&cnt, "/sys/power/wakeup_count");

3: if (ret) {

4: ret = write(cnt, "/sys/power/wakeup_count");

5: } else {

6: countine;

7: }

8: } while (!ret);

9:

10: write("mem", "/sys/power/state");

11:

12: /* goto here after wakeup */

例子很简单:

a)读取wakeup count值,如果成功,将读取的值回写。否则说明有正在处理的wakeup events,continue。

b)回写后,判断返回值是否成功,如果不成功(说明读、写的过程中产生了wakeup events),继续读、写,直到成功。成功后,可以触发电源状态切换。

4.2 /sys/power/wakeup_count

wakeup_count文件是在kernel/power/main.c中,利用power_attr注册的,如下(大家可以仔细研读一下那一大段注释,内核很多注释写的非常好,而好的注释,就是软件功力的体现):

1: /*

2: * The 'wakeup_count' attribute, along with the functions defined in

3: * drivers/base/power/wakeup.c, provides a means by which wakeup events can be

4: * handled in a non-racy way.

5: *

6: * If a wakeup event occurs when the system is in a sleep state, it simply is

7: * woken up. In turn, if an event that would wake the system up from a sleep

8: * state occurs when it is undergoing a transition to that sleep state, the

9: * transition should be aborted. Moreover, if such an event occurs when the

10: * system is in the working state, an attempt to start a transition to the

11: * given sleep state should fail during certain period after the detection of

12: * the event. Using the 'state' attribute alone is not sufficient to satisfy

13: * these requirements, because a wakeup event may occur exactly when 'state'

14: * is being written to and may be delivered to user space right before it is

15: * frozen, so the event will remain only partially processed until the system is

16: * woken up by another event. In particular, it won't cause the transition to

17: * a sleep state to be aborted.

18: *

19: * This difficulty may be overcome if user space uses 'wakeup_count' before

20: * writing to 'state'. It first should read from 'wakeup_count' and store

21: * the read value. Then, after carrying out its own preparations for the system

22: * transition to a sleep state, it should write the stored value to

23: * 'wakeup_count'. If that fails, at least one wakeup event has occurred since

24: * 'wakeup_count' was read and 'state' should not be written to. Otherwise, it

25: * is allowed to write to 'state', but the transition will be aborted if there

26: * are any wakeup events detected after 'wakeup_count' was written to.

27: */

28:

29: static ssize_t wakeup_count_show(struct kobject *kobj,

30: struct kobj_attribute *attr,

31: char *buf)

32: {

33: unsigned int val;

34:

35: return pm_get_wakeup_count(&val, true) ?

36: sprintf(buf, "%u\n", val) : -EINTR;

37: }

38:

39: static ssize_t wakeup_count_store(struct kobject *kobj,

40: struct kobj_attribute *attr,

41: const char *buf, size_t n)

42: {

43: unsigned int val;

44: int error;

45:

46: error = pm_autosleep_lock();

47: if (error)

48: return error;

49:

50: if (pm_autosleep_state() > PM_SUSPEND_ON) {

51: error = -EBUSY;

52: goto out;

53: }

54:

55: error = -EINVAL;

56: if (sscanf(buf, "%u", &val) == 1) {

57: if (pm_save_wakeup_count(val))

58: error = n;

59: }

60:

61: out:

62: pm_autosleep_unlock();

63: return error;

64: }

65:

66: tr(wakeup_count);

实现很简单:read时,直接调用pm_get_wakeup_count(注意第2个参数);write时,直接调用pm_save_wakeup_count(注意用户空间的wakeup count功能和auto sleep互斥,会在下篇文章解释原因)。这两个接口均是wakeup events framework提供的接口,跟着代码往下看吧。

4.3 pm_get_wakeup_count

pm_get_wakeup_count的实现如下:

1: bool pm_get_wakeup_count(unsigned int *count, bool block)

2: {

3: unsigned int cnt, inpr;

4:

5: if (block) {

6: DEFINE_WAIT(wait);

7:

8: for (;;) {

9: prepare_to_wait(&wakeup_count_wait_queue, &wait,

10: TASK_INTERRUPTIBLE);

11: split_counters(&cnt, &inpr);

12: if (inpr == 0 || signal_pending(current))

13: break;

14:

15: schedule();

16: }

17: finish_wait(&wakeup_count_wait_queue, &wait);

18: }

19:

20: split_counters(&cnt, &inpr);

21: *count = cnt;

22: return !inpr;

23: }

该接口有两个参数,一个是保存返回的count值得指针,另一个指示是否block,具体请参考代码逻辑:

a)如果block为false,直接读取registered wakeup events和wakeup events in progress两个counter值,将registered wakeup events交给第一个参数,并返回wakeup events in progress的状态(若返回false,说明当前有wakeup events正在处理,不适合suspend)。

b)如果block为true,定义一个等待队列,等待wakeup events in progress为0,再返回counter。

注1:由4.2小节可知,sysfs发起的read动作,block为true,所以如果有正在处理的wakeup events,read进程会阻塞。其它模块(如auto sleep)发起的read,则可能不需要阻塞。

4.4 pm_save_wakeup_count

pm_save_wakeup_count的实现如下:

1: bool pm_save_wakeup_count(unsigned int count)

2: {

3: unsigned int cnt, inpr;

4: unsigned long flags;

5:

6: events_check_enabled = false;

7: spin_lock_irqsave(&events_lock, flags);

8: split_counters(&cnt, &inpr);

9: if (cnt == count && inpr == 0) {

10: saved_count = count;

11: events_check_enabled = true;

12: }

13: spin_unlock_irqrestore(&events_lock, flags);

14: return events_check_enabled;

15: }

1)注意这个变量,events_check_enabled,如果它不为真,pm_wakeup_pending接口直接返回false,意味着如果不利用wakeup count功能,suspend过程中不会做任何wakeup events检查,也就不会进行任何的同步。

2)解除当前的registered wakeup events、wakeup events in progress,保存在变量cnt和inpr中。

3)如果写入的值和cnt不同(说明读、写的过程中产生events),或者inpr不为零(说明有events正在被处理),返回false(说明此时不宜suspend)。

4)否则,events_check_enabled置位(后续的pm_wakeup_pending才会干活),返回true(可以suspend),并将当前的wakeup count保存在saved count变量中。

4.5 /sys/power/state

再回忆一下“Linux电源管理(6)_Generic PM之Suspend功能”中suspend的流程,在suspend_enter接口中,suspend前的最后一刻,会调用pm_wakeup_pending接口,代码如下:

1: static int suspend_enter(suspend_state_t state, bool *wakeup)

2: {

3: ...

4: error = syscore_suspend();

5: if (!error) {

6: *wakeup = pm_wakeup_pending();

7: if (!(suspend_test(TEST_CORE) || *wakeup)) {

8: error = suspend_ops->enter(state);

9: events_check_enabled = false;

10: }

11: syscore_resume();

12: }

13: ...

14: }

在write wakeup_count到调用pm_wakeup_pending这一段时间内,wakeup events framework会照常产生wakeup events,因此如果pending返回true,则不能“enter”,终止suspend吧!

注2:wakeup后,会清除events_check_enabled标记。

“Linux电源管理(7)_Wakeup events framework”中已经介绍过pm_wakeup_pending了,让我们再看一遍吧:

1: bool pm_wakeup_pending(void)

2: {

3: unsigned long flags;

4: bool ret = false;

5:

6: spin_lock_irqsave(&events_lock, flags);

7: if (events_check_enabled) {

8: unsigned int cnt, inpr;

9:

10: split_counters(&cnt, &inpr);

11: ret = (cnt != saved_count || inpr > 0);

12: events_check_enabled = !ret;

13: }

14: spin_unlock_irqrestore(&events_lock, flags);

15:

16: if (ret)

17: print_active_wakeup_sources();

18:

19: return ret;

20: }

a)首先会判断events_check_enabled是否有效,无效直接返回false。有效的话:

b)获得cnt和inpr,如果cnt不等于saved_count(说明这段时间内有events产生),或者inpr不为0(说明有events正在被处理),返回true(告诉调用者,放弃吧,时机不到)。同时清除events_check_enabled的状态。

c)否则,返回false(放心睡吧),同时保持events_check_enabled的置位状态(以免pm_wakeup_pending再次调用)。

Okay,结束了,等待wakeup吧~~~~

原创文章,转发请注明出处。蜗窝科技,www.wowotech.net。

评论:

catamout

2020-03-12 10:45

bool pm_wakeup_pending(void)

首先会判断events_check_enabled是否有效,无效直接返回false。

在kernel/power/suspend_test.c中test_suspend进入休眠的流程events_check_enabled == false,那休眠的整个过程中,pm_wakeup_pending的返回值都是false,没有去检测是否有event产生。

是否存在其他events_check_enabled == false时,系统进入休眠的情况?

cym

2017-11-01 11:07

Hi wowo

在N上遇到有很多的wakeup source:

Line 571: 09-16 09:44:07.490     0     0 I         : [460489.904631,1] last active wakeup source: ipc000002b2_PowerManagerSer

Line 657: 09-16 09:44:09.380     0     0 I         : [460491.346436,0] last active wakeup source: ipc000002b2_PowerManagerSer

Line 717: 09-16 09:44:11.446     0     0 I         : [460492.174366,2] last active wakeup source: ipc000002b2_PowerManagerSer

Line 895: 09-16 09:44:17.257     0     0 I         : [460494.912370,1] last active wakeup source: ipc000002b2_PowerManagerSer

Line 987: 09-16 09:44:18.967     0     0 I         : [460496.271585,2] last active wakeup source: ipc000002b2_PowerManagerSer

Line 1106: 09-16 09:44:24.730     0     0 I         : [460501.129454,2] last active wakeup source: ipc000002b2_PowerManagerSer

请问下你知道这是怎么产生的吗??

Rafe

2017-09-12 16:06

@wowo

请教一个问题:

我在高通的power key driver中看到,当设备处于suspend mode的时候,按power key唤醒设备,中断处理仅仅通过input子系统上报键值。且上报前没有任何的延迟操作。

所以我觉得这个时候,用户空间进程应该会存在还未resume回来或者没有被调度到的情况,而autosleep timeout,紧接着再次进入suspend mode。

而我现在看到的现象是从没出现过这种情况,我现在就是不清楚是像我猜测的那样?

还是每次用户空间都能准时收到?又或者Linux的电源管理部分有相关的地方保证了消息的发送处理?

2017-09-13 16:39

@Rafe:你这个问题很有意思,确实像你说的那样,有些powerkey的上报根本没有处理wakeup event有关的内容,之所以没有出问题,我的猜测是(只是猜测,没有仔细分析,有空的话你可以试试):

1)用户空间程序(例如android的EventHub,frameworks/native/services/inputflinger/EventHub.cpp)一直都poll(等待)在key event上。

2)当power key事件上报的时候,kernel会wakeup等待队列,以便让用户空间程序执行并读取到键值。

3)在等待的线程被执行之前,系统不能(或者没有机会)再次被休眠(autosleep也是在线程中?),直到等待的线程醒来。

4)处理键值的线程醒来执行后,就好办了~~~

mallocnew

2017-03-21 23:16

非常感谢就是还有个小疑问:

pm_save_wakeup_count中的

3)如果写入的值和cnt不同(说明读、写的过程中产生events),或者inpr不为零(说明有events正在被处理),返回false(说明此时不宜suspend)。

以及pm_wakeup_pending中的

b)获得cnt和inpr,如果cnt不等于saved_count(说明这段时间内有events产生),或者inpr不为0(说明有events正在被处理),返回true(告诉调用者,放弃吧,时机不到)。同时清除events_check_enabled的状态。

inpr不为0,停止suspend能理解,而对于“写入的值和cnt不同”和“cnt不等于saved_count”,cnt不是记录的已经处理完成的event的个数吗?如果event已经处理完成了,为什么要停止suspend而不是继续suspend呢?

2017-03-22 08:47

@mallocnew:文中的表述是:

“读取系统的wakeup counts(该值记录了当前的wakeup event总数)”

所以这是总数,不是已处理数。

jiangxinyu

2016-11-16 11:44

@wowo:

你好,有个问题请教下,我想建立一个驱动,里面实现suspend/resume接口,目的是在系统休眠和唤醒时分别被调用,用来实现一些功能控制外设的功能, 目前已经成功注册到Linux pm模块。当我手动执行echo mem > sys/power/state的时候,我写的suspend/resume能够成功执行。但是,现在的问题是,当我的Android设备自动进入休眠或者手按power键的时候,我的suspend/resume函数没有被调用,我追了一下,发现系统休眠的时候,貌似并没有执行sys/power/state这个节点,难道Android系统进入休眠的时候不走Linux的PM机制?

期待您的答复!

2016-11-16 13:05

@jiangxinyu:旧版本的android,很多确实没有使用kernel标准的电源管理框架,转而使用自定义的early suspend机制,你可以检查一下你的代码。

jiangxinyu

2016-11-16 14:28

@wowo:@wowo:

您好,我的suspend/resume能够被调用到了,原因是连着USB抓的实时log,汗。。

还有两个个问题:

1 APP获取的wake_lock最终会走到sys/power/wake_lock吗?也就是说APP申请的锁是不是最终也会进入kernel空间?

2 假如后台有应用一直在跑(一直占用wake_lock),sys/power/state永远不会被写入mem,是这样吗?

2016-11-16 21:25

@jiangxinyu:如果android使用linux kernel标准的autosleep、wakelock机制,你提到的这两点是对的。

2020-10-13 10:57

@jiangxinyu:是的,android某些版本,播放音乐时 即使按下power-key黑屏,系统也不会suspend,原因就是music app一直take wake_lock。

2016-10-20 18:36

cracker

12 分钟前

@wowo:在_device_suspend如下代码

if (pm_runtime_barrier(dev) && device_may_wakeup(dev))

pm_wakeup_event(dev, 0);(1)

if (pm_wakeup_pending()) {       (2)

pm_get_active_wakeup_sources(suspend_abort,

MAX_SUSPEND_ABORT_LEN);

log_suspend_abort_reason(suspend_abort);

async_error = -EBUSY;

goto Complete;

}

这段代码(2)处不是在做设备睡眠前的最后检查吗?因为这里检查完就调用dirver->pm->suspend去关中断了。如果设备没有wakeup event,才会走到syscore_suspend

另外,(1)处的作用是什么呢?

===============================================

并不是所有设备都希望关中断,特别是那些有唤醒能力的设备。另外没有规定dirver->pm->suspend一定会关中断。

(1)处的作用,正好是处理那些有唤醒能力的设备,怎么处理呢?参考代码的注释就行了(确保此时这个设备能醒来,以便为当前的事情做准备):

/*

* If a device configured to wake up the system from sleep states

* has been suspended at run time and there's a resume request pending

* for it, this is equivalent to the device signaling wakeup, so the

* system suspend operation should be aborted.

*/

2016-10-20 19:05

@wowo:1、是不是可以这么理解:suspend_ops->enter(state)这里是保持suspend最后的状态,如果有中断信号(这个状态已经不依赖wakeup count终止suspend),然后syscore_resume()?

2、我有最简单的疑问,Android N上插着usb,然后执行echo mem >sys/power/state,可以看到屏幕背光灭了,但是cat proc/kmsg log:<6>[ 3769.251077][2016-01-03 20:36:55.759322763]PM: suspend entry 2016-01-03 20:36:55.745081096 UTC

<6>[ 3769.259538][2016-01-03 20:36:55.839104013]PM: Syncing filesystems ... done.

<7>[ 3769.339710][2016-01-03 20:36:55.839118492]PM: Preparing system for mem sleep

<6>[ 3769.581798][2016-01-03 20:36:56.122554950]Restarting tasks ... done.

<6>[ 3769.620337][2016-01-03 20:36:56.122567710]PM: suspend exit 2016-01-03 20:36:56.114344950 UTC

不明白屏幕为什么会灭,手动写节点,在freeze task被终止suspend,没处理到device啊

另外,终止suspend的原因是usb锁没释放吗,我看wake_lock节点下有PowerManagerService.Display和PowerManagerService.WakeLocks这两个锁

2016-10-20 19:51

@cracker:1. 是的。

2. 为什么屏幕背光毁灭?我猜在freeze task的时候,有些task主动关的背光,不过具体是怎么回事,你可以再查查。至于suspend失败的原因,应该是电源管理服务的锁----PowerManagerService.WakeLocks(因为你现在在充电)。另外你可以看看这个文件,它有很多统计信息:

/sys/kernel/debug/suspend_stats

汉纸月

2016-08-26 16:58

@wowo

有一事不明,请教老师,主要就是内核都睡下去了,如何才醒得过来:

假设是STR,在函数suspend_enter中,最终调用如下函数进入了睡眠中。

error = suspend_ops->enter(state);

当函数返回的时候,睡眠就结束了,开始了resume的过程。

这个suspend_ops->enter(state);中做了些什么事情呢?它怎么能突然就醒了呢?

syscore_suspend()函数似乎是在irq禁止的情况下调用的。所以suspend_ops->enter(state)这个里面,中断是不是也禁止了?

就算中断没有禁止,中断处理器和这个函数处于两个执行线程中,如何从中断处理器中通知suspend_ops->enter(state)有wakeup事件需要醒过来呢?

能以ARM为例介绍一下吗?非常感谢老师了。

2016-08-26 17:26

@汉纸月:你可以这样认为:

当CPU执行完syscore_suspend中的某一个指令后,它就停止工作了。直到外设(例如GIC,它还活着)给它发送一个硬件的wakeup信号,它就醒了,继续执行,suspend_ops->enter返回。

具体可以看看下面大家的评论和讨论。

aaron

2016-04-18 16:36

你好,请教一个问题。

先介绍一下背景,android4.4+kernel3.10

我们设计要求是当用户按下电源按键(用户请求系统休眠)时,系统必须无条件进入休眠。但用户再次按下电源键时必须无条件唤醒系统。

目前我们我们修改了powermanger中wakelock的机制保证满足我们的设计要求。

现在测试发现一个问题:有时候用户按电源键试图唤醒系统时,并没有将系统唤醒。通过log分析发现当用户按下电源键时,内核已经被唤醒了,但是紧接着又进入了suspend过程。

现在不清楚是什么原因。

2016-04-18 17:04

@aaron:首先,我觉得,“无条件休眠”这种设计,有点粗暴,不妥。kernel的suspend过程,需要很多同步操作,这样做,可能会有一些问题。

然后是你的问题,很明显,两次power key按下之间,没有同步好,每次power key按下被处理的时候,需要严格依赖当前的状态(以便执行toggle动作)。例如,当power key按下后:

如果系统正在执行suspend,要怎么办?

如果系统正在执行resume,要怎么办?

2015-08-03 16:38

打扰了,wowo请教一个问题,当进入enter之前中断已经被关闭了,CPU进入suspend后,这里的wakeup event是指什么呢?CPU是靠什么东西来捕获的自动恢复的?

2015-08-03 21:42

@锐:这个问题可以参考“http://www.wowotech.net/linux_kenrel/suspend_and_resume.html”中linuxer同学的回答。

2015-08-04 14:46

@wowo:谢谢wowo,看了解释,受益匪浅,但还有一点不太明白,linuxer说:

GIC和各个CPU的接口包括两种硬件信号:

(a)触发CPU中断的信号。nIRQCPU和nFIQCPU信号线,熟悉ARM CPU的工程师对这两个信号线应该不陌生,主要用来触发ARM cpu进入IRQ mode和FIQ mode。

(b)Wake up信号。nFIQOUT和nIRQOUT信号线,去ARM CPU的电源管理模块,用来唤醒CPU的

因此disable了CPU的中断仅仅是堵死了中断这一个分支而已,wakeup信号仍在正常工作中。

当CPU休眠的时候,中断关闭的时候,wakeup信号怎么才能产生呢?比如:外部一个按键按钮按下或者点击触摸屏的时候,GIC捕获到wakeup信号了?

在系统suspend之后,捕获这种特定信号来唤醒,在driver里注册中断是不是加入IRQF_NO_SUSPEND这个标识就可以做到了?

2015-08-04 15:19

@锐:是的,GIC没有睡死,如果加入IRQF_NO_SUSPEND,就会保留这个设备和GIC之间的联系。

2015-08-06 17:45

@wowo:wowo,你好,非常感谢你的分享。按照CPU进入休眠状态的说法,是不是也就说现在的安卓系统锁屏,基本上都不会进入suspend的状态,就像类似于推送服务一样,它需要捕获网络发送过来的消息,都获取了wakelock,阻止系统进入了休眠,程序一直在后台运行不是比较耗电吗?

2015-08-06 18:23

@锐:网络消息不需要实时啊,定时去取就行了,所以还是会suspend的。

2015-06-30 20:13

注意这个变量,events_check_enabled,如果它不为真,pm_wakeup_pending接口直接返回false,意味着如果不利用wakeup count功能,suspend过程中不会做任何wakeup events检查,也就不会进行任何的同步。

------如果events_check_enabled不为真的话,应该不会跑到pm_wakeup_pending的吧。会发生wakeup_count_store回写错误,用户空间进程被终止。所以"也就不会进行任何的同步"不会存在这种情况的吧。

2015-06-30 20:17

@koala:所以,只要跑到pm_wakeup_pending时,events_check_enabled肯定会被置1的,不然pm_wakeup_pending返回0,suspend_ops->enter(state)一定会被执行。

2015-06-30 21:28

@koala:可能您理解错我的意思了,/sys/power/state可以在不操作wakeup count的前提下使用的,在这种情况下,suspend过程会跑到pm_wakeup_pending,由于events_check_enabled为false,则不会进行任何的检查,继续suspend过程。

其实这就是传统suspend的方法,即不依赖wakeup count时的方法,此时kernel不会做任何同步处理。

1 2

发表评论:

昵称

邮件地址 (选填)

个人主页 (选填)

Linux中_countof函数,Linux电源管理(8)_Wakeup count功能相关推荐

  1. linux中dup2函数,Linux 下的 dup 和 dup2 函数简介

    dup 和 dup2 都可以用来复制一个现存的文件描述符.经常用来重新定向进程的 STDIN, STDOUT, STDERR. dup 函数 dup 函数定义在 中,函数原形为: int dup ( ...

  2. linux中probe函数的pm管理,linux中 probe函数的何时调用的

    所以的驱动教程上都说:只有设备和驱动的名字匹配,BUS就会调用驱动的probe函数,但是有时我们要看看probe函数里面到底做了什么,还有传递给probe函数的参数我们就不知道在哪定义(反正不是我们在 ...

  3. linux中iconv函数,Linux下编码转换(iconv函数族)

    转自:http://www.linuxdiyf.com/viewarticle.php?id=45164 在Linux上进行编码转换时,既可以利用iconv函数族编程实现,也可以利用iconv命令来实 ...

  4. linux中execvp函数,Linux shell的实现——execvp

    一.类Linux(包括Android)操作系统elf文件执行过程 从上边分析,我们知道:Linux支持的标准可执行文件格式为elf,Linux内核会对该格式文件进行解析并执行.而这个过程最重要的就是e ...

  5. Linux中gsub函数,Linux中awk下 gsub函数用法

    一.遇到的问题: 问题:echo "a b c 2011-11-22 a:d" | awk '$4=gsub(/-/,"",$4)'为啥 输出后 2011-11 ...

  6. linux中creat-file函数,Linux应用程序-文件编程-file_creat()函数的问题

    * **系统调用:创建一个文件 **函数原型:int creat(const char *filename,mode_t mode); **参数:filename->要创建的文件名(包含路径,缺 ...

  7. linux如deepin manjaro对笔记本电脑电池的伤害解决方案:TLP:一个可以延长 Linux 笔记本电池寿命的高级电源管理工具

    TLP:一个可以延长 Linux 笔记本电池寿命的高级电源管理工具 笔记本电池是针对 Windows 操作系统进行了高度优化的,当我在笔记本电脑中使用 Windows 操作系统时,我已经意识到这一点, ...

  8. Linux中pthread_create函数的实现

    转:http://blog.sina.com.cn/s/blog_6abf2c040101fpca.html 原文地址:[原]Linux中pthread_create函数的实现作者:jiq408694 ...

  9. linux中probe函数传递参数的寻找(下)

    点击打开链接 linux中probe函数传递参数的寻找(下) 通过追寻driver的脚步,我们有了努力的方向:只有找到spi_bus_type的填充device即可,下面该从device去打通,当两个 ...

  10. linux中 probe函数的何时调用的?

    点击打开链接 linux中 probe函数何时调用的 所以的驱动教程上都说:只有设备和驱动的名字匹配,BUS就会调用驱动的probe函数,但是有时我们要看看probe函数里面到底做了什么,还有传递给p ...

最新文章

  1. 解决:No configuration found. Configuring ehcache from ehcache-failsafe.xml 问题
  2. MobileViT 网络测试
  3. 1SGD、Momention原理
  4. android项目打包成apk
  5. 龙芯3A4000 VNC配置
  6. 【转载】并发操作会带来哪些数据不一致性(数据库)
  7. 8 -- 深入使用Spring -- 4...3 AOP的基本概念
  8. [活动]《博客园精华集》设计模式分册第2轮筛选结果公示
  9. ipconfig默认网关为空_网络工程师之IPCONFIG命令详解
  10. 麦轮平台的速度分解与合成
  11. Python 基础 —— re:正则表达
  12. tf.keras与 TensorFlow混用,trainable=False设置无效
  13. 一致性算法中的节点下限(转)
  14. ZC公司员工评分系统——前台排版算法
  15. 基于Python的BOSS直聘Python岗位数据分析
  16. 打开心扉计算机谱子,教你演唱咏叹调《人们叫我咪咪》(附曲谱)丨选自普契尼歌剧《艺术家的生涯》...
  17. 翟菜花:搜索引擎这碗饭,到底能不能吃?
  18. 如何在win10下安装Docker
  19. git错误:error: failed to push some refs to
  20. 第十章:如何制定项目目标?

热门文章

  1. 测试投入度量元的选择
  2. Connection reset by peer 问题解析
  3. 2020高中计算机会考成绩查询,2020年高中会考成绩查询入口
  4. U3D性能优化之MeshBaker(带光照)
  5. 消费者行为学的典型营销案例
  6. 服务器linux攻击方法,Linux操作系统中实现DDOS攻击的方法
  7. arXiv | FedPer:带个性化层的联邦学习
  8. blendshapes
  9. import * as用法
  10. 【小样本基础】N-way K-shot 模式和训练策略