- 0 NULL
- 1 kernel code
- 2 kernel data
- 3 user space code
- 4 user space data
- base -> entry address
- limit -> entry size
- 0 - Division by zero exception
- 1 - Debug exception
- 2 - Non maskable interrupt
- 3 - Breakpoint exception
Results:
@iOS work on normal queue -> id @,0 @NORMAL queue queue :: id 0,time_out : 9,priority : 0,work_time : 2 queue :: id 1,time_out : 2,priority : 1,work_time : 3 queue :: id 2,time_out : 4,priority : 2,work_time : 3 @EMERGENCY queue @iOS work on normal queue -> id @,0 @NORMAL queue queue :: id 0,time_out : 8,priority : 0,work_time : 1 queue :: id 1,time_out : 1,priority : 1,work_time : 3 queue :: id 2,time_out : 3,priority : 2,work_time : 3 @EMERGENCY queue @iOS work on emergency queue -> id @,1 @NORMAL queue queue :: id 2,time_out : 2,priority : 2,work_time : 3 queue :: id 0,time_out : 7,priority : 0,work_time : 1 @EMERGENCY queue queue :: id 1,time_out : 0,priority : 1,work_time : 2 @iOS work on emergency queue -> id @,1 @NORMAL queue queue :: id 2,time_out : 1,priority : 2,work_time : 3 queue :: id 0,time_out : 6,priority : 0,work_time : 1ps: 應該要好好認真的把 OS 看熟才是...XD project @ https://github.com/funningboy/SOC_c_model/tree/master/iOS/ Refs: OS Kernel 相關閱讀與實作心得﹝一﹞ http://en.wikipedia.org/wiki/X86_memory_segmentation x86 Instruction Set Reference x86 Disassembly/Loop Examples OrzMicrokernel tasks.asm 工作排程器的切換執行權函式註解,
void *check_work_queue(void *t){
int i;
for(;;){
//check 4 each ALU in work_queue
pthread_mutex_lock(&count_mutex);
gid = -1;
for(i=0; i<3; i++){
if( is_work_queue_exist(&qulist,i) == QUEUE_ER_ARB ){
gid = i;
break;
}
}
// dump_work_queue(qulist);
pthread_mutex_unlock(&count_mutex);
sleep(ALU_DEF_DELAY);
if( DONE == ALU_OK)
pthread_exit(NULL);
}
}
Results
time @ Fri Oct 15 16:51:49 2010 assign ALU 0 command : 0,in_a : 3,in_b : 4 time @ Fri Oct 15 16:51:51 2010 queue :: id 0,cmd : 0,in_a : 3,in_b : 4, (pre)out_c : 7 assign ALU 1 command : 1,in_a : 3,in_b : 4 time @ Fri Oct 15 16:51:53 2010 queue :: id 1,cmd : 1,in_a : 3,in_b : 4, (pre)out_c : -1 assign ALU 1 command : 2,in_a : 3,in_b : 4 time @ Fri Oct 15 16:51:55 2010 queue :: id 0,cmd : 0,in_a : 3,in_b : 4, (pre)out_c : 7 queue :: id 1,cmd : 1,in_a : 3,in_b : 4, (pre)out_c : -1 assign ALU 2project download here
//儲存CPU status && Disable Interrupt
cpu_sr = save_cpu_sr();
//取得最高priority 的 thread Id
top_prio = get_top_prio();
/* If the timer expires... */
if (sched_type == SCHED_TIME_EXPIRE) {
/* Threads that are currently running will continue to run it
* at the highest priority */
if (current_thread->prio < top_prio) {
current_thread->time_quantum = TIME_QUANTUM;
restore_cpu_sr(cpu_sr);
return;
}
/* otherwise, threads in a ready state, then run the highest
* priority one. */
//取得 ready_list的 first Node 2 entry list && change context switch mode
pnode = delete_front_list(&ready_list[top_prio]);
if (is_empty_list(&ready_list[top_prio]))
prio_exist_flag[top_prio] = false;
next_thread = entry_list(pnode, thread_struct, node);
next_thread->state = RUNNING;
next_thread->time_quantum = TIME_QUANTUM;
/* Ready to change the status of the currently executing thread */
current_thread->state = READY;
insert_back_list(&ready_list[current_thread->prio],
¤t_thread->node);
prio_exist_flag[current_thread->prio] = true;
total_csw_cnt++;
/* actual context switching */
context_switch_in_interrupt();
}
code ref: Jserv's 解析 CuRT 與嵌入式系統設計
放大參考here
ps: 如有錯誤的地方歡迎指正,謝謝
% sudo modprobe uinput2. sample code ref here 確定uinput掛載好後,用ioctl()來控制IO2的讀寫.最後用linux/input.h 中的 input_event來模擬我們 input的vector.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <sys/time.h>
#include <unistd.h>
// Test the uinput module
struct uinput_user_dev uinp;
struct input_event event;
int main(void) {
int ufile, retcode, i;
ufile = open("/dev/input/uinput", O_WRONLY | O_NDELAY );
printf("open /dev/input/uinput returned %d.\n", ufile);
if (ufile == 0) {
printf("Could not open uinput.\n");
return -1;
}
memset(&uinp, 0, sizeof(uinp));
strncpy(uinp.name, "simulated mouse", 20);
uinp.id.version = 4;
uinp.id.bustype = BUS_USB;
ioctl(ufile, UI_SET_EVBIT, EV_KEY);
ioctl(ufile, UI_SET_EVBIT, EV_REL);
ioctl(ufile, UI_SET_RELBIT, REL_X);
ioctl(ufile, UI_SET_RELBIT, REL_Y);
for (i=0; i<256; i++) {
ioctl(ufile, UI_SET_KEYBIT, i);
}
ioctl(ufile, UI_SET_KEYBIT, BTN_MOUSE);
// create input device in input subsystem
retcode = write(ufile, &uinp, sizeof(uinp));
printf("First write returned %d.\n", retcode);
retcode = (ioctl(ufile, UI_DEV_CREATE));
printf("ioctl UI_DEV_CREATE returned %d.\n", retcode);
if (retcode) {
printf("Error create uinput device %d.\n", retcode);
return -1;
}
// NOW DO STUFF !!!!
for (i=0; i<100; i++) {
struct timeval tv1;
// move pointer upleft by 5 pixels
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_REL;
event.code = REL_X;
event.value = -5;
write(ufile, &event, sizeof(event));
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_REL;
event.code = REL_Y;
event.value = -5;
write(ufile, &event, sizeof(event));
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(ufile, &event, sizeof(event));
// wait just a moment
do { gettimeofday(&tv1, NULL); } while ((tv1.tv_usec &
0x3FFF) != 0);
do { gettimeofday(&tv1, NULL); } while ((tv1.tv_usec &
0x3FFF) == 0);
}
// destroy the device
ioctl(ufile, UI_DEV_DESTROY);
close(ufile);
}
ps: Keymouse 也是用此原理來做的, 你可以在 device.cpp 發現相似的地方.
Refs:
Sending simulated mouse events using uinput
Mouseemu / uinput
Linux Cross Reference
Linux 驅動程式的 I/O, #4: fops->ioctl 實作
最近剛開始研究圖形介面,發現 Mesa 有提供Hw 加速的功能,可透過 Mesa 的 API 直接控制硬體來減少Sw 的複雜度. 底下找了一些相關的data,有興趣的人可以看看
Refs:
x.org case study
Linux 的3D加速--DRI
Mesa
Mesa 3D
OpenGL
[PDF] OpenGL Programming Guide
Xephyr -kb -query xxx.xxx.xxx.xxx -fullscreen -ac :10Refs: X Window System core protocol Xephyr Multiseat Configuration/Xephyr
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char* argv[]){
if(argc!=2){
printf("usage %s <string> \n",argv[0]);
exit(EXIT_FAILURE);
}
printf("%s\n",argv[1]);
exit(EXIT_SUCCESS);
}
step 2. 用 execve 來執行 sample.exe
注意 ./sample 是需要代入參數
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[]){
char *newargv[] = { NULL, "Hello", NULL };
char *newenviron[] = { NULL };
if (argc != 2) {
fprintf(stderr, "Usage: %s <file-to-exec>\n", argv[0]);
exit(EXIT_FAILURE);
}
newargv[0] = argv[1];
execve(argv[1], newargv, newenviron);
perror("execve"); /* execve() only returns on error */
exit(EXIT_FAILURE);
}
Refs: Linux Programmer's Manual EXECVE(2)
Execve problem with invoking
execve problem solaris
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/reg.h>
#include <sys/syscall.h> /* For SYS_write etc */
#include <stdio.h>
#include <stdlib.h>
int main()
{ pid_t child;
long orig_eax, eax;
long params[3];
int status;
int insyscall = 0;
child = fork();
if(child == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl("/bin/ls", "ls", NULL);
}
else {
while(1) {
wait(&status);
if(WIFEXITED(status))
break;
orig_eax = ptrace(PTRACE_PEEKUSER,
child, 4 * ORIG_EAX, NULL);
if(orig_eax == SYS_write) {
if(insyscall == 0) {
/* Syscall entry */
insyscall = 1;
params[0] = ptrace(PTRACE_PEEKUSER,
child, 4 * EBX,
NULL);
params[1] = ptrace(PTRACE_PEEKUSER,
child, 4 * ECX,
NULL);
params[2] = ptrace(PTRACE_PEEKUSER,
child, 4 * EDX,
NULL);
printf("Write called with "
"%ld, %ld, %ld\n",
params[0], params[1],
params[2]);
}
else { /* Syscall exit */
eax = ptrace(PTRACE_PEEKUSER,
child, 4 * EAX, NULL);
printf("Write returned "
"with %ld\n", eax);
insyscall = 0;
}
}
ptrace(PTRACE_SYSCALL,
child, NULL, NULL);
}
}
return 0;
}
code ref : Playing with ptrace
ps : 當然你也可以用 strace 來trace 執行時所呼叫的system call.
Refs:
ptrace
Playing with ptrace
#include >sys/wait.h>
#include >stdio.h>
#include >stdlib.h>
#include >unistd.h>
#include >string.h>
int
main(int argc, char *argv[])
{
int pipefd[2];
pid_t cpid;
char buf;
if (argc != 2) {
fprintf(stderr, "Usage: %s >string>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (pipe(pipefd) == -1) { // create pipe structure...
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork(); // create child proc
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { /* Child reads from pipe */
printf("Child...\n");
close(pipefd[1]); /* Close unused write end */
// disable write func
while (read(pipefd[0], &buf, 1) > 0) // read from argv[] one chart by one chart
write(STDOUT_FILENO, &buf, 1); // write 2 STDOUT
write(STDOUT_FILENO, "\n", 1);
close(pipefd[0]); // disable read func
_exit(EXIT_SUCCESS); // child proc end
} else { /* Parent writes argv[1] to pipe */
printf("Parent...\n");
close(pipefd[0]); /* Close unused read end */
write(pipefd[1], argv[1], strlen(argv[1]));
close(pipefd[1]); /* Reader will see EOF */
wait(NULL); /* Wait for child */
exit(EXIT_SUCCESS);
}
}
code ref: Linux Programmer's Manual
Refs :
Linux Programmer's Manual PIPE(2)
pipe(7) - Linux man page
Executing programs with C(Linux)
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[]) {
int count = 1;
int child;
if(!(child = vfork())) {
printf("This is son, his count is: %d. and his pid is: %d\n", ++count, getpid());
} else {
printf("This is father, his count is: %d, his pid is: %d\n", count, getpid());
}
return 0;
}
clone.c
發現 Parent 的 Data 會被 Child 而改變.
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <signal.h>
#define FIBER_STACK 8192
int a;
void * stack;
int do_something(){
printf("This is son, the pid is:%d, the a is: %d\n", getpid(), ++a);
free(stack);
exit(1);
}
int main() {
void * stack;
a = 1;
stack = malloc(FIBER_STACK);
if(!stack) {
printf("The stack failed\n");
exit(0);
}
printf("creating son thread!!!\n");
clone(&do_something, (char *)stack + FIBER_STACK, CLONE_VM|CLONE_VFORK, 0);
printf("This is father, my pid is: %d, the a is: %d\n", getpid(), a);
exit(1);
}
Refs:
fork,vfork和clone底层实现
fork, vfork, clone,pthread_create,kernel_thread
clone fork及vfork的区别
Refs: Android-x86 - Porting Android to x86
artigo_a1100_barebones_pc_review
TT *get_TTNode(TT *p,int Id){
TT *tPtr = p;
while(tPtr!=NULL){
if( tPtr->Id == Id ){
return tPtr; break;
}
tPtr = tPtr->Nxt;
}
return NULL;
}
objdump -d (disassemble)
080484d3 <get_TTNode>: 80484d3: 55 push %ebp 80484d4: 89 e5 mov %esp,%ebp // store current stack pointer 80484d6: 83 ec 14 sub $0x14,%esp 80484d9: 8b 45 08 mov 0x8(%ebp),%eax // get "TT *p" 80484dc: 89 45 fc mov %eax,-0x4(%ebp) // "TT *tPtr = p" 80484df: eb 1b jmp 80484fc <get_TTNode+0x29> // jump to while loop 80484e1: 8b 45 fc mov -0x4(%ebp),%eax // "tPtr->Id" 80484e4: 8b 00 mov (%eax),%eax // mov to eax register 80484e6: 3b 45 0c cmp 0xc(%ebp),%eax // cmp (tPtr->Id == Id )? true : false; 80484e9: 75 08 jne 80484f3 <get_TTNode+0x20> 80484eb: 8b 45 fc mov -0x4(%ebp),%eax 80484ee: 89 45 ec mov %eax,-0x14(%ebp) // return tPtr 80484f1: eb 16 jmp 8048509 <get_TTNode+0x36> // break 80484f3: 8b 45 fc mov -0x4(%ebp),%eax 80484f6: 8b 40 0c mov 0xc(%eax),%eax // tPtr = tPtr->Nxt 80484f9: 89 45 fc mov %eax,-0x4(%ebp) 80484fc: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) // while loop 8048500: 75 df jne 80484e1 <get_TTNode+0xe> // cmp (tPtr!=NULL)? true : false; 8048502: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%ebp) 8048509: 8b 45 ec mov -0x14(%ebp),%eax //return NULL 804850c: c9 leave 804850d: c3 retRefs : objdump strace
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/sysinfo.h>
#include<unistd.h>
#define __USE_GNU
#include<sched.h>
#include<ctype.h>
#include<string.h>
int main(int argc, char* argv[])
{
int num = sysconf(_SC_NPROCESSORS_CONF);
int created_thread = 0;
int myid;
int i;
int j = 0;
cpu_set_t mask;
cpu_set_t get;
if (argc != 2)
{
printf("usage : ./cpu num\n");
exit(1);
}
myid = atoi(argv[1]);
printf("system has %i processor(s). \n", num);
CPU_ZERO(&mask);
CPU_SET(myid, &mask);
if (sched_setaffinity(0, sizeof(mask), &mask) == -1)
{
printf("warning: could not set CPU affinity, continuing...\n");
}
while (1)
{
CPU_ZERO(&get);
if (sched_getaffinity(0, sizeof(get), &get) == -1)
{
printf("warning: cound not get cpu affinity, continuing...\n");
}
for (i = 0; i < num; i++)
{
if (CPU_ISSET(i, &get))
{
printf("this process %d is running processor : %d\n",getpid(), i);
}
}
}
return 0;
}
code reference [精彩] 发一个多CPU中进程与CPU绑定的例子
Refs:
Linux RCU机制详解
Read-copy-update
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
arch/arm/cpu/arm_cortexa8/start.o (.text)
*(.text)
}
而在 start.s 中,主要透過Assembly code 來設定 @ARM CPU 基本的function Mode,跟load boot-loader 到 RAM 的動作.
start.s
.globl _start
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
_pad: .word 0x12345678 /* now 16*4=64 */
lowlevel_init.S 設定 hold chip 的 Freq. 包含 PLL set, Divide set, Mux set, Memory set, and PLL lock wait(等待 PLL 能穩定).
.globl lowlevel_init
lowlevel_init:
ldr sp, SRAM_STACK
str ip, [sp] /* stash old link register */
mov ip, lr /* save link reg across call */
bl s_init /* go setup pll, mux, memory */
ldr ip, [sp] /* restore save ip */
mov lr, ip /* restore link reg */
/* back to arch calling code */
mov pc, lr
....
pll_ctl_add:
.word CM_CLKEN_PLL
pll_div_add1:
.word CM_CLKSEL1_PLL
cache.S 中設定 Icache(instruction cache) && Dcache(data cache). 如 cache enable, cache disable, cache flush...
l2_cache_enable:
stmfd r13!, {r0, r1, r2, lr}
@ ES2 onwards we can disable/enable L2 ourselves
bl get_cpu_rev
cmp r0, #CPU_3XX_ES20
blt l2_cache_disable_EARLIER_THAN_ES2
mrc 15, 0, r3, cr1, cr0, 1
orr r3, r3, #2
mcr 15, 0, r3, cr1, cr0, 1
b l2_cache_enable_END
step3. other sets
GPIO, sys_info, syslib...
其實就是分別依序填入control value 到相對應的"control Register",能讓系統能做到簡單的work,之後在load kernel image, and build....
Refs :
ARM cortexa8
beagle
Refs:
Das U-Boot -- the Universal Boot Loader
Inside the Linux boot process
Booting
基于S3C2410的Linux全线移植文档 作者:dozec
U-Boot Quick Reference
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <list>
using namespace std;
enum PWSTATE {
PW_RUN =0,
PW_STANDBY =1,
PW_SLEEP =2,
PW_SHUTDOWN =3,
PW_NOP =4,
};
enum PWSWITCH {
ON =0,
OFF =1,
SLEEP =2,
LOW =3,
};
enum PWERROR {
CUR2NXT_OK =0,
CUR2NXT_ERR =1,
CUR2PUT_OK =2,
CUR2PUT_ERR =3,
};
template<class T>
class Power_Man_IN {
public:
T ReBoot;
T Activity;
T InActivity;
T ShutDown;
T CLK;
T Button;
};
template<class T>
class Power_Man_OT {
public:
T CPU;
T LCD;
T Keys;
T Audio;
};
class Power_Man {
public:
Power_Man_IN<int8_t> PW_MN_IN_Pt;
Power_Man_OT<int8_t> PW_MN_OT_Pt;
list<Power_Man_IN<int8_t> > TST_VEC_LIST;
int8_t Cur_ST;
int8_t Nxt_ST;
void SET2PW_MN_IN(int8_t r,int8_t a,int8_t i,int8_t s,int8_t c,int8_t b);
void SET2PW_MN_OT(int8_t c,int8_t l,int8_t k,int8_t a);
int8_t PRO2PW_MN();
int8_t Put2OutREG();
void DisPlaySET2PW_MN_IN();
void DisPlaySET2PW_MN_OT();
//================================
// Test Bench
//================================
void SET_TEST_VECTOR(int8_t r,int8_t a,int8_t i,int8_t s,int8_t c,int8_t b);
void SET_TEST_LIST();
};
power_man.cpp
//#include <systemc.h>
#include "power_man.h"
void Power_Man::SET_TEST_VECTOR(int8_t r,int8_t a,int8_t i,int8_t s,int8_t c,int8_t b){
Power_Man_IN<int8_t> *VECPt = new Power_Man_IN<int8_t>;
VECPt->ReBoot = r;
VECPt->Activity = a;
VECPt->InActivity = i;
VECPt->ShutDown = s;
VECPt->CLK = c;
VECPt->Button = b;
TST_VEC_LIST.push_back(*VECPt);
delete VECPt;
}
//====================================
// Write your Test Bench here
//====================================
void Power_Man::SET_TEST_LIST(){
Cur_ST = PW_NOP;
Nxt_ST = PW_NOP;
SET_TEST_VECTOR(OFF, OFF, OFF, OFF, OFF, OFF);
// Set to Run ST
SET_TEST_VECTOR(ON, OFF, OFF, OFF, OFF, OFF);
SET_TEST_VECTOR(OFF, OFF, OFF, OFF, OFF, OFF);
SET_TEST_VECTOR(OFF, OFF, OFF, OFF, OFF, OFF);
// Set to STANDBY
SET_TEST_VECTOR(OFF, OFF, ON, OFF, OFF, OFF);
SET_TEST_VECTOR(OFF, OFF, OFF, OFF, OFF, OFF);
SET_TEST_VECTOR(OFF, OFF, OFF, OFF, OFF, OFF);
}
void Power_Man::SET2PW_MN_IN(int8_t r,int8_t a,int8_t i,int8_t s,int8_t c,int8_t b){
PW_MN_IN_Pt.ReBoot = r;
PW_MN_IN_Pt.Activity = a;
PW_MN_IN_Pt.InActivity = i;
PW_MN_IN_Pt.ShutDown = s;
PW_MN_IN_Pt.CLK = c;
PW_MN_IN_Pt.Button = b;
}
void Power_Man::SET2PW_MN_OT(int8_t c,int8_t l,int8_t k,int8_t a){
PW_MN_OT_Pt.CPU = c;
PW_MN_OT_Pt.LCD = l;
PW_MN_OT_Pt.Keys = k;
PW_MN_OT_Pt.Audio = a;
}
int8_t Power_Man::PRO2PW_MN(){
switch(Cur_ST){
case PW_RUN : Nxt_ST = (PW_MN_IN_Pt.InActivity == ON )? PW_STANDBY :
(PW_MN_IN_Pt.ShutDown == ON )? PW_SHUTDOWN : PW_RUN; break;
case PW_STANDBY : Nxt_ST = (PW_MN_IN_Pt.InActivity == ON )? PW_SLEEP :
(PW_MN_IN_Pt.Activity == ON )? PW_RUN : PW_STANDBY; break;
case PW_SLEEP : Nxt_ST = (PW_MN_IN_Pt.Activity == ON )? PW_RUN : PW_SLEEP; break;
case PW_SHUTDOWN: Nxt_ST = (PW_MN_IN_Pt.Button == ON )? PW_RUN : PW_SHUTDOWN; break;
case PW_NOP : Nxt_ST = (PW_MN_IN_Pt.ReBoot == ON )? PW_RUN : PW_NOP; break;
default: return CUR2NXT_ERR; break;
}
Cur_ST = Nxt_ST;
return CUR2NXT_OK;
}
int8_t Power_Man::Put2OutREG(){
switch(Cur_ST){
case PW_RUN : SET2PW_MN_OT(ON, ON, ON, ON ); break;
case PW_STANDBY : SET2PW_MN_OT(LOW, OFF, ON, ON ); break;
case PW_SLEEP : SET2PW_MN_OT(SLEEP,OFF, OFF, OFF); break;
case PW_SHUTDOWN: SET2PW_MN_OT(SLEEP,OFF, OFF, OFF); break;
case PW_NOP : SET2PW_MN_OT(OFF, OFF, OFF, OFF); break;
default: return CUR2PUT_ERR; break;
}
return CUR2PUT_OK;
}
void Power_Man::DisPlaySET2PW_MN_IN(){
int8_t r = PW_MN_IN_Pt.ReBoot;
int8_t a = PW_MN_IN_Pt.Activity;
int8_t i = PW_MN_IN_Pt.InActivity;
int8_t s = PW_MN_IN_Pt.ShutDown;
int8_t c = PW_MN_IN_Pt.CLK;
int8_t b = PW_MN_IN_Pt.Button;
cout<<"CTL\t"<<"CLK:\t"<<int(c)<<"\tREBT:\t"<<int(r)<<"\tACT:\t"<<int(a)<<"\tINACT:\t"<<int(i)<<"\tSHTDN:\t"<<int(s)<<"\tBUTTON:\t"<<int(b)<<endl;
}
void Power_Man::DisPlaySET2PW_MN_OT(){
int8_t c = PW_MN_OT_Pt.CPU;
int8_t l = PW_MN_OT_Pt.LCD;
int8_t k = PW_MN_OT_Pt.Keys;
int8_t a = PW_MN_OT_Pt.Audio;
cout<<"PUT\t"<<"CPU:\t"<<int(c)<<"\tLCD:\t"<<int(l)<<"\tKEYS:\t"<<int(k)<<"\tAUDIO:\t"<<int(a)<<endl;
}
int main() {
_List_iterator<Power_Man_IN<int8_t> > it;
Power_Man *PW_MN_Pt = new Power_Man;
PW_MN_Pt->SET_TEST_LIST();
for(it=PW_MN_Pt->TST_VEC_LIST.begin(); it!=PW_MN_Pt->TST_VEC_LIST.end(); it++){
if( PW_MN_Pt->Put2OutREG()!= CUR2PUT_OK ){
cout<<"CUR2PUT Error"<<endl; return -1; }
PW_MN_Pt->DisPlaySET2PW_MN_OT();
int8_t r = it->ReBoot;
int8_t a = it->Activity;
int8_t i = it->InActivity;
int8_t s = it->ShutDown;
int8_t c = it->CLK;
int8_t b = it->Button;
PW_MN_Pt->SET2PW_MN_IN( r, a, i, s, c, b);
PW_MN_Pt->DisPlaySET2PW_MN_IN();
if( PW_MN_Pt->PRO2PW_MN()!= CUR2NXT_OK ){
cout<<"CUR2NXT Error"<<endl; return -1; }
}
delete PW_MN_Pt;
return 0;
}
Results:
PUT CPU: 1 LCD: 1 KEYS: 1 AUDIO: 1
CTL CLK: 1 REBT: 1 ACT: 1 INACT: 1 SHTDN: 1 BUTTON: 1
PUT CPU: 1 LCD: 1 KEYS: 1 AUDIO: 1
CTL CLK: 1 REBT: 0 ACT: 1 INACT: 1 SHTDN: 1 BUTTON: 1
PUT CPU: 0 LCD: 0 KEYS: 0 AUDIO: 0
CTL CLK: 1 REBT: 1 ACT: 1 INACT: 1 SHTDN: 1 BUTTON: 1
PUT CPU: 0 LCD: 0 KEYS: 0 AUDIO: 0
CTL CLK: 1 REBT: 1 ACT: 1 INACT: 1 SHTDN: 1 BUTTON: 1
PUT CPU: 0 LCD: 0 KEYS: 0 AUDIO: 0
CTL CLK: 1 REBT: 1 ACT: 1 INACT: 0 SHTDN: 1 BUTTON: 1
PUT CPU: 3 LCD: 1 KEYS: 0 AUDIO: 0
PS:目前只有考慮 CPU, LCD, KEYS, AUDIO 的 control. 當然你也可以自己 define
所要 control 的 devices
download :
http://sites.google.com/site/funningboy/c/power_man.cpp?attredirects=0&d=1
http://sites.google.com/site/funningboy/c/power_man.h?attredirects=0&d=1