控制台命令方式操作设备驱动程序

本文介绍了一款用于控制设备背光亮度的程序实现细节。通过读取和设置/sys/class/backlight目录下的实际亮度和最大亮度值,程序能够动态调整背光强度,包括获取当前亮度、设置最大亮度以及执行循环渐变效果。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <getopt.h>
#include <stdbool.h>
#include <libgen.h>
#include <signal.h>

#define INADEQUATE_CONDITIONS 3

#define CMD_SIZE 80
#define BUF_SIZE 20

#define BACKLIGHT_DEV "/sys/class/backlight/backlight"
//该程序提供了另一种自带驱动的方式
enum Type { ACTUAL, MAX };

/* Exit flag */
volatile bool g_quit = false;

/* Short option names */
static const char g_shortopts [] = ":vh";

/* Option names */
static const struct option g_longopts [] = {
    { "version",     no_argument,            NULL,        'v' },
    { "help",        no_argument,            NULL,        'h' },
    { 0, 0, 0, 0 }
};

static void usage(FILE *fp, int argc, char **argv) {
    fprintf(fp,
            "Usage: %s [options]\n\n"
            "Options:\n"
            " -v | --version       Display version information\n"
            " -h | --help          Show help content\n\n"
            "", basename(argv[0]));
}

static void opt_parsing_err_handle(int argc, char **argv, int flag) {
    /* Exit if no input parameters are entered  */
    int state = 0;
    /* Feedback Error parameter information then exit */
    if (optind < argc || flag) {
        printf("Error:  Parameter parsing failed\n");
        if (flag)
            printf("\tunrecognized option '%s'\n", argv[optind-1]);

        while (optind < argc) {
            printf("\tunrecognized option '%s'\n", argv[optind++]);
        }
            
        state = -1;
    }

    if (state == -1) {
        printf("Tips: '-h' or '--help' to get help\n\n");
        exit(2);
    }
}

void sig_handle(int arg) {
    g_quit = true;
}


static int get_backlight(int type) {
    FILE *fp;
    char cmd[CMD_SIZE];
    char buf[BUF_SIZE];

    switch (type) {
    case ACTUAL:
        snprintf(cmd, CMD_SIZE, "cat %s/actual_brightness", BACKLIGHT_DEV);
        break;
    case MAX:
        snprintf(cmd, CMD_SIZE, "cat %s/max_brightness", BACKLIGHT_DEV);
        break;
    default:
        return -1;
        break;
    }

    fp = popen(cmd, "r");  //注意该函数同fork效果类似 ,Windows不支持 ,以子进程的方式打开,通常该函数调用的都是控制台命令字符串!
    //这里判断一下fp==NULL 抛出异常
    fgets(buf, sizeof(buf), fp); //从文件读一行字符到buf ,#include <stdio.h>
    //这里判断一下fgets返回值==NULL 抛出异常
    pclose (fp);
    return atoi(buf);
}
/***************************************************
函数原型:int snprintf(char* dest_str,size_t size,const char* format,...);
所需头文件:#include<stdio.h>
函数功能:先将可变参数 “…” 按照format的格式格式化为字符串,然后再将其拷贝至dest_str中。
注意事项:如果格式化后的字符串长度小于size,则将字符串全部拷贝至dest_str中,并在字符串结尾处加上‘\0’; 
如果格式化后的字符串长度大于或等于size,则将字符串的(size-1)拷贝至dest_str中,然后在字符串结尾处加上’\0’. 
函数返回值是 格式化字符串的长度。
 ***************************************************/
int set_brightness(int value) {
    char cmd[CMD_SIZE];
    
    snprintf(cmd, CMD_SIZE, "echo %d > %s/brightness", value, BACKLIGHT_DEV);
    if ((system(cmd)) != 0) //执行系统命令,等同控制台直接输入
        return -1;

    return 0;
}

int main(int argc, char **argv) {
    int c = 0;
    int flag = 0;
    int actual_value = -1;
    int max_value = -1;

    /* Parsing input parameters */
    while ((c = getopt_long(argc, argv, g_shortopts, g_longopts, NULL)) != -1) {
        switch (c) {
        case 'v':
            /* Display the version */
            printf("version : 1.0\n");
            exit(0);

        case 'h':
            usage(stdout, argc, argv);
            exit(0);

        default :
            flag = 1;
            break;
        }
    }

    opt_parsing_err_handle(argc, argv, flag);

    /* Ctrl+c handler */
    signal(SIGINT, sig_handle);

    actual_value = get_backlight(ACTUAL);
    if (actual_value < 0) {
        printf("Error: Get actual brightness value error\n");
        return INADEQUATE_CONDITIONS;
    }
    printf("Actual backlight is:%d\n", actual_value);

    max_value = get_backlight(MAX);
    if (max_value < 0) {
        printf("Error: Get max brightness value error\n");
        return INADEQUATE_CONDITIONS;
    }
    printf("Max backlight is:%d\n", max_value);

    /* loop to brighten backlight */
    while (!g_quit) {
        /* brighten backlight */
        set_brightness(max_value);
        usleep(1000000);

        set_brightness(max_value * 0.8);
        usleep(250000);

        set_brightness(max_value * 0.6);
        usleep(250000);

        set_brightness(max_value * 0.4);
        usleep(250000);

        set_brightness(max_value * 0.2);
        usleep(250000);

        set_brightness(0);
        usleep(250000);
    }

    /* get back to actual backlight */
    set_brightness(actual_value);

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值