开始尝试写一些工作和学习的东西,从事linux底层开发有一年光景了,从硬件到软件的角色转变,感觉自己喜欢上了这个职业,开始为之添砖加瓦。
最近在学习marvell平台上的ipm机制,打算把学习的心得总结一下。
IPM 在linux上的总体思路为,在用户空间建立一个policy maker,负责收集整个系统的电源信息以并控制更改系统电源状态,调频调压,实现系统动态功耗最小
有如下几个模块负责向policy maker提供信息,idle profiler、perf profiler 、device driver and Applications
• Profilers periodically report the system utilization
Init policy manager communicate system
int IPMServerInitComm(void) { int s_fd; #ifdef IPM_SOCKET_COM struct sockaddr_in ServAddr;
/* Create socket for sending/receiving datagrams */ if ((s_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { fprintf(stderr, "get socket error:%s./n", strerror(errno)); return -1; }
/* Construct local address structure */ memset(&ServAddr, 0, sizeof(ServAddr)); ServAddr.sin_family = AF_INET; ServAddr.sin_addr.s_addr = inet_addr(SERVER_IP); ServAddr.sin_port = htons(PORT_NUM);
/* Bind to the local address */ if (bind(s_fd, (struct sockaddr *) &ServAddr, sizeof(ServAddr)) < 0) { fprintf(stderr, "socket bind error:%s/n", strerror(errno)); return -1; } #else int ret;
ret = mkfifo(PIPESERVER, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); if (ret == -1) { fprintf(stderr, "make pipe error:%s/n", strerror(errno)); return -1; } if ((s_fd = open(PIPESERVER,O_RDWR)) < 0) { fprintf(stderr, "Open ioctl device file %s error./n", "pipe"); return -1; } #endif return s_fd; }
/* * Caller shoule be know that call this function maybe blocked. For P.M */ int IPMServerGetMsg(int s_fd, IPMMsg *msg) { int size; /* Size of received message */ #ifdef IPM_SOCKET_COM /* I don't care the send's address since all of them are local */ if ((size = recvfrom(s_fd,msg,IPM_MSG_SIZE,0, NULL, NULL ))!=IPM_MSG_SIZE) { fprintf(stderr, "socket recvfrom error:%s/n", strerror(errno)); return -1; } #else if ((size = read(s_fd, msg, IPM_MSG_SIZE))!=IPM_MSG_SIZE) { fprintf(stderr, "read pipe error:%s/n", strerror(errno)); return -1; } #endif return 0; }