|
楼主 |
发表于 2013-5-8 18:16:53
|
显示全部楼层
本帖最后由 soloforce 于 2013-5-9 21:35 编辑
再发一个用GPIO控制LED显示当前CPU繁忙情况的小程序。
在GPIO的LD1~LD6接了3只LED,以二进制码形式显示CPU使用率。- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <string.h>
- #include <signal.h>
- /**
- * Here we use the GPIO expansion near the SATA connector, from PD1 ~ PD7
- * */
- #define MIN_PIN 1
- #define MAX_PIN 7
- /**
- * Binary value that GPIO pins could accept
- * */
- typedef enum{
- LOW=0,
- HIGH=1
- }value_t;
- /**
- * GPIO pins get/set direction
- * */
- typedef enum{
- IN=0,
- OUT=1
- }direction_t;
- typedef struct{
- long int user,nice,sys,idle,iowait,irq,softirq;
- }jiffies_t;
- /**
- * GPIO pin values' file pointers
- * */
- FILE* value_fp[MAX_PIN+1]={NULL};
- /**
- * Signal actions structures
- * */
- struct sigaction int_act,term_act, old_act;
- /**
- * @brief Signal INT handler
- * */
- void sigint_handler(int sig_num)
- {
- printf("Uninitialzing GPIO...\n");
- /* uninitialize the GPIO */
- gpio_uninit();
- /* change back to the original handler */
- sigaction(SIGINT, &old_act,NULL);
-
- /* emit the SIGINT again */
- kill(0,SIGINT);
- }
- /**
- * @brief Signal TERM handler
- * */
- void sigterm_handler(int sig_num)
- {
- printf("Uninitialzing GPIO...\n");
- /* uninitialize the GPIO */
- gpio_uninit();
- /* change back to the original handler */
- sigaction(SIGTERM, &old_act,NULL);
- /* emit the SIGTERM again */
- kill(0,SIGTERM);
- }
- /**
- * @brief Initialize signals
- * * */
- void catch_signal_init()
- {
- memset(&int_act,0,sizeof(int_act));
- memset(&term_act,0,sizeof(int_act));
- memset(&old_act,0,sizeof(old_act));
- int_act.sa_handler=&sigint_handler;
- term_act.sa_handler=&sigterm_handler;
- sigaction(SIGINT, &int_act, &old_act);
- sigaction(SIGTERM, &term_act, &old_act);
- }
- /**
- * @brief Initialize the GPIO ports' value file pointers
- *
- * */
- void gpio_init()
- {
- int i;
- for(i=MIN_PIN;i<=MAX_PIN;i++)
- value_fp[i]=NULL;
- pinMode(1,OUT);
- pinMode(2,OUT);
- pinMode(3,OUT);
- pinMode(4,OUT);
- pinMode(5,OUT);
- pinMode(6,OUT);
- }
- /**
- * @brief Uninitialize the GPIO ports, unexport those exported and close files.
- *
- * */
- int gpio_uninit()
- {
- int i;
- FILE *unexport_fp=fopen("/sys/class/gpio/unexport","w");
- if(!unexport_fp) return -1;
- for(i=MIN_PIN;i<=MAX_PIN;i++){
- if(value_fp[i]){
- fclose(value_fp[i]);
- fprintf(unexport_fp,"%d",i);
- fflush(unexport_fp);
- }
- }
- fclose(unexport_fp);
- return 0;
- }
- /**
- * @brief Set the GPIO pins to specified direction
- *
- * @param pin: GPIO pin to set direction
- * @param dir: IN or OUT
- *
- * */
- int pinMode(int pin, direction_t dir)
- {
- char direction_file[64];
- char value_file[64];
- FILE *export_fp=fopen("/sys/class/gpio/export","w");
- if(!export_fp) return -1;
-
- fprintf(export_fp,"%d",pin);
- sleep(1);
- fclose(export_fp);
- sprintf(direction_file,"/sys/class/gpio/gpio%d_pd%d/direction", pin, pin);
- FILE *direction_fp=fopen(direction_file,"w");
- if(!direction_fp) return -2;
- if(dir==OUT){
- fprintf(direction_fp,"out");
- }else fprintf(direction_fp,"in");
- fclose(direction_fp);
- sprintf(value_file,"/sys/class/gpio/gpio%d_pd%d/value", pin, pin);
- value_fp[pin]=fopen(value_file,"w");
- if(!value_fp[pin]) return -3;
- return 0;
- }
- /**
- * @brief Set the GPIO pins to specified binary value
- *
- * @param pin: GPIO pin to set value
- * @param value: LOW or HIGH
- *
- * */
- int digitalWrite(int pin, value_t value)
- {
- if(!value_fp[pin])return -1;
- if(pin<MIN_PIN) pin=MIN_PIN;
- if(pin>MAX_PIN) pin=MAX_PIN;
- fprintf(value_fp[pin],"%d", value);
- fflush(value_fp[pin]);
- return 0;
- }
- /**
- * @brief Get CPU jiffies from /proc/stat
- *
- * @param s(OUTPUT) Point of CPU jiffies structure
- *
- * */
- int get_jiffies(jiffies_t *s)
- {
- char buf[128]={0};
- char cpu[8]={0};
- if(!s) return -1;
- FILE* cpu_stat_fp = fopen("/proc/stat","r");
- if(cpu_stat_fp == NULL){
- return -1;
- }
- fgets(buf,sizeof(buf),cpu_stat_fp);
- sscanf(buf,"%s%d%d%d%d%d%d%d",cpu, &(s->user),&(s->nice),&(s->sys),&(s->idle),&(s->iowait),&(s->irq),&(s->softirq));
- fclose(cpu_stat_fp);
- return 0;
- }
- /**
- * @brief Get CPU usage
- *
- * @param usage(OUTPUT): CPU usage in a short time
- *
- * */
- int get_cpu_usage(float * usage)
- {
- jiffies_t j1,j2;
- float all1, all2;
- int status;
- if(!usage) return -1;
- status=get_jiffies(&j1);
- if(status) return -2;
- usleep(100000);
- status=get_jiffies(&j2);
- if(status) return -2;
-
- all1=j1.user+j1.nice+j1.sys+j1.idle+j1.iowait+j1.irq+j1.softirq;
- all2=j2.user+j2.nice+j2.sys+j2.idle+j2.iowait+j2.irq+j2.softirq;
- *usage=((all2-j2.idle)-(all1-j1.idle))/(all2-all1) ;
- return 0;
- }
- /**
- * @brief Show CPU usage to LEDs in binary-mode
- *
- * @param n(INPUT): CPU usage level, from 0~7
- *
- * */
- void show_cpu_usage(int n)
- {
- if(n & 0x04){
- digitalWrite(1,LOW);
- digitalWrite(2,HIGH);
- }else{
- digitalWrite(1,HIGH);
- digitalWrite(2,LOW);
- }
- if(n & 0x02){
- digitalWrite(3,LOW);
- digitalWrite(4,HIGH);
- }else{
- digitalWrite(3,HIGH);
- digitalWrite(4,LOW);
- }
- if(n & 0x01){
- digitalWrite(5,LOW);
- digitalWrite(6,HIGH);
- }else{
- digitalWrite(5,HIGH);
- digitalWrite(6,LOW);
- }
- }
- /**
- * @brief A daemon to show CPU usage through GPIO expansion
- * to flash a LED connected between the two pins. Press Ctrl+C to Quit.
- * */
- int main()
- {
- float usage;
- pid_t pid=fork();
-
- /* Create a daemon process, and terminate the parent process. */
- if(pid>0) exit(0);
- if(pid<0) {
- printf("Failed to create sub-process!\n");
- exit(-1);
- }
- setsid();
- catch_signal_init();
- gpio_init();
-
- while(1){
- if(get_cpu_usage(&usage)){
- printf("Failed to get CPU usage!\n");
- break;
- }
- int n=(int)(usage*8);
- if(n>7) n=7;
- show_cpu_usage(n);
- sleep(1);
- }
-
- }
复制代码 |
|