|
|
@@ -1,196 +1,178 @@
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <string.h>
|
|
|
+#include <fcntl.h>
|
|
|
#include <unistd.h>
|
|
|
+#include <errno.h>
|
|
|
#include <getopt.h>
|
|
|
-#include <sys/types.h>
|
|
|
-#include <sys/stat.h>
|
|
|
-#include <fcntl.h>
|
|
|
|
|
|
-//7-segment digital tube
|
|
|
-typedef struct {
|
|
|
- char *f_arg;
|
|
|
- int r_flag;
|
|
|
- int d_flag;
|
|
|
- char *str_arg;
|
|
|
-} Options;
|
|
|
-
|
|
|
-int flash_flag = 0;
|
|
|
-int read_flag = 0;
|
|
|
-int dp_flag = 0;
|
|
|
-long int display_value = 0;
|
|
|
-
|
|
|
-void print_usage(const char *program_name) {
|
|
|
- printf("Usage: %s [options] <string>\n", program_name);
|
|
|
- printf("Options:\n");
|
|
|
- printf(" -f <arg> Specify an argument for -f option\n");
|
|
|
- printf(" -r Enable r option (no argument)\n");
|
|
|
- printf(" -d Enable d option (no argument)\n");
|
|
|
- printf(" -h Show this help message\n");
|
|
|
- printf("\nExample:\n");
|
|
|
- printf(" %s -f config.txt -r -d hello\n", program_name);
|
|
|
- printf(" %s -r -f data.txt world\n", program_name);
|
|
|
-}
|
|
|
+#if defined(PROJECT) && (PROJECT == POS)
|
|
|
+#define DEVICE_PATH "/dev/leds"
|
|
|
+#else
|
|
|
+#define DEVICE_PATH "/dev/ssegment"
|
|
|
+#endif
|
|
|
|
|
|
-int parse_arguments(int argc, char *argv[], Options *opts) {
|
|
|
- int opt;
|
|
|
- int ret = 0;
|
|
|
- int f_option_count = 0;
|
|
|
-
|
|
|
- memset(opts, 0, sizeof(Options));
|
|
|
-
|
|
|
- while ((opt = getopt(argc, argv, "f:rdh")) != -1) {
|
|
|
- switch (opt) {
|
|
|
- case 'f':
|
|
|
- flash_flag = atoi(optarg);
|
|
|
- opts->f_arg = optarg;
|
|
|
- f_option_count++;
|
|
|
- printf("[DEBUG] -f option with argument: %s\n", optarg);
|
|
|
- break;
|
|
|
-
|
|
|
- case 'r':
|
|
|
- read_flag = 1;
|
|
|
- opts->r_flag = 1;
|
|
|
- printf("[DEBUG] -r option enabled\n");
|
|
|
- break;
|
|
|
-
|
|
|
- case 'd':
|
|
|
- dp_flag = 1;
|
|
|
- opts->d_flag = 1;
|
|
|
- printf("[DEBUG] -d option enabled\n");
|
|
|
- break;
|
|
|
-
|
|
|
- case 'h':
|
|
|
- print_usage(argv[0]);
|
|
|
- return 0;
|
|
|
-
|
|
|
- case '?':
|
|
|
- return -1;
|
|
|
-
|
|
|
- default:
|
|
|
- fprintf(stderr, "Unexpected option: %c\n", opt);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (f_option_count > 1) {
|
|
|
- fprintf(stderr, "Error: -f option can only be used once\n");
|
|
|
- return -1;
|
|
|
+
|
|
|
+int write_data_to_device(unsigned int data)
|
|
|
+{
|
|
|
+ int fd;
|
|
|
+ ssize_t ret;
|
|
|
+
|
|
|
+ // 打开设备
|
|
|
+ fd = open(DEVICE_PATH, O_WRONLY);
|
|
|
+ if (fd < 0)
|
|
|
+ {
|
|
|
+ return 1;
|
|
|
}
|
|
|
-
|
|
|
- if (optind < argc) {
|
|
|
- if (argc - optind > 1) {
|
|
|
- fprintf(stderr, "Warning: Extra arguments after string will be ignored\n");
|
|
|
- }
|
|
|
- opts->str_arg = argv[optind];
|
|
|
- char *endptr;
|
|
|
- display_value = strtol(opts->str_arg, &endptr, 16);
|
|
|
- if(*endptr != '\0')
|
|
|
- {
|
|
|
- printf("Error: Invalid string argument\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- printf("display_value=%lx\n", display_value);
|
|
|
- }
|
|
|
|
|
|
- printf("[DEBUG] String argument: %s\n", opts->str_arg);
|
|
|
- } else {
|
|
|
- fprintf(stderr, "Error: Missing required string argument\n");
|
|
|
- print_usage(argv[0]);
|
|
|
- return -1;
|
|
|
+ // 写入1字节
|
|
|
+ ret = write(fd, &data, sizeof(data));
|
|
|
+ if (ret < 0)
|
|
|
+ {
|
|
|
+ close(fd);
|
|
|
+ return 1;
|
|
|
}
|
|
|
-
|
|
|
- return 1;
|
|
|
+ close(fd);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
-void show_results(Options *opts) {
|
|
|
- printf("\n=== Parsing Results ===\n");
|
|
|
-
|
|
|
- if (opts->f_arg) {
|
|
|
- printf("-f option argument: %s\n", opts->f_arg);
|
|
|
- } else {
|
|
|
- printf("-f option not specified\n");
|
|
|
+int read_from_device(unsigned int *data)
|
|
|
+{
|
|
|
+ int fd;
|
|
|
+ unsigned char buffer[256];
|
|
|
+ ssize_t ret;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ fd = open(DEVICE_PATH, O_RDWR);
|
|
|
+ if (fd < 0)
|
|
|
+ {
|
|
|
+ return 1;
|
|
|
}
|
|
|
-
|
|
|
- printf("-r option: %s\n", opts->r_flag ? "enabled" : "disabled");
|
|
|
- printf("-d option: %s\n", opts->d_flag ? "enabled" : "disabled");
|
|
|
-
|
|
|
- if (opts->str_arg) {
|
|
|
- printf("String argument: %s\n", opts->str_arg);
|
|
|
+
|
|
|
+ ret = read(fd, data, sizeof(unsigned int));
|
|
|
+ if (ret < 0)
|
|
|
+ {
|
|
|
+ return 1;
|
|
|
}
|
|
|
-
|
|
|
- printf("======================\n");
|
|
|
+
|
|
|
+ close(fd);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
-int main(int argc, char *argv[]) {
|
|
|
- Options opts;
|
|
|
- int ret;
|
|
|
- unsigned int cmd = 0;
|
|
|
- int fd = 0;
|
|
|
-
|
|
|
- printf("Argument Parser Demo\n");
|
|
|
- printf("====================\n");
|
|
|
- printf("Total arguments: %d\n", argc);
|
|
|
-
|
|
|
-
|
|
|
- printf("Raw arguments:");
|
|
|
- for (int i = 0; i < argc; i++) {
|
|
|
- printf(" [%d]%s", i, argv[i]);
|
|
|
- }
|
|
|
- printf("\n\n");
|
|
|
-
|
|
|
- ret = parse_arguments(argc, argv, &opts);
|
|
|
-
|
|
|
- if (ret == 0) {
|
|
|
- return 0;
|
|
|
- } else if (ret < 0) {
|
|
|
- fprintf(stderr, "\nArgument parsing failed!\n");
|
|
|
+
|
|
|
+int main(int argc, char *argv[])
|
|
|
+{
|
|
|
+ int ret = 0;
|
|
|
+ int opt;
|
|
|
+ int flash_option = 0;
|
|
|
+ int flash_value = 0;
|
|
|
+ int decimal_point = 0;
|
|
|
+ int read_option = 0;
|
|
|
+ char *hex_arg = NULL;
|
|
|
+ unsigned char data;
|
|
|
+ unsigned int rw_data = 0;
|
|
|
+
|
|
|
+ // 如果没有参数,显示帮助
|
|
|
+ if (argc == 1)
|
|
|
+ {
|
|
|
return 1;
|
|
|
}
|
|
|
-
|
|
|
- show_results(&opts);
|
|
|
- fd = open("/dev/ssegment", O_RDWR);
|
|
|
- if(fd < 0)
|
|
|
+
|
|
|
+ // 解析命令行参数
|
|
|
+ optind = 1; // 重置 getopt
|
|
|
+ while ((opt = getopt(argc, argv, "f:dr")) != -1)
|
|
|
{
|
|
|
- printf("open led device failed\n");
|
|
|
- return -1;
|
|
|
+ switch (opt)
|
|
|
+ {
|
|
|
+ case 'f':
|
|
|
+ flash_option = 1;
|
|
|
+ flash_value = atoi(optarg);
|
|
|
+ if (flash_value <= 0)
|
|
|
+ {
|
|
|
+ fprintf(stderr, "错误: -f 参数必须是大于0的数字\n");
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'd':
|
|
|
+ decimal_point = 1;
|
|
|
+ break;
|
|
|
+ case 'r':
|
|
|
+ read_option = 1;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ printf("error\n");
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查 -r 选项的特殊规则
|
|
|
+ if (read_option)
|
|
|
+ {
|
|
|
+ rw_data = 0;
|
|
|
+ ret = read_from_device(&rw_data);
|
|
|
+ data = rw_data & 0xFF;
|
|
|
+ printf("The number displayed is %02x\n", data);
|
|
|
+ if(rw_data & (1<<9))
|
|
|
+ {
|
|
|
+ printf("The msb is ON\n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ printf("The msb is OFF\n");
|
|
|
+ }
|
|
|
+ if(rw_data & (1<<15))
|
|
|
+ {
|
|
|
+ printf("The flashing is ON\n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ printf("The flashing is OFF\n");
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
}
|
|
|
-
|
|
|
- cmd = 0;
|
|
|
- if(dp_flag == 1)
|
|
|
+
|
|
|
+ // 非 -r 选项,必须有最后的十六进制参数
|
|
|
+ if (optind >= argc)
|
|
|
{
|
|
|
- cmd = cmd | 0x0200;
|
|
|
+ fprintf(stderr, "error\n");
|
|
|
+ return 1;
|
|
|
}
|
|
|
- if(flash_flag == 1)
|
|
|
+
|
|
|
+ hex_arg = argv[optind];
|
|
|
+
|
|
|
+ // 解析十六进制参数 (支持 aa, bb, 12 等格式)
|
|
|
+ char *endptr;
|
|
|
+ long hex_value = strtol(hex_arg, &endptr, 16);
|
|
|
+
|
|
|
+ // 检查转换是否成功
|
|
|
+ if (*endptr != '\0' || endptr == hex_arg)
|
|
|
{
|
|
|
- cmd = cmd | 0x8000;
|
|
|
+ fprintf(stderr, "错误: 无效的十六进制参数 '%s'\n", hex_arg);
|
|
|
+ fprintf(stderr, "请使用类似 aa, bb, 12, 0x12 的格式\n");
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
- cmd = cmd | (display_value & 0xff);
|
|
|
- if(read_flag == 1)
|
|
|
+ // 检查范围 (0-255)
|
|
|
+ if (hex_value < 0 || hex_value > 255)
|
|
|
{
|
|
|
- cmd = 0;
|
|
|
- ret = read(fd, &cmd, 4);
|
|
|
- if(ret < 0)
|
|
|
- {
|
|
|
- printf("read led device failed\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
- printf("read led device success, cmd=%x\n", cmd);
|
|
|
+ fprintf(stderr, "错误: 十六进制值必须在 0x00-0xFF 之间 (当前: 0x%lX)\n", hex_value);
|
|
|
+ return 1;
|
|
|
}
|
|
|
- else
|
|
|
+
|
|
|
+ data = (unsigned char)hex_value;
|
|
|
+
|
|
|
+
|
|
|
+ if (flash_value == 1)
|
|
|
{
|
|
|
- ret = write(fd, &cmd, 4);
|
|
|
- if(ret < 0)
|
|
|
- {
|
|
|
- printf("write led device failed\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
+ rw_data |= 1 << 15;
|
|
|
}
|
|
|
|
|
|
+ if (decimal_point == 1)
|
|
|
+ {
|
|
|
+ rw_data |= 1 << 9;
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
+ rw_data |= data;
|
|
|
+ ret = write_data_to_device(rw_data);
|
|
|
return 0;
|
|
|
-}
|
|
|
+}
|