lpm_cpu.c
2.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
* Native CPU lpm.h implementation
*
* Uses system calls to emulate CPU power modes.
*
* Copyright (C) 2013 Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
* @ingroup lpm
* @ingroup native_cpu
* @{
* @file
* @author Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>
* @}
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>
#include "lpm.h"
#include "debug.h"
#include "cpu.h"
#include "native_internal.h"
static enum lpm_mode native_lpm;
void lpm_init(void)
{
DEBUG("lpm_init()\n");
native_lpm = LPM_ON;
return;
}
void _native_lpm_sleep(void)
{
_native_in_syscall++; // no switching here
real_pause();
_native_in_syscall--;
if (_native_sigpend > 0) {
DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n");
_native_in_syscall++;
_native_syscall_leave();
}
}
/**
* LPM_IDLE uses sleep() to wait for interrupts
* LPM_OFF exits process
* other modes not supported at the moment
*/
enum lpm_mode lpm_set(enum lpm_mode target)
{
enum lpm_mode last_lpm;
//DEBUG("lpm_set(%i)\n", target);
last_lpm = native_lpm;
native_lpm = target;
switch(native_lpm) { /* @contiki :-p */
case LPM_ON:
break;
case LPM_IDLE:
//DEBUG("lpm_set(): pause()\n");
//pause();
_native_lpm_sleep();
break;
/* XXX: unfinished modes: */
case LPM_SLEEP:
/*TODO: implement*/
printf("XXX: lpm_set(): LPM_SLEEP not implemented\n");
//sigsuspend();
case LPM_POWERDOWN:
/*TODO: implement*/
printf("XXX: lpm_set(): LPM_POWERDOWN not implemented\n");
//sigsuspend();
case LPM_OFF:
printf("lpm_set(): exit()\n");
real_exit(EXIT_SUCCESS);
default:
DEBUG("XXX: unsupported power mode: %i\n", native_lpm);
real_exit(EXIT_FAILURE);
}
return last_lpm;
}
void lpm_awake(void)
{
DEBUG("XXX: lpm_awake()\n");
native_lpm = LPM_ON;
return;
}
void lpm_begin_awake(void)
{
DEBUG("XXX: lpm_begin_awake()\n");
return;
}
void lpm_end_awake(void)
{
DEBUG("XXX: lpm_end_awake()\n");
native_lpm = LPM_ON;
return;
}
enum lpm_mode lpm_get(void)
{
return native_lpm;
}