Bläddra i källkod

Change Chinese to English

liu qidong [url ssh://qidong.liu@10.2.90.253:29418/] 1 vecka sedan
förälder
incheckning
e440f6a993
23 ändrade filer med 529 tillägg och 530 borttagningar
  1. 4 0
      .vscode/settings.json
  2. 1 1
      Makefile
  3. 6 7
      backlight.c
  4. 11 12
      batteryled.c
  5. 6 29
      buzzer.c
  6. 0 35
      cash_drawers.c
  7. 1 3
      ec_version.c
  8. 0 2
      fan.c
  9. 303 0
      fan.c_ybak
  10. 3 34
      lcd_2x20.c
  11. 0 2
      led.c
  12. 18 56
      light_ring.c
  13. 0 1
      main.c
  14. 4 32
      myname.c
  15. 6 30
      power.c
  16. 2 32
      ssegment.c
  17. 4 24
      switches.c
  18. 13 13
      test_app/lcd_app.c
  19. 0 7
      test_app/power_app.c
  20. 11 27
      test_app/setss.c
  21. 36 51
      test_app/test_ssegment.c
  22. 98 106
      test_app/watchdog_app.c
  23. 2 26
      writeprotect.c

+ 4 - 0
.vscode/settings.json

@@ -0,0 +1,4 @@
+{
+    "commentTranslate.source": "Bing",
+    "commentTranslate.targetLanguage": "en"
+}

+ 1 - 1
Makefile

@@ -1,6 +1,6 @@
 CROSS_COMPILE=arm-poky-linux-gnueabi-  
  
-#也可以同时编译多个模块  obj-m += export_symbol.o export_symbol1.o export_symbol2.o
+
 obj-m := coral.o
 
 coral-objs := main.o led.o light_ring.o ssegment.o ec_version.o buzzer.o fan.o writeprotect.o myname.o cash_drawers.o batteryled.o watchdog.o power.o switches.o backlight.o gsensor.o lcd_2x20.o

+ 6 - 7
backlight.c

@@ -26,7 +26,7 @@ static int max_brightness_val = 1;
 #define BACKLIGHT_PATH "/sys/class/backlight/intel_backlight/brightness"
 
 
-// 从sysfs读取当前亮度值
+// Read the current brightness value from sysfs
 static int read_current_brightness(void)
 {
     struct file *filp = NULL;
@@ -73,7 +73,7 @@ static int read_max_brightness(void)
     return max_brightness;
 }
 
-// 向sysfs写入亮度值
+// Write brightness value to sysfs
 static int write_brightness_value(int value)
 {
     struct file *filp = NULL;
@@ -82,7 +82,7 @@ static int write_brightness_value(int value)
     int ret = -EIO;
     int max_brightness;
     
-    // 先读取最大值进行边界检查
+    // First read the maximum value for boundary checking
     filp = filp_open("/sys/class/backlight/intel_backlight/max_brightness", O_RDONLY, 0);
     if (!IS_ERR(filp)) {
         char max_buf[32] = {0};
@@ -97,7 +97,7 @@ static int write_brightness_value(int value)
         filp_close(filp, NULL);
     }
     
-    // 写入亮度值
+    // Write brightness value
     filp = filp_open(BACKLIGHT_PATH, O_WRONLY, 0);
     if (IS_ERR(filp)) {
         pr_err("Failed to open backlight file for write: %ld\n", PTR_ERR(filp));
@@ -153,7 +153,6 @@ static ssize_t brightness_store(struct kobject *kobj, struct kobj_attribute *att
 static struct kobj_attribute brightness =
     __ATTR(brightness, 0644, brightness_show, brightness_store);
 
-/* ==================== 属性组 ==================== */
 static struct attribute *backlight_attrs[] = {
     &brightness.attr,
     NULL,
@@ -177,14 +176,14 @@ int backlight_init(void)
     }
 
     brightness_val = read_current_brightness();
-        /* 创建 /sys/kernel/vfiec/lightring */
+        /* Create /sys/kernel/vfiec/lightring */
     backlight_kobj = kobject_create_and_add("backlight", vfiec_kobj);
     if (!backlight_kobj)
     {
         ret = -ENOMEM;
     }
 
-    /* 创建属性文件 */
+    /* Create property file */
     ret = sysfs_create_group(backlight_kobj, &backlight_attr_group);
     if (ret)
     {

+ 11 - 12
batteryled.c

@@ -24,7 +24,7 @@
 
 // blue is charge
 // white is health
-// 因为我们的LED没有蓝色和白色。只有红色和绿色。所以用红色表示充电,绿色表示健康
+// Because our LED does not have blue and white. Only red and green. So use red to indicate charging, green to indicate healthy.
 enum battery_led_color
 {
  BATTERY_LED_OFF = 0x00,
@@ -267,7 +267,6 @@ static ssize_t led_charge_store(struct kobject *kobj, struct kobj_attribute *att
 static struct kobj_attribute led_charge =
     __ATTR(led_charge, 0644, led_charge_show, led_charge_store);
 
-/* ==================== 属性组 ==================== */
 static struct attribute *batteryled_attrs[] = {
     &led_charge.attr,
     &led_health.attr,
@@ -285,19 +284,19 @@ static void delay_work_func(struct work_struct *work)
 
     if(blink_flag == 0)
     {
-        //闪烁的时候灭
+        //Turn off when flickering
         blink_flag = 1;
         if(led_health_val == 0x0)
         {
-            data = data & 0xf3;//灭
+            data = data & 0xf3;
         }
         else if(led_health_val == 0x1)
         {
-            data = data | 0x04;//亮
+            data = data | 0x04;
         }
         else if(led_health_val == 0x3)
         {
-            data = data & 0xf3;//灭
+            data = data & 0xf3;
         }
         
         if(led_charge_val == 0x0)
@@ -316,19 +315,19 @@ static void delay_work_func(struct work_struct *work)
     }
     else if(blink_flag == 1)
     {
-        // 闪烁的时候亮
+        // Bright when flashing
         blink_flag = 0;
         if(led_health_val == 0x0)
         {
-            data = data & 0xf3;//灭
+            data = data & 0xf3;
         }
         else if(led_health_val == 0x1)
         {
-            data = data | 0x04;//亮
+            data = data | 0x04;
         }
         else if(led_health_val == 0x3)
         {
-            data = data | 0x04;//亮
+            data = data | 0x04;
         }
         
         if(led_charge_val == 0x0)
@@ -354,7 +353,7 @@ int batteryled_init(void)
     int ret;
     INIT_DELAYED_WORK(&delay_work1, delay_work_func);
 
-        /* 创建 /sys/kernel/vfiec/batteryled */
+        /* Create /sys/kernel/vfiec/batteryled */
     batteryled_kobj = kobject_create_and_add("batteryled", vfiec_kobj);
     if (!batteryled_kobj)
     {
@@ -362,7 +361,7 @@ int batteryled_init(void)
         return ret;
     }
 
-    /* 创建属性文件 */
+    /* Create property file */
     ret = sysfs_create_group(batteryled_kobj, &batteryled_attr_group);
     if (ret)
     {

+ 6 - 29
buzzer.c

@@ -21,9 +21,9 @@
 
 #define note(x) ((119318200+(x)/2)/(x))
 
-// 可以通过模块参数指定主设备号和次设备号
-static int buzzer_major = 56; // 默认主设备号
-static int buzzer_minor = 100;   // 默认次设备号
+// You can specify the major device number and minor device number through module parameters
+static int buzzer_major = 56; // Default main device number
+static int buzzer_minor = 100;   // Default sub-device number
 module_param(buzzer_major, int, S_IRUGO);
 module_param(buzzer_minor, int, S_IRUGO);
 MODULE_PARM_DESC(buzzer_major, "Major device number");
@@ -34,7 +34,7 @@ static struct device *char_device = NULL;
 static struct cdev my_cdev;
 static dev_t dev_num;
 
-// 设备结构体
+
 struct buzzer_dev
 {
     char *buffer;
@@ -84,12 +84,11 @@ static void delay_work_func(struct work_struct *work)
         printk(KERN_INFO "buzzer: size < 4\n");
         return;
     }
-    // 关闭buzzer
+    // Close buzzer
     BeepOff();
     printk(KERN_INFO "delay_work_func\n");
 }
 
-// 文件打开操作
 static int buzzer_open(struct inode *inode, struct file *filp)
 {
     struct buzzer_dev *dev;
@@ -108,7 +107,6 @@ static int buzzer_open(struct inode *inode, struct file *filp)
     return 0;
 }
 
-// 文件释放操作
 static int buzzer_release(struct inode *inode, struct file *filp)
 {
     // release_region(PORT_80, 1);
@@ -116,7 +114,6 @@ static int buzzer_release(struct inode *inode, struct file *filp)
     return 0;
 }
 
-// 读操作 - 支持cat命令
 static ssize_t buzzer_read(struct file *filp, char __user *buf,
                              size_t count, loff_t *f_pos)
 {
@@ -129,7 +126,7 @@ static ssize_t buzzer_read(struct file *filp, char __user *buf,
     if (mutex_lock_interruptible(&dev->lock))
         return -ERESTARTSYS;
 
-    // 这里read_count没有固定为4个字节,是为了便于后续扩展
+    // The read count here is not fixed at 4 bytes, in order to facilitate future expansion.
     if (count > dev->size)
     {
         read_count = dev->size;
@@ -152,7 +149,6 @@ out:
     return ret;
 }
 
-// 写操作
 static ssize_t buzzer_write(struct file *filp, const char __user *buf,
                               size_t count, loff_t *f_pos)
 {
@@ -164,13 +160,11 @@ static ssize_t buzzer_write(struct file *filp, const char __user *buf,
     int freq = 0;
     int duration = 0;    
 
-    // 加锁
     if (mutex_lock_interruptible(&dev->lock))
     {
         return -ERESTARTSYS;
     }
 
-    // 计算可写数据量
     if (count > BUFFER_SIZE)
     {
         count = BUFFER_SIZE;
@@ -183,7 +177,6 @@ static ssize_t buzzer_write(struct file *filp, const char __user *buf,
         goto out;
     }
 
-    // 拷贝数据
     ret = copy_from_user(dev->buffer, buf, count);
     if (ret != 0)
     {
@@ -193,12 +186,10 @@ static ssize_t buzzer_write(struct file *filp, const char __user *buf,
 
     dev->size = count;
 
-    // 解析数据
     status_flag = dev->buffer[0];
     freq = dev->buffer[2]<<8 + dev->buffer[1];
     duration = dev->buffer[3];
 
-    // 打开buzzer
     if(status_flag == 1)
     {
         BeepOn(freq);
@@ -213,7 +204,6 @@ static ssize_t buzzer_write(struct file *filp, const char __user *buf,
 out:
     mutex_unlock(&dev->lock);
 
-    // 让buzzer工作duration秒
     if (ret == 0)
     {
         schedule_delayed_work(&dev->delay_work1, msecs_to_jiffies(duration*1000));
@@ -221,7 +211,6 @@ out:
     return count;
 }
 
-// 文件操作结构体
 static struct file_operations fops = {
     .owner = THIS_MODULE,
     .open = buzzer_open,
@@ -230,7 +219,6 @@ static struct file_operations fops = {
     .write = buzzer_write,
 };
 
-// 模块初始化
 int buzzer_init(void)
 {
     int result;
@@ -238,17 +226,14 @@ int buzzer_init(void)
     printk(KERN_INFO "buzzer: Initializing driver with major=%d, minor=%d\n",
            buzzer_major, buzzer_minor);
 
-    // 检查主设备号是否有效
     if (buzzer_major <= 0)
     {
         printk(KERN_ALERT "buzzer: Invalid major number %d\n", buzzer_major);
         return -EINVAL;
     }
 
-    // 构建设备号
     dev_num = MKDEV(buzzer_major, buzzer_minor);
 
-    // 注册设备号 - 使用指定的主设备号
     result = register_chrdev_region(dev_num, 1, DEVICE_NAME);
     if (result < 0)
     {
@@ -260,7 +245,6 @@ int buzzer_init(void)
     printk(KERN_INFO "buzzer: Registered with major=%d, minor=%d\n",
            MAJOR(dev_num), MINOR(dev_num));
 
-    // 分配设备结构体
     dev = kmalloc(sizeof(struct buzzer_dev), GFP_KERNEL);
     if (!dev)
     {
@@ -269,7 +253,6 @@ int buzzer_init(void)
     }
     memset(dev, 0, sizeof(struct buzzer_dev));
 
-    // 分配缓冲区
     dev->buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
     if (!dev->buffer)
     {
@@ -277,16 +260,13 @@ int buzzer_init(void)
         goto fail_buffer;
     }
 
-    // 初始化互斥锁
     mutex_init(&dev->lock);
 
     INIT_DELAYED_WORK(&dev->delay_work1, delay_work_func);
 
-    // 初始化字符设备
     cdev_init(&dev->cdev, &fops);
     dev->cdev.owner = THIS_MODULE;
 
-    // 添加字符设备到系统
     result = cdev_add(&dev->cdev, dev_num, 1);
     if (result)
     {
@@ -294,7 +274,6 @@ int buzzer_init(void)
         goto fail_cdev;
     }
 
-    // 创建设备类
     char_class = class_create(THIS_MODULE, CLASS_NAME);
     if (IS_ERR(char_class))
     {
@@ -303,7 +282,6 @@ int buzzer_init(void)
         goto fail_class;
     }
 
-    // 创建设备
     char_device = device_create(char_class, NULL, dev_num, NULL, DEVICE_NAME);
     if (IS_ERR(char_device))
     {
@@ -330,7 +308,6 @@ fail_malloc:
     return result;
 }
 
-// 模块退出
 void buzzer_exit(void)
 {
     cancel_delayed_work_sync(&dev->delay_work1);

+ 0 - 35
cash_drawers.c

@@ -1,4 +1,3 @@
-// cashd.c - 双节点字符设备驱动
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
@@ -25,7 +24,6 @@
 #define GPIO1_CTL 0xFD6D0B60
 #define GPIO1_STATUS 0xFD6D0950
 
-// 每个设备节点的私有数据结构
 struct cashd_device {
     unsigned char *buffer;
     size_t data_size;
@@ -46,7 +44,6 @@ static int cashd_major = 0;
 static struct class *cashd_class = NULL;
 static struct cashd_device *cashd_devices[MINOR_COUNT];
 
-// 文件打开操作
 static int cashd_open(struct inode *inode, struct file *filp)
 {
     struct cashd_device *dev;
@@ -63,14 +60,12 @@ static int cashd_open(struct inode *inode, struct file *filp)
         return -ENODEV;
     }
     
-    // 将私有数据保存在file结构中
     filp->private_data = dev;
     pr_info("cashd: Device /dev/cashd%d opened\n", minor);
     
     return 0;
 }
 
-// 文件释放操作
 static int cashd_release(struct inode *inode, struct file *filp)
 {
     unsigned int minor = iminor(inode);
@@ -78,7 +73,6 @@ static int cashd_release(struct inode *inode, struct file *filp)
     return 0;
 }
 
-// 读操作
 static ssize_t cashd_read(struct file *filp, char __user *buf, 
                           size_t count, loff_t *f_pos)
 {
@@ -127,7 +121,6 @@ static ssize_t cashd_read(struct file *filp, char __user *buf,
     return bytes_read;
 }
 
-// 写操作
 static ssize_t cashd_write(struct file *filp, const char __user *buf,
                            size_t count, loff_t *f_pos)
 {
@@ -167,7 +160,6 @@ static ssize_t cashd_write(struct file *filp, const char __user *buf,
     return count;
 }
 
-// poll操作 - 支持select/poll/epoll
 static unsigned int cashd_poll(struct file *filp, poll_table *wait)
 {
     struct cashd_device *dev = filp->private_data;
@@ -176,17 +168,14 @@ static unsigned int cashd_poll(struct file *filp, poll_table *wait)
     if (!dev)
         return POLLERR;
     
-    // 添加等待队列
     poll_wait(filp, &dev->read_wait, wait);
     // poll_wait(filp, &dev->write_wait, wait);
     
     mutex_lock(&dev->lock);
     
-    // 可读条件:缓冲区有数据
     if (dev->data_size > 0)
         mask |= POLLIN | POLLRDNORM;
     
-    // // 可写条件:缓冲区有空间
     // if (dev->data_size < dev->buffer_size)
     //     mask |= POLLOUT | POLLWRNORM;
     
@@ -195,7 +184,6 @@ static unsigned int cashd_poll(struct file *filp, poll_table *wait)
     return mask;
 }
 
-// 文件操作结构体
 static const struct file_operations cashd_fops = {
     .owner = THIS_MODULE,
     .open = cashd_open,
@@ -205,19 +193,16 @@ static const struct file_operations cashd_fops = {
     // .poll = cashd_poll,
 };
 
-// 初始化设备
 static int __init cashd_init_device(struct cashd_device *dev, int minor)
 {
     int ret;
     
-    // 分配缓冲区
     dev->buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
     if (!dev->buffer) {
         pr_err("cashd: Failed to allocate buffer for minor %d\n", minor);
         return -ENOMEM;
     }
     
-    // 初始化字段
     memset(dev->buffer, 0, BUFFER_SIZE);
     dev->data_size = 0;
     dev->buffer_size = BUFFER_SIZE;
@@ -226,18 +211,14 @@ static int __init cashd_init_device(struct cashd_device *dev, int minor)
     dev->can_read = false;
     dev->can_write = true;
     
-    // 初始化等待队列
     init_waitqueue_head(&dev->read_wait);
     init_waitqueue_head(&dev->write_wait);
     
-    // 初始化互斥锁
     mutex_init(&dev->lock);
     
-    // 初始化cdev
     cdev_init(&dev->cdev, &cashd_fops);
     dev->cdev.owner = THIS_MODULE;
     
-    // 添加字符设备到系统
     ret = cdev_add(&dev->cdev, MKDEV(cashd_major, minor), 1);
     if (ret) {
         pr_err("cashd: Failed to add cdev for minor %d\n", minor);
@@ -248,7 +229,6 @@ static int __init cashd_init_device(struct cashd_device *dev, int minor)
     return 0;
 }
 
-// 模块初始化
 int cashd_init(void)
 {
     int ret;
@@ -258,7 +238,6 @@ int cashd_init(void)
     
     pr_info("cashd: Initializing driver\n");
     
-    // 动态分配主设备号
     ret = alloc_chrdev_region(&dev_num, MINOR_BASE, MINOR_COUNT, DEVICE_NAME);
     if (ret < 0) {
         pr_err("cashd: Failed to allocate device numbers\n");
@@ -268,7 +247,6 @@ int cashd_init(void)
     cashd_major = MAJOR(dev_num);
     pr_info("cashd: Allocated major number %d\n", cashd_major);
     
-    // 创建设备类
     cashd_class = class_create(THIS_MODULE, CLASS_NAME);
     if (IS_ERR(cashd_class)) {
         ret = PTR_ERR(cashd_class);
@@ -276,9 +254,7 @@ int cashd_init(void)
         goto fail_class;
     }
     
-    // 为每个次设备号创建设备
     for (i = 0; i < MINOR_COUNT; i++) {
-        // 分配设备结构体
         cashd_devices[i] = kzalloc(sizeof(struct cashd_device), GFP_KERNEL);
         if (!cashd_devices[i]) {
             pr_err("cashd: Failed to allocate device for minor %d\n", i);
@@ -286,7 +262,6 @@ int cashd_init(void)
             goto fail_devices;
         }
         
-        // 初始化设备
         ret = cashd_init_device(cashd_devices[i], i);
         if (ret) {
             pr_err("cashd: Failed to init device for minor %d\n", i);
@@ -295,7 +270,6 @@ int cashd_init(void)
             goto fail_devices;
         }
         
-        // 创建设备节点
         device = device_create(cashd_class, NULL, 
                                MKDEV(cashd_major, i), NULL,
                                "cashd%d", i);
@@ -315,7 +289,6 @@ int cashd_init(void)
     return 0;
 
 fail_devices:
-    // 清理已初始化的设备
     for (i = 0; i < MINOR_COUNT; i++) {
         if (cashd_devices[i]) {
             device_destroy(cashd_class, MKDEV(cashd_major, i));
@@ -332,38 +305,30 @@ fail_class:
     return ret;
 }
 
-// 模块清理
 void cashd_exit(void)
 {
     int i;
     
     pr_info("cashd: Cleaning up driver\n");
     
-    // 销毁设备和释放资源
     for (i = 0; i < MINOR_COUNT; i++) {
         if (cashd_devices[i]) {
-            // 销毁设备节点
             device_destroy(cashd_class, MKDEV(cashd_major, i));
             
-            // 删除字符设备
             cdev_del(&cashd_devices[i]->cdev);
             
-            // 释放缓冲区
             if (cashd_devices[i]->buffer)
                 kfree(cashd_devices[i]->buffer);
             
-            // 释放设备结构体
             kfree(cashd_devices[i]);
             
             pr_info("cashd: Removed /dev/cashd%d\n", i);
         }
     }
     
-    // 销毁设备类
     if (cashd_class)
         class_destroy(cashd_class);
     
-    // 注销设备号
     unregister_chrdev_region(MKDEV(cashd_major, MINOR_BASE), MINOR_COUNT);
     
     pr_info("cashd: Driver cleaned up\n");

+ 1 - 3
ec_version.c

@@ -103,7 +103,7 @@ static ssize_t fw_version_show(struct kobject *kobj, struct kobj_attribute *attr
     {
         oem_ec_read_ram(2, i, &data[i]);
     }
-    // 这里待完善,获取真实的,版本号
+    // This needs to be completed here, obtain the real version number
     sprintf(buf, "%02x%02x%02x%02x", data[0], data[1], data[2], data[3]);
 
     return 8;
@@ -119,7 +119,6 @@ static ssize_t fw_version_store(struct kobject *kobj, struct kobj_attribute *att
 static struct kobj_attribute ec_version_attr =
     __ATTR(fw_version, 0444, fw_version_show, fw_version_store);
 
-/* ==================== 属性组 ==================== */
 static struct attribute *ec_version_attrs[] = {
     &ec_version_attr.attr,
     NULL,
@@ -133,7 +132,6 @@ int ec_version_init(void)
 {
     int ret = 0;
 
-    /* 创建属性文件 */
     ret = sysfs_create_group(vfiec_kobj, &ec_version_attr_group);
     if (ret)
     {

+ 0 - 2
fan.c

@@ -4224,7 +4224,6 @@ static struct kobj_attribute pwm2_enable =
 
 
 
-/* ==================== 属性组 ==================== */
 static struct attribute *fan_attrs[] = {
     &fan1_input.attr,
     &fan2_input.attr,
@@ -4300,7 +4299,6 @@ int fan_init(void)
         printk(KERN_INFO "Faifan to create sysfs node\n");
     }
 
-    /* 创建属性文件 */
     err = sysfs_create_group(fan_kobj, &fan_attr_group);
     if (err)
     {

+ 303 - 0
fan.c_ybak

@@ -0,0 +1,303 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/i2c.h>
+#include <linux/acpi.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include "light_ring.h"
+
+#define DEVICE_NAME "fan"
+#define CLASS_NAME "fan_class"
+#define DRIVER_NAME "fan_driver"
+
+struct fan_dev
+{
+    struct cdev cdev;
+    dev_t devt;
+    struct class *class;
+    struct device *device;
+};
+
+extern struct kobject *vfiec_kobj;
+static struct kobject *fan_kobj = NULL;
+static int major = 0; // 主设备号(0表示动态分配)
+static struct fan_dev *fan_dev_device = NULL;
+static dev_t dev_num;
+
+// 文件打开
+static int fan_open(struct inode *inode, struct file *filp)
+{
+    // 从inode获取cdev,再获取包含cdev的结构体
+    struct fan_dev *dev = container_of(inode->i_cdev, struct fan_dev, cdev);
+    filp->private_data = dev; // 保存到file结构供其他函数使用
+
+    printk(KERN_INFO "fan: device opened\n");
+    return 0;
+}
+
+// 文件释放
+static int fan_release(struct inode *inode, struct file *filp)
+{
+    printk(KERN_INFO "fan: device closed\n");
+    return 0;
+}
+
+// 读操作
+static ssize_t fan_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+    struct fan_dev *dev = filp->private_data;
+    return count;
+}
+
+// 写操作
+static ssize_t fan_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
+{
+    struct fan_dev *dev = filp->private_data;
+
+    printk(KERN_INFO "fan: wrote %zu bytes\n", count);
+    return count;
+}
+
+// 文件操作结构体
+static struct file_operations fan_fops = {
+    .owner = THIS_MODULE,
+    .open = fan_open,
+    .release = fan_release,
+    .read = fan_read,
+    .write = fan_write,
+};
+
+static ssize_t fan1_input_show(struct kobject *kobj, struct kobj_attribute *attr,
+                               char *buf)
+{
+    static int count = 0;
+    count++;
+
+    return sprintf(buf, "fan1_input_show count=%d\n", count);
+}
+
+static ssize_t fan1_input_store(struct kobject *kobj, struct kobj_attribute *attr,
+                                const char *buf, size_t count)
+{
+    printk("fan1_input_store kernel rev:%s\n", buf);
+    return count;
+}
+
+static ssize_t fan2_input_show(struct kobject *kobj, struct kobj_attribute *attr,
+                               char *buf)
+{
+    static int count = 0;
+    count++;
+
+    return sprintf(buf, "fan2_input_show count=%d\n", count);
+}
+
+static ssize_t fan2_input_store(struct kobject *kobj, struct kobj_attribute *attr,
+                                const char *buf, size_t count)
+{
+    printk("fan2_input_store kernel rev:%s\n", buf);
+    return count;
+}
+
+static ssize_t pwm1_show(struct kobject *kobj, struct kobj_attribute *attr,
+                         char *buf)
+{
+    static int count = 0;
+    count++;
+
+    return sprintf(buf, "pwm1_show count=%d\n", count);
+}
+
+static ssize_t pwm1_store(struct kobject *kobj, struct kobj_attribute *attr,
+                          const char *buf, size_t count)
+{
+    printk("pwm1_store kernel rev:%s\n", buf);
+    return count;
+}
+
+static ssize_t pwm1_enable_show(struct kobject *kobj, struct kobj_attribute *attr,
+                                char *buf)
+{
+    static int count = 0;
+    count++;
+
+    return sprintf(buf, "pwm1_enable_show count=%d\n", count);
+}
+
+static ssize_t pwm1_enable_store(struct kobject *kobj, struct kobj_attribute *attr,
+                                 const char *buf, size_t count)
+{
+    printk("pwm1_enable_store kernel rev:%s\n", buf);
+    return count;
+}
+
+static ssize_t pwm2_show(struct kobject *kobj, struct kobj_attribute *attr,
+                         char *buf)
+{
+    static int count = 0;
+    count++;
+
+    return sprintf(buf, "pwm2_show count=%d\n", count);
+}
+
+static ssize_t pwm2_store(struct kobject *kobj, struct kobj_attribute *attr,
+                          const char *buf, size_t count)
+{
+    printk("pwm2_store kernel rev:%s\n", buf);
+    return count;
+}
+
+static ssize_t pwm2_enable_show(struct kobject *kobj, struct kobj_attribute *attr,
+                                char *buf)
+{
+    static int count = 0;
+    count++;
+
+    return sprintf(buf, "pwm2_enable_show count=%d\n", count);
+}
+
+static ssize_t pwm2_enable_store(struct kobject *kobj, struct kobj_attribute *attr,
+                                 const char *buf, size_t count)
+{
+    printk("pwm2_enable_store kernel rev:%s\n", buf);
+    return count;
+}
+
+static struct kobj_attribute fan1_input =
+    __ATTR(fan1_input, 0644, fan1_input_show, fan1_input_store);
+
+static struct kobj_attribute fan2_input =
+    __ATTR(fan2_input, 0644, fan2_input_show, fan2_input_store);
+
+static struct kobj_attribute pwm1 =
+    __ATTR(pwm1, 0644, pwm1_show, pwm1_store);
+
+static struct kobj_attribute pwm1_enable =
+    __ATTR(pwm1_enable, 0644, pwm1_enable_show, pwm1_enable_store);
+
+static struct kobj_attribute pwm2 =
+    __ATTR(pwm2, 0644, pwm2_show, pwm2_store);
+
+static struct kobj_attribute pwm2_enable =
+    __ATTR(pwm2_enable, 0644, pwm2_enable_show, pwm2_enable_store);
+
+/* ==================== 属性组 ==================== */
+static struct attribute *fan_attrs[] = {
+    &fan1_input.attr,
+    &fan2_input.attr,
+    &pwm1.attr,
+    &pwm1_enable.attr,
+    &pwm2.attr,
+    &pwm2_enable.attr,
+    NULL,
+};
+
+static struct attribute_group fan_attr_group = {
+    .attrs = fan_attrs,
+};
+
+int fan_init(void)
+{
+    int ret;
+    /* 创建 /sys/kernel/vfiec/lightring */
+    fan_kobj = kobject_create_and_add("hwmon", vfiec_kobj);
+    if (!fan_kobj)
+    {
+        ret = -ENOMEM;
+    }
+    else
+    {
+        printk(KERN_INFO "Faifan to create sysfs node\n");
+    }
+
+    /* 创建属性文件 */
+    ret = sysfs_create_group(fan_kobj, &fan_attr_group);
+    if (ret)
+    {
+        pr_err("Faifan to create sysfs group: %d\n", ret);
+        goto free_fan_kobj;
+    }
+    else
+    {
+        printk(KERN_INFO "Create sysfs group success\n");
+    }
+
+    ret = alloc_chrdev_region(&dev_num, 0, 1, DEVICE_NAME);
+    if (ret < 0)
+    {
+        printk(KERN_ALERT "mychar: Failed to allocate device number\n");
+        goto free_group;
+    }
+
+    major = MAJOR(dev_num);
+    printk(KERN_INFO "mychar: Assigned major number %d\n", major);
+    // 2. 分配设备结构体内存
+    fan_dev_device = kzalloc(sizeof(struct fan_dev), GFP_KERNEL);
+    if (!fan_dev_device)
+    {
+        printk(KERN_ALERT "mychar: Failed to allocate device memory\n");
+        ret = -ENOMEM;
+        goto free_chrdev;
+    }
+
+    cdev_init(&fan_dev_device->cdev, &fan_fops);
+    fan_dev_device->cdev.owner = THIS_MODULE;
+    ret = cdev_add(&fan_dev_device->cdev, dev_num, 1);
+    if (ret < 0)
+    {
+        printk(KERN_ALERT "mychar: Failed to add cdev\n");
+        goto free_fan_devices;
+    }
+
+    // 4. 创建设备类(用于自动创建/dev节点)
+    fan_dev_device->class = class_create(THIS_MODULE, CLASS_NAME);
+    if (IS_ERR(fan_dev_device->class))
+    {
+        printk(KERN_ALERT "mychar: Failed to create class\n");
+        goto free_cdev_del;
+    }
+
+    // 5. 创建设备节点(会在/dev下生成)
+    fan_dev_device->device = device_create(fan_dev_device->class, NULL, dev_num, NULL, DEVICE_NAME);
+    if (IS_ERR(fan_dev_device->device))
+    {
+        printk(KERN_ALERT "mychar: Failed to create device\n");
+        goto free_class;
+    }
+    return 0;
+free_class:
+    class_destroy(fan_dev_device->class);
+free_cdev_del:
+    cdev_del(&fan_dev_device->cdev);
+free_fan_devices:
+    kfree(fan_dev_device);
+free_chrdev:
+    unregister_chrdev_region(dev_num, 1);
+free_group:
+    sysfs_remove_group(fan_kobj, &fan_attr_group);
+free_fan_kobj:
+    kobject_put(fan_kobj);
+    return ret;
+}
+
+void fan_exit(void)
+{
+    device_destroy(fan_dev_device->class, dev_num);
+    class_destroy(fan_dev_device->class);
+    cdev_del(&fan_dev_device->cdev);
+    kfree(fan_dev_device);
+    unregister_chrdev_region(dev_num, 1);
+    sysfs_remove_group(fan_kobj, &fan_attr_group);
+    kobject_put(fan_kobj);
+}

+ 3 - 34
lcd_2x20.c

@@ -13,11 +13,9 @@
 #define DRIVER_NAME "lcd2002"
 #define LCD_I2C_ADDR_DEFAULT 0x3E
 
-/* 控制字节定义 */
 #define LCD_CONTROL_BYTE    0x00
 #define LCD_DATA_BYTE       0x40
 
-/* 基本指令 */
 #define LCD_CLEAR_DISPLAY   0x01
 #define LCD_RETURN_HOME     0x02
 #define LCD_ENTRY_MODE_SET  0x04
@@ -64,16 +62,15 @@ struct lcd2002_dev {
 
 static struct lcd2002_dev *lcd_dev = NULL;
 
-/* 模块参数 - 多种匹配方式 */
 static char *pci_addr = "0000:00:15.0";
 module_param(pci_addr, charp, 0444);
 MODULE_PARM_DESC(pci_addr, "PCI address (e.g., 0000:00:15.0)");
 
-static char *adapter_name = NULL;  /* 如: "Synopsys DesignWare I2C adapter" */
+static char *adapter_name = NULL;
 module_param(adapter_name, charp, 0444);
 MODULE_PARM_DESC(adapter_name, "I2C adapter name (e.g., Synopsys DesignWare)");
 
-static int i2c_bus = -1;  /* 直接指定总线号,如 1 对应 /dev/i2c-1 */
+static int i2c_bus = -1;
 module_param(i2c_bus, int, 0444);
 MODULE_PARM_DESC(i2c_bus, "I2C bus number (e.g., 1 for /dev/i2c-1)");
 
@@ -85,13 +82,11 @@ static int debug = 1;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Debug level (0=none, 1=normal, 2=verbose)");
 
-/* 延时 */
 static inline void lcd_delay_ms(unsigned int ms)
 {
     msleep(ms);
 }
 
-/* I2C写 */
 static int lcd_i2c_write(unsigned char *buf, int len)
 {
     struct i2c_msg msg;
@@ -113,7 +108,6 @@ static int lcd_i2c_write(unsigned char *buf, int len)
     return 0;
 }
 
-/* 发送指令 */
 static int lcd_send_command(unsigned char cmd)
 {
     unsigned char buf[2];
@@ -131,7 +125,6 @@ static int lcd_send_command(unsigned char cmd)
     return ret;
 }
 
-/* 发送数据 */
 static int lcd_send_data(unsigned char data)
 {
     unsigned char buf[2];
@@ -149,34 +142,28 @@ static int lcd_send_data(unsigned char data)
     return ret;
 }
 
-/* 初始化LCD */
 static int lcd_init_display(void)
 {
     int ret;
 
     lcd_delay_ms(50);
 
-    /* 功能设置: 2行, 5x8点阵 (0x28) */
     ret = lcd_send_command(LCD_FUNCTION_SET | 0x08);
     if (ret < 0) return ret;
     lcd_delay_ms(5);
 
-    /* 显示开,光标关,闪烁关 (0x0C) */
     ret = lcd_send_command(LCD_DISPLAY_CONTROL | LCD_DISPLAY_ON | LCD_CURSOR_OFF | LCD_BLINK_OFF);
     if (ret < 0) return ret;
 
-    /* 清屏 */
     ret = lcd_send_command(LCD_CLEAR_DISPLAY);
     if (ret < 0) return ret;
     lcd_delay_ms(3);
 
-    /* 输入模式: 光标右移 (0x06) */
     ret = lcd_send_command(LCD_ENTRY_MODE_SET | LCD_ENTRY_RIGHT);
     
     return ret;
 }
 
-/* 设置光标 */
 static int lcd_set_cursor(unsigned char col, unsigned char row)
 {
     unsigned char addr;
@@ -186,7 +173,6 @@ static int lcd_set_cursor(unsigned char col, unsigned char row)
     return lcd_send_command(LCD_SET_DDRAM_ADDR | addr);
 }
 
-/* 清屏 */
 static int lcd_clear(void)
 {
     int ret = lcd_send_command(LCD_CLEAR_DISPLAY);
@@ -194,13 +180,11 @@ static int lcd_clear(void)
     return ret;
 }
 
-/* 显示控制 */
 static int lcd_display_control(unsigned char display, unsigned char cursor, unsigned char blink)
 {
     return lcd_send_command(LCD_DISPLAY_CONTROL | display | cursor | blink);
 }
 
-/* 写字符串 */
 static int lcd_write_string(const char *str, size_t len)
 {
     size_t i;
@@ -234,7 +218,6 @@ static int lcd_write_string(const char *str, size_t len)
     return ret;
 }
 
-/* 调试:打印适配器信息 */
 static void print_adapter_info(struct i2c_adapter *adap, int nr)
 {
     struct device *parent;
@@ -262,7 +245,6 @@ static void print_adapter_info(struct i2c_adapter *adap, int nr)
     }
 }
 
-/* 方式1: 通过PCI地址查找 */
 static struct i2c_adapter *find_by_pci(const char *target_pci)
 {
     struct i2c_adapter *adapter;
@@ -278,7 +260,6 @@ static struct i2c_adapter *find_by_pci(const char *target_pci)
         if (debug >= 2)
             print_adapter_info(adapter, nr);
         
-        /* 递归向上查找PCI设备 */
         while (parent && !found) {
             if (parent->bus == &pci_bus_type) {
                 struct pci_dev *pdev = to_pci_dev(parent);
@@ -293,7 +274,7 @@ static struct i2c_adapter *find_by_pci(const char *target_pci)
                     found = true;
                     break;
                 }
-                break; /* 只检查第一级PCI父设备 */
+                break;
             }
             parent = parent->parent;
         }
@@ -308,7 +289,6 @@ static struct i2c_adapter *find_by_pci(const char *target_pci)
     return NULL;
 }
 
-/* 方式2: 通过名称查找 */
 static struct i2c_adapter *find_by_name(const char *name)
 {
     struct i2c_adapter *adapter;
@@ -331,45 +311,38 @@ static struct i2c_adapter *find_by_name(const char *name)
     return NULL;
 }
 
-/* 方式3: 通过总线号 */
 static struct i2c_adapter *find_by_bus(int bus)
 {
     pr_info("Trying i2c bus %d...\n", bus);
     return i2c_get_adapter(bus);
 }
 
-/* 查找适配器主函数 */
 static struct i2c_adapter *find_adapter(void)
 {
     struct i2c_adapter *adapter = NULL;
     
-    /* 优先级1: 直接指定总线号 */
     if (i2c_bus >= 0) {
         adapter = find_by_bus(i2c_bus);
         if (adapter) goto done;
         pr_warn("Specified i2c_bus %d not found\n", i2c_bus);
     }
     
-    /* 优先级2: PCI地址 */
     if (pci_addr && strlen(pci_addr) > 0) {
         adapter = find_by_pci(pci_addr);
         if (adapter) goto done;
         pr_warn("PCI address %s not found\n", pci_addr);
     }
     
-    /* 优先级3: 适配器名称 */
     if (adapter_name && strlen(adapter_name) > 0) {
         adapter = find_by_name(adapter_name);
         if (adapter) goto done;
         pr_warn("Adapter name '%s' not found\n", adapter_name);
     }
     
-    /* 回退: 自动检测常见名称 (Synopsys DesignWare) */
     pr_info("Trying auto-detect (Synopsys DesignWare)...\n");
     adapter = find_by_name("Synopsys DesignWare");
     if (adapter) goto done;
     
-    /* 最后回退: 使用 i2c-1 (根据用户环境) */
     pr_info("Trying fallback i2c-1...\n");
     adapter = find_by_bus(1);
     
@@ -377,7 +350,6 @@ done:
     return adapter;
 }
 
-/* 文件操作 */
 static int lcd_open(struct inode *inode, struct file *file)
 {
     return lcd_dev ? 0 : -ENODEV;
@@ -474,7 +446,6 @@ int lcd2x20_init(void)
     mutex_init(&lcd_dev->lock);
     lcd_dev->addr = i2c_address;
     
-    /* 查找适配器 */
     lcd_dev->adapter = find_adapter();
     if (!lcd_dev->adapter) {
         pr_err("Failed to find any suitable I2C adapter!\n");
@@ -493,7 +464,6 @@ int lcd2x20_init(void)
     
     pr_info("Using I2C adapter: %s\n", lcd_dev->adapter->name);
     
-    /* 初始化LCD */
     ret = lcd_init_display();
     if (ret < 0) {
         pr_err("LCD init failed: %d\n", ret);
@@ -508,7 +478,6 @@ int lcd2x20_init(void)
     
     pr_info("LCD2002 ready at /dev/%s\n", lcd_miscdev.name);
     
-    /* 欢迎信息 */
     lcd_clear();
     lcd_write_string("LCD2002 Driver OK", 17);
     lcd_set_cursor(0, 1);

+ 0 - 2
led.c

@@ -64,7 +64,6 @@ static ssize_t mode_store(struct kobject *kobj, struct kobj_attribute *attr,
 static struct kobj_attribute mode_attr =
     __ATTR(mode, 0644, mode_show, mode_store);
 
-/* ==================== 属性组 ==================== */
 static struct attribute *led_attrs[] = {
     &color_attr.attr,
     &mode_attr.attr,
@@ -85,7 +84,6 @@ int led_init(void)
         ret = -ENOMEM;
     }
 
-    /* 创建属性文件 */
     ret = sysfs_create_group(led_kobj, &led_attr_group);
     if (ret)
     {

+ 18 - 56
light_ring.c

@@ -23,11 +23,9 @@
 
 #define PCA9685_ADDR 0x40
 
-/* I2C设备地址 */
 #define PCA9685_DEFAULT_ADDR 0x40
 #define PCA9685_GENERAL_CALL 0x00
 
-/* PCA9685寄存器定义 */
 #define PCA9685_MODE1 0x00
 #define PCA9685_MODE2 0x01
 #define PCA9685_SUBADR1 0x02
@@ -45,7 +43,6 @@
 #define PCA9685_PRESCALE 0xFE
 #define PCA9685_TESTMODE 0xFF
 
-/* MODE1寄存器位定义 */
 #define MODE1_RESTART 0x80
 #define MODE1_EXTCLK 0x40
 #define MODE1_AI 0x20
@@ -55,21 +52,18 @@
 #define MODE1_SUB3 0x02
 #define MODE1_ALLCALL 0x01
 
-/* MODE2寄存器位定义 */
 #define MODE2_INVRT 0x10
 #define MODE2_OCH 0x08
 #define MODE2_OUTDRV 0x04
 #define MODE2_OUTNE1 0x02
 #define MODE2_OUTNE0 0x01
 
-/* 参数 */
 #define PCA9685_PWM_RESOLUTION 4096
 #define PCA9685_OSC_FREQ 25000000
 #define PCA9685_MIN_FREQ 24
 #define PCA9685_MAX_FREQ 1526
 
 
-/* 错误码 */
 #define PCA9685_OK              0
 #define PCA9685_ERR_OPEN       -1
 #define PCA9685_ERR_ADDR       -2
@@ -96,7 +90,6 @@
 #define LIGHT_MODE_FLASH_MEDIUM 0x07
 #define LIGHT_MODE_FLASH_FAST 0x08
 
-/* 内部数据结构 */
 struct lightring_data
 {
     u32 brightness;
@@ -106,19 +99,18 @@ struct lightring_data
     u32 flash_time;
 };
 
-/* 驱动私有数据结构 */
 struct light_ring_i2c_dev
 {
-    struct pci_dev *pdev;             /* PCI设备指针 */
-    struct i2c_adapter *adapter;      /* I2C适配器指针 */
-    struct i2c_client client;         /* I2C客户端指针 */
-    struct cdev cdev;                 /* 字符设备结构 */
-    struct class *class;              /* 设备类 */
-    struct device *device;            /* 设备指针 */
-    dev_t dev_num;                    /* 设备号 */
-    struct mutex lock;                /* 互斥锁 */
-    int bus_number;                   /* 保存的总线编号 */
-    struct lightring_data *lightring; /* 内部数据结构 */
+    struct pci_dev *pdev;             
+    struct i2c_adapter *adapter;      
+    struct i2c_client client;         
+    struct cdev cdev;                 
+    struct class *class;              
+    struct device *device;            
+    dev_t dev_num;                    
+    struct mutex lock;                
+    int bus_number;                   
+    struct lightring_data *lightring; 
     struct delayed_work delay_work1;
 };
 int set_color(unsigned int color);
@@ -128,7 +120,6 @@ static void delay_work_func(struct work_struct *work)
 {
     static int flag = 0;
     printk("this is delay_work_func !\n");
-    //自己再启动自己,也可以在其他地方启动
     if(global_dev->lightring->flash_time != 0)
     {
         if(global_dev->lightring->mode == LIGHT_MODE_FLASH_1SEC || \
@@ -137,13 +128,11 @@ static void delay_work_func(struct work_struct *work)
         {
             if(flag == 0)
             {
-                // 显示颜色
                 set_color(global_dev->lightring->color);
                 flag = 1;
             }
             else
             {
-                // 关闭灯带
                 set_color(0);
                 flag = 0;
             }
@@ -244,7 +233,6 @@ static ssize_t brightness_store(struct kobject *kobj, struct kobj_attribute *att
         printk("Lightring: brightness out of range\n");
         return -1;
     }
-    /* 硬件操作:设置亮度 */
     global_dev->lightring->brightness = val;
     set_color(global_dev->lightring->color);
 
@@ -463,7 +451,6 @@ static ssize_t mode_store(struct kobject *kobj, struct kobj_attribute *attr,
 static struct kobj_attribute mode_attr =
     __ATTR(mode, 0644, mode_show, mode_store);
 
-/* ==================== 属性组 ==================== */
 static struct attribute *lightring_attrs[] = {
     &brightness_attr.attr,
     &color_attr.attr,
@@ -489,7 +476,6 @@ static struct i2c_adapter *find_i2c_adapter_by_pci(struct pci_dev *pdev)
     if (!pdev)
         return NULL;
 
-    /* 获取PCI设备的fwnode */
     fwnode = dev_fwnode(&pdev->dev);
     if (!fwnode)
     {
@@ -497,17 +483,12 @@ static struct i2c_adapter *find_i2c_adapter_by_pci(struct pci_dev *pdev)
         return NULL;
     }
 
-    /* 对于内核5.15,需要使用其他方法查找i2c适配器 */
-
-    /* 方法A: 通过设备链接查找 */
     struct device_link *link;
 
-    /* 遍历PCI设备的消费者链接 */
     list_for_each_entry(link, &pdev->dev.links.consumers, s_node)
     {
         if (link->supplier == &pdev->dev)
         {
-            /* 检查消费者是否是i2c适配器 */
             if (link->consumer->type &&
                 link->consumer->type->name &&
                 strcmp(link->consumer->type->name, "i2c_adapter") == 0)
@@ -521,20 +502,18 @@ static struct i2c_adapter *find_i2c_adapter_by_pci(struct pci_dev *pdev)
 
     if (adapter)
     {
-        i2c_put_adapter(adapter);               /* 先释放引用 */
-        adapter = i2c_get_adapter(adapter->nr); /* 重新获取 */
+        i2c_put_adapter(adapter);               
+        adapter = i2c_get_adapter(adapter->nr); 
         printk("i2c_get_adapter\n");
         return adapter;
     }
 
-    /* 方法B: 遍历所有i2c适配器 */
     int i;
     for (i = 0; i < 255; i++)
     {
         adapter = i2c_get_adapter(i);
         if (adapter)
         {
-            /* 检查适配器的父设备是否是我们的PCI设备 */
             if (adapter->dev.parent == &pdev->dev)
             {
                 return adapter;
@@ -546,12 +525,10 @@ static struct i2c_adapter *find_i2c_adapter_by_pci(struct pci_dev *pdev)
     return NULL;
 }
 
-/* 初始化PCI设备 */
 static struct pci_dev *init_pci_device(void)
 {
     struct pci_dev *pdev;
 
-    /* 查找PCI设备: domain=0, bus=0, devfn=PCI_DEVFN(0x1f, 4) */
     pdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0x1f, 4));
     if (!pdev)
     {
@@ -657,7 +634,6 @@ int light_ring_init(void)
 
     pr_info("light_ring_i2c_dev initializing...\n");
 
-    /* 分配设备结构 */
     dev = kzalloc(sizeof(struct light_ring_i2c_dev), GFP_KERNEL);
     if (!dev)
     {
@@ -667,7 +643,6 @@ int light_ring_init(void)
     global_dev = dev;
     mutex_init(&dev->lock);
 
-    /* 1. 初始化PCI设备 */
     dev->pdev = init_pci_device();
     if (!dev->pdev)
     {
@@ -676,7 +651,6 @@ int light_ring_init(void)
         goto err_free_dev;
     }
 
-    /* 2. 通过PCI设备查找I2C适配器 */
     dev->adapter = find_i2c_adapter_by_pci(dev->pdev);
     if (!dev->adapter)
     {
@@ -685,26 +659,23 @@ int light_ring_init(void)
         goto err_put_pci;
     }
 
-    /* 保存总线编号用于调试 */
     dev->bus_number = dev->adapter->nr;
     pr_info("Found I2C adapter on bus %d\n", dev->bus_number);
 
-    // 检查适配器是否支持字节数据读写
     if (!i2c_check_functionality(dev->adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA |
                                                    I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
     {
         dev_err(&dev->adapter->dev, "Adapter does not support required SMBus features\n");
-        return -ENOTSUPP; // 返回不支持错误码
+        return -ENOTSUPP; 
     }
     else
     {
         pr_info("Adapter supports required SMBus features\n");
     }
 
-    /* 初始化I2C客户端 */
-    dev->client.adapter = dev->adapter;      // 你已有的 adapter
-    dev->client.addr = PCA9685_DEFAULT_ADDR; // 从设备地址
-    dev->client.flags = 0;                   // 7位地址模式
+    dev->client.adapter = dev->adapter;      
+    dev->client.addr = PCA9685_DEFAULT_ADDR; 
+    dev->client.flags = 0;                   
 
     INIT_DELAYED_WORK(&dev->delay_work1, delay_work_func);
 
@@ -718,21 +689,12 @@ int light_ring_init(void)
         goto err_put_pci;
     }
 
-    /* 默认值 */
     global_dev->lightring->brightness = 60;
-    global_dev->lightring->color = 0xFFFFFF; /* 白色 */
+    global_dev->lightring->color = 0xFFFFFF;
     global_dev->lightring->max_fade_brightness = 255;
     global_dev->lightring->mode = 0; /* static */
 
-    /* 创建 /sys/kernel/vfiec */
-    // vfiec_kobj = kobject_create_and_add("vfiec", kernel_kobj);
-    // if (!vfiec_kobj)
-    // {
-    //     ret = -ENOMEM;
-    //     goto err_free;
-    // }
 
-    /* 创建 /sys/kernel/vfiec/lightring */
     lightring_kobj = kobject_create_and_add("lightring", vfiec_kobj);
     if (!lightring_kobj)
     {
@@ -740,7 +702,7 @@ int light_ring_init(void)
         goto err_free;
     }
 
-    /* 创建属性文件 */
+
     ret = sysfs_create_group(lightring_kobj, &lightring_attr_group);
     if (ret)
     {

+ 0 - 1
main.c

@@ -38,7 +38,6 @@ struct kobject *vfiec_kobj = NULL;
 static int __init all_driver_init(void)
 {
     int ret = 0;
-    /* 创建 /sys/kernel/vfiec */
     vfiec_kobj = kobject_create_and_add("vfiec", kernel_kobj);
     if (!vfiec_kobj)
     {

+ 4 - 32
myname.c

@@ -25,9 +25,8 @@
 #define SWITCH_ID3 0xFD6D0B30
 #define SWITCH_ID4 0xFD6D0B40
 
-// 可以通过模块参数指定主设备号和次设备号
-static int myname_major = 56; // 默认主设备号
-static int myname_minor = 130;   // 默认次设备号
+static int myname_major = 56; 
+static int myname_minor = 130;
 module_param(myname_major, int, S_IRUGO);
 module_param(myname_minor, int, S_IRUGO);
 MODULE_PARM_DESC(myname_major, "Major device number");
@@ -38,7 +37,6 @@ static struct device *char_device = NULL;
 static struct cdev my_cdev;
 static dev_t dev_num;
 
-// 设备结构体
 struct myname_dev
 {
     char *buffer;
@@ -63,7 +61,6 @@ static void delay_work_func(struct work_struct *work)
     printk(KERN_ERR "delay_work_func\n");
 }
 
-// 文件打开操作
 static int myname_open(struct inode *inode, struct file *filp)
 {
     struct myname_dev *dev;
@@ -76,7 +73,6 @@ static int myname_open(struct inode *inode, struct file *filp)
     return 0;
 }
 
-// 文件释放操作
 static int myname_release(struct inode *inode, struct file *filp)
 {
     // release_region(PORT_80, 1);
@@ -84,7 +80,6 @@ static int myname_release(struct inode *inode, struct file *filp)
     return 0;
 }
 
-// 读操作 - 支持cat命令
 static ssize_t myname_read(struct file *filp, char __user *buf,
                              size_t count, loff_t *f_pos)
 {
@@ -95,18 +90,15 @@ static ssize_t myname_read(struct file *filp, char __user *buf,
     if (mutex_lock_interruptible(&dev->lock))
         return -ERESTARTSYS;
 
-    // 关键检查:是否已经读到文件末尾?
     if (*f_pos >= dev->size) {
         printk(KERN_DEBUG "myname: EOF reached (pos=%lld, size=%zu)\n", 
                *f_pos, dev->size);
         mutex_unlock(&dev->lock);
-        return 0;  // 返回 0 告诉 cat 文件结束
+        return 0;
     }
 
-    // 计算剩余可读字节数
     size_t available = dev->size - *f_pos;
     
-    // 确定本次读取的字节数
     if (count > available) {
         retval = available;
     } else {
@@ -123,16 +115,14 @@ static ssize_t myname_read(struct file *filp, char __user *buf,
         return -EFAULT;
     }
 
-    // 更新文件位置指针 - 这一步非常关键!
     *f_pos += retval;
 
     printk(KERN_DEBUG "myname: Read %zu bytes, new pos=%lld\n", retval, *f_pos);
 
     mutex_unlock(&dev->lock);
-    return retval;  // 返回实际读取的字节数
+    return retval;
 }
 
-// 写操作
 static ssize_t myname_write(struct file *filp, const char __user *buf,
                               size_t count, loff_t *f_pos)
 {
@@ -142,19 +132,16 @@ static ssize_t myname_write(struct file *filp, const char __user *buf,
     int ret = 0;
     return -1;
 
-    // 加锁
     if (mutex_lock_interruptible(&dev->lock))
     {
         return -ERESTARTSYS;
     }
 
-    // 计算可写数据量
     if (count > dev->size)
     {
         count = dev->size;
     }
 
-    // 拷贝数据
     ret = copy_from_user(dev->buffer, buf, count);
     if (ret != 0)
     {
@@ -169,7 +156,6 @@ static ssize_t myname_write(struct file *filp, const char __user *buf,
 out:
     mutex_unlock(&dev->lock);
 
-    // 调度延迟工作
     if (ret == 0)
     {
         schedule_delayed_work(&dev->delay_work1, msecs_to_jiffies(10));
@@ -177,7 +163,6 @@ out:
     return count;
 }
 
-// 文件操作结构体
 static struct file_operations fops = {
     .owner = THIS_MODULE,
     .open = myname_open,
@@ -186,7 +171,6 @@ static struct file_operations fops = {
     .write = myname_write,
 };
 
-// 获取board_id
 int get_board_id(void)
 {
     unsigned int board_id = 0;
@@ -227,7 +211,6 @@ int get_board_id(void)
     return board_id;
 }
 
-// 模块初始化
 int myname_init(void)
 {
     int result;
@@ -235,17 +218,14 @@ int myname_init(void)
     printk(KERN_ERR "myname: Initializing driver with major=%d, minor=%d\n",
            myname_major, myname_minor);
 
-    // 检查主设备号是否有效
     if (myname_major <= 0)
     {
         printk(KERN_ALERT "myname: Invalid major number %d\n", myname_major);
         return -EINVAL;
     }
 
-    // 构建设备号
     dev_num = MKDEV(myname_major, myname_minor);
 
-    // 注册设备号 - 使用指定的主设备号
     result = register_chrdev_region(dev_num, 1, DEVICE_NAME);
     if (result < 0)
     {
@@ -257,7 +237,6 @@ int myname_init(void)
     printk(KERN_ERR "myname: Registered with major=%d, minor=%d\n",
            MAJOR(dev_num), MINOR(dev_num));
 
-    // 分配设备结构体
     dev = kmalloc(sizeof(struct myname_dev), GFP_KERNEL);
     if (!dev)
     {
@@ -266,7 +245,6 @@ int myname_init(void)
     }
     memset(dev, 0, sizeof(struct myname_dev));
 
-    // 分配缓冲区
     dev->buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
     if (!dev->buffer)
     {
@@ -274,18 +252,15 @@ int myname_init(void)
         goto fail_buffer;
     }
     memset(dev->buffer, 0, BUFFER_SIZE);
-    // 初始化互斥锁
     mutex_init(&dev->lock);
 
     INIT_DELAYED_WORK(&dev->delay_work1, delay_work_func);
     dev->board_id = get_board_id();
     printk(KERN_ERR "myname: %s\n", dev->buffer);
 
-    // 初始化字符设备
     cdev_init(&dev->cdev, &fops);
     dev->cdev.owner = THIS_MODULE;
 
-    // 添加字符设备到系统
     result = cdev_add(&dev->cdev, dev_num, 1);
     if (result)
     {
@@ -293,7 +268,6 @@ int myname_init(void)
         goto fail_cdev;
     }
 
-    // 创建设备类
     char_class = class_create(THIS_MODULE, CLASS_NAME);
     if (IS_ERR(char_class))
     {
@@ -302,7 +276,6 @@ int myname_init(void)
         goto fail_class;
     }
 
-    // 创建设备
     char_device = device_create(char_class, NULL, dev_num, NULL, DEVICE_NAME);
     if (IS_ERR(char_device))
     {
@@ -329,7 +302,6 @@ fail_malloc:
     return result;
 }
 
-// 模块退出
 void myname_exit(void)
 {
     cancel_delayed_work_sync(&dev->delay_work1);

+ 6 - 30
power.c

@@ -28,14 +28,13 @@ static int minor_num = MINOR_NUM;
 static struct class *device_class = NULL;
 static struct device *device = NULL;
 
-/* 设备结构体 */
 struct chardev_device {
     struct cdev cdev;
-    char *buffer;           /* 数据缓冲区 */
-    size_t data_len;        /* 当前数据长度 */
-    wait_queue_head_t read_queue;  /* 读等待队列 */
-    struct mutex lock;      /* 互斥锁 */
-    bool nonblock;          /* 非阻塞标志(可选) */
+    char *buffer;           
+    size_t data_len;        
+    wait_queue_head_t read_queue;
+    struct mutex lock;      
+    bool nonblock;          
     struct delayed_work delay_work1;
     char status;
 };
@@ -132,7 +131,6 @@ uint8_t soft_rest_btn(void)//read GPIO of btn SW_HRST1
     return (val & 0x01) ? 1 : 0;
 }
 
-/* 打开设备 */
 static int chardev_open(struct inode *inode, struct file *filp)
 {
     struct chardev_device *dev = container_of(inode->i_cdev, 
@@ -142,14 +140,12 @@ static int chardev_open(struct inode *inode, struct file *filp)
     return 0;
 }
 
-/* 释放设备 */
 static int chardev_release(struct inode *inode, struct file *filp)
 {
     dev_info(device, "Device released\n");
     return 0;
 }
 
-/* read 系统调用 */
 static ssize_t chardev_read(struct file *filp, char __user *buf, 
                             size_t count, loff_t *f_pos)
 {
@@ -159,7 +155,6 @@ static ssize_t chardev_read(struct file *filp, char __user *buf,
     
     mutex_lock(&dev->lock);
     
-    /* 等待数据可用(支持非阻塞和超时) */
     while (dev->data_len == 0) {
         if (filp->f_flags & O_NONBLOCK) {
             mutex_unlock(&dev->lock);
@@ -168,7 +163,6 @@ static ssize_t chardev_read(struct file *filp, char __user *buf,
         
         mutex_unlock(&dev->lock);
         
-        /* 等待数据(可中断) */
         if (wait_event_interruptible(dev->read_queue, dev->data_len > 0)) {
             return -ERESTARTSYS;
         }
@@ -176,20 +170,16 @@ static ssize_t chardev_read(struct file *filp, char __user *buf,
         mutex_lock(&dev->lock);
     }
     
-    /* 确定可读取的数据量 */
     available = min(count, dev->data_len);
     
-    /* 拷贝数据到用户空间 */
     if (copy_to_user(buf, &chardev_dev->status, available)) {
         mutex_unlock(&dev->lock);
         return -EFAULT;
     }
     
-    /* 更新缓冲区(简单实现:读取后清空所有数据) */
     if (available == dev->data_len) {
         dev->data_len = 0;
     } else {
-        /* 这里简单处理:移动剩余数据到开头 */
         memmove(dev->buffer, dev->buffer + available, dev->data_len - available);
         dev->data_len -= available;
     }
@@ -201,7 +191,6 @@ static ssize_t chardev_read(struct file *filp, char __user *buf,
     return ret;
 }
 
-/* poll 系统调用(支持 select) */
 static __poll_t chardev_poll(struct file *filp, struct poll_table_struct *wait)
 {
     struct chardev_device *dev = filp->private_data;
@@ -211,14 +200,13 @@ static __poll_t chardev_poll(struct file *filp, struct poll_table_struct *wait)
     
     mutex_lock(&dev->lock);
     if (dev->data_len > 0) {
-        mask |= EPOLLIN | EPOLLRDNORM;  /* 数据可读 */
+        mask |= EPOLLIN | EPOLLRDNORM;
     }
     mutex_unlock(&dev->lock);
     
     return mask;
 }
 
-/* 可选:提供写接口供测试用 */
 static ssize_t chardev_write(struct file *filp, const char __user *buf,
                              size_t count, loff_t *f_pos)
 {
@@ -242,7 +230,6 @@ static ssize_t chardev_write(struct file *filp, const char __user *buf,
     dev->data_len += to_write;
     ret = to_write;
     
-    /* 唤醒等待读的进程 */
     wake_up_interruptible(&dev->read_queue);
     
     mutex_unlock(&dev->lock);
@@ -251,7 +238,6 @@ static ssize_t chardev_write(struct file *filp, const char __user *buf,
     return ret;
 }
 
-/* file_operations 结构 */
 static struct file_operations chardev_fops = {
     .owner = THIS_MODULE,
     .open = chardev_open,
@@ -304,16 +290,13 @@ static void delay_work_func(struct work_struct *work)
 	schedule_delayed_work(&chardev_dev->delay_work1, msecs_to_jiffies(500));
 }
 
-/* 初始化设备 */
 int power_interface_init(void)
 {
     int ret;
     dev_t dev_num;
     
-    /* 使用指定的主设备号和次设备号 */
     dev_num = MKDEV(MAJOR_NUM, MINOR_NUM);
     
-    /* 注册设备号(指定固定主设备号) */
     ret = register_chrdev_region(dev_num, 1, DEVICE_NAME);
     if (ret < 0) {
         pr_err("Failed to register device number %d:%d\n", MAJOR_NUM, MINOR_NUM);
@@ -323,7 +306,6 @@ int power_interface_init(void)
     minor_num = MINOR_NUM;
     pr_info("Registered device number %d:%d\n", major_num, minor_num);
     
-    /* 分配设备结构体 */
     chardev_dev = kzalloc(sizeof(struct chardev_device), GFP_KERNEL);
     if (!chardev_dev) {
         ret = -ENOMEM;
@@ -334,19 +316,16 @@ int power_interface_init(void)
     
 	schedule_delayed_work(&chardev_dev->delay_work1, msecs_to_jiffies(500));
     
-    /* 分配数据缓冲区 */
     chardev_dev->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL);
     if (!chardev_dev->buffer) {
         ret = -ENOMEM;
         goto err_alloc_buffer;
     }
     
-    /* 初始化互斥锁和等待队列 */
     mutex_init(&chardev_dev->lock);
     init_waitqueue_head(&chardev_dev->read_queue);
     chardev_dev->data_len = 0;
     
-    /* 初始化 cdev */
     cdev_init(&chardev_dev->cdev, &chardev_fops);
     chardev_dev->cdev.owner = THIS_MODULE;
     ret = cdev_add(&chardev_dev->cdev, dev_num, 1);
@@ -355,7 +334,6 @@ int power_interface_init(void)
         goto err_cdev_add;
     }
     
-    /* 创建设备类 */
     device_class = class_create(THIS_MODULE, CLASS_NAME);
     if (IS_ERR(device_class)) {
         ret = PTR_ERR(device_class);
@@ -363,7 +341,6 @@ int power_interface_init(void)
         goto err_class_create;
     }
     
-    /* 创建设备节点 */
     device = device_create(device_class, NULL, dev_num, NULL, DEVICE_NAME);
     if (IS_ERR(device)) {
         ret = PTR_ERR(device);
@@ -387,7 +364,6 @@ err_alloc_dev:
     return ret;
 }
 
-/* 退出模块 */
 void power_interface_exit(void)
 {
     dev_t dev_num = MKDEV(major_num, minor_num);

+ 2 - 32
ssegment.c

@@ -19,9 +19,8 @@
 #define DRIVER_NAME     "port80_seg7"
 #define BUFFER_SIZE 1024
 
-// 可以通过模块参数指定主设备号和次设备号
-static int major = 56; // 默认主设备号
-static int minor = 40;   // 默认次设备号
+static int major = 56; 
+static int minor = 40; 
 module_param(major, int, S_IRUGO);
 module_param(minor, int, S_IRUGO);
 MODULE_PARM_DESC(major, "Major device number");
@@ -32,7 +31,6 @@ static struct device *char_device = NULL;
 static struct cdev my_cdev;
 static dev_t dev_num;
 
-// 设备结构体
 struct ssegment_dev
 {
     char *buffer;
@@ -66,31 +64,25 @@ static void delay_work_func(struct work_struct *work)
     unsigned int val = 0;
     if(dev->size != 0)
     {
-        // 写数据
         outb(dev->buffer[0], PORT_80);
         if((dev->buffer[1] & 0x02))
         {
             val = readl_cust(SSEGMENT_POINT);
             val = val | 0x01;
             ret = writel_cust(SSEGMENT_POINT, val);
-            // 显示小数点 待提供接口
-            // 待实现
         }
         else
         {
             val = readl_cust(SSEGMENT_POINT);
             val = val & 0xFFFFFFFE;
             ret = writel_cust(SSEGMENT_POINT, val);
-            // 不显示小数点
         }
 
         if((dev->buffer[1] & 0x80))
         {
-            // 闪烁 LED
         }
         else
         {
-            // 不闪烁 LED
         }
     }
 
@@ -99,7 +91,6 @@ static void delay_work_func(struct work_struct *work)
     printk(KERN_INFO "delay_work_func\n");
 }
 
-// 文件打开操作
 static int ssegment_open(struct inode *inode, struct file *filp)
 {
     struct ssegment_dev *dev;
@@ -118,7 +109,6 @@ static int ssegment_open(struct inode *inode, struct file *filp)
     return 0;
 }
 
-// 文件释放操作
 static int ssegment_release(struct inode *inode, struct file *filp)
 {
     // release_region(PORT_80, 1);
@@ -126,7 +116,6 @@ static int ssegment_release(struct inode *inode, struct file *filp)
     return 0;
 }
 
-// 读操作 - 支持cat命令
 static ssize_t ssegment_read(struct file *filp, char __user *buf,
                              size_t count, loff_t *f_pos)
 {
@@ -139,7 +128,6 @@ static ssize_t ssegment_read(struct file *filp, char __user *buf,
     if (mutex_lock_interruptible(&dev->lock))
         return -ERESTARTSYS;
 
-    // 这里read_count没有固定为4个字节,是为了便于后续扩展
     if (count > dev->size)
     {
         read_count = dev->size;
@@ -162,7 +150,6 @@ out:
     return ret;
 }
 
-// 写操作
 static ssize_t ssegment_write(struct file *filp, const char __user *buf,
                               size_t count, loff_t *f_pos)
 {
@@ -171,19 +158,16 @@ static ssize_t ssegment_write(struct file *filp, const char __user *buf,
     size_t available;
     int ret = 0;
 
-    // 加锁
     if (mutex_lock_interruptible(&dev->lock))
     {
         return -ERESTARTSYS;
     }
 
-    // 计算可写数据量
     if (count > BUFFER_SIZE)
     {
         count = BUFFER_SIZE;
     }
 
-    // 拷贝数据
     ret = copy_from_user(dev->buffer, buf, count);
     if (ret != 0)
     {
@@ -198,7 +182,6 @@ static ssize_t ssegment_write(struct file *filp, const char __user *buf,
 out:
     mutex_unlock(&dev->lock);
 
-    // 调度延迟工作
     if (ret == 0)
     {
         schedule_delayed_work(&dev->delay_work1, msecs_to_jiffies(10));
@@ -206,7 +189,6 @@ out:
     return count;
 }
 
-// 文件操作结构体
 static struct file_operations fops = {
     .owner = THIS_MODULE,
     .open = ssegment_open,
@@ -215,7 +197,6 @@ static struct file_operations fops = {
     .write = ssegment_write,
 };
 
-// 模块初始化
 int ssegment_init(void)
 {
     int result;
@@ -223,17 +204,14 @@ int ssegment_init(void)
     printk(KERN_INFO "ssegment: Initializing driver with major=%d, minor=%d\n",
            major, minor);
 
-    // 检查主设备号是否有效
     if (major <= 0)
     {
         printk(KERN_ALERT "ssegment: Invalid major number %d\n", major);
         return -EINVAL;
     }
 
-    // 构建设备号
     dev_num = MKDEV(major, minor);
 
-    // 注册设备号 - 使用指定的主设备号
     result = register_chrdev_region(dev_num, 1, DEVICE_NAME);
     if (result < 0)
     {
@@ -245,7 +223,6 @@ int ssegment_init(void)
     printk(KERN_INFO "ssegment: Registered with major=%d, minor=%d\n",
            MAJOR(dev_num), MINOR(dev_num));
 
-    // 分配设备结构体
     dev = kmalloc(sizeof(struct ssegment_dev), GFP_KERNEL);
     if (!dev)
     {
@@ -254,7 +231,6 @@ int ssegment_init(void)
     }
     memset(dev, 0, sizeof(struct ssegment_dev));
 
-    // 分配缓冲区
     dev->buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
     if (!dev->buffer)
     {
@@ -262,16 +238,13 @@ int ssegment_init(void)
         goto fail_buffer;
     }
 
-    // 初始化互斥锁
     mutex_init(&dev->lock);
 
     INIT_DELAYED_WORK(&dev->delay_work1, delay_work_func);
 
-    // 初始化字符设备
     cdev_init(&dev->cdev, &fops);
     dev->cdev.owner = THIS_MODULE;
 
-    // 添加字符设备到系统
     result = cdev_add(&dev->cdev, dev_num, 1);
     if (result)
     {
@@ -279,7 +252,6 @@ int ssegment_init(void)
         goto fail_cdev;
     }
 
-    // 创建设备类
     char_class = class_create(THIS_MODULE, CLASS_NAME);
     if (IS_ERR(char_class))
     {
@@ -288,7 +260,6 @@ int ssegment_init(void)
         goto fail_class;
     }
 
-    // 创建设备
     char_device = device_create(char_class, NULL, dev_num, NULL, DEVICE_NAME);
     if (IS_ERR(char_device))
     {
@@ -315,7 +286,6 @@ fail_malloc:
     return result;
 }
 
-// 模块退出
 void ssegment_exit(void)
 {
     cancel_delayed_work_sync(&dev->delay_work1);

+ 4 - 24
switches.c

@@ -20,12 +20,12 @@
 #define BUFFER_SIZE 1024
 
 /*
-拨码
+
 F12 0xFD6A0940 bit1
 F16 0xFD6A0980 bit1
 F17 0xFD6A0990 bit1
 F18 0xFD6A09A0 bit1
-跳帽
+
 ID0-D0 0xFD6D0A40 bit1
 ID1-D1 0xFD6D0A50 bit1
 ID2-D14 0xFD6D0B20 bit1
@@ -44,9 +44,8 @@ ID4-D16 0xFD6D0B40 bit1
 #define SWITCH_ID3 0xFD6D0B30
 #define SWITCH_ID4 0xFD6D0B40
 
-// 可以通过模块参数指定主设备号和次设备号
-static int switches_major = 56; // 默认主设备号
-static int switches_minor = 71;   // 默认次设备号
+static int switches_major = 56; 
+static int switches_minor = 71; 
 module_param(switches_major, int, S_IRUGO);
 module_param(switches_minor, int, S_IRUGO);
 MODULE_PARM_DESC(switches_major, "Major device number");
@@ -57,7 +56,6 @@ static struct device *char_device = NULL;
 static struct cdev my_cdev;
 static dev_t dev_num;
 
-// 设备结构体
 struct switches_dev
 {
     char *buffer;
@@ -81,7 +79,6 @@ int get_switch_gpio_status(void)
 {
     dev->switch_status[0] = 0;
     dev->switch_status[1] = 0;
-    // 这里需要待完善,确认熊工提供的地址和API文档的对应关系
     dev->switch_status[0] |= (switch_readl(SWITCH_F12)&0x02) >> 1;
     dev->switch_status[0] |= switch_readl(SWITCH_F16)&0x02;
     dev->switch_status[0] |= (switch_readl(SWITCH_F17)&0x02) << 1;
@@ -103,7 +100,6 @@ static void delay_work_func(struct work_struct *work)
     printk(KERN_INFO "delay_work_func\n");
 }
 
-// 文件打开操作
 static int switches_open(struct inode *inode, struct file *filp)
 {
     struct switches_dev *dev;
@@ -116,7 +112,6 @@ static int switches_open(struct inode *inode, struct file *filp)
     return 0;
 }
 
-// 文件释放操作
 static int switches_release(struct inode *inode, struct file *filp)
 {
     // release_region(PORT_80, 1);
@@ -124,7 +119,6 @@ static int switches_release(struct inode *inode, struct file *filp)
     return 0;
 }
 
-// 读操作 - 支持cat命令
 static ssize_t switches_read(struct file *filp, char __user *buf,
                              size_t count, loff_t *f_pos)
 {
@@ -152,7 +146,6 @@ static ssize_t switches_read(struct file *filp, char __user *buf,
     return ret;
 }
 
-// 写操作
 static ssize_t switches_write(struct file *filp, const char __user *buf,
                               size_t count, loff_t *f_pos)
 {
@@ -165,7 +158,6 @@ static unsigned int switches_poll(struct file *filp, poll_table *wait)
     return 0;
 }
 
-// 文件操作结构体
 static struct file_operations fops = {
     .owner = THIS_MODULE,
     .open = switches_open,
@@ -175,7 +167,6 @@ static struct file_operations fops = {
     .poll = switches_poll,
 };
 
-// 模块初始化
 int switches_init(void)
 {
     int result;
@@ -183,17 +174,14 @@ int switches_init(void)
     printk(KERN_INFO "switches: Initializing driver with major=%d, minor=%d\n",
            switches_major, switches_minor);
 
-    // 检查主设备号是否有效
     if (switches_major <= 0)
     {
         printk(KERN_ALERT "switches: Invalid major number %d\n", switches_major);
         return -EINVAL;
     }
 
-    // 构建设备号
     dev_num = MKDEV(switches_major, switches_minor);
 
-    // 注册设备号 - 使用指定的主设备号
     result = register_chrdev_region(dev_num, 1, DEVICE_NAME);
     if (result < 0)
     {
@@ -205,7 +193,6 @@ int switches_init(void)
     printk(KERN_INFO "switches: Registered with major=%d, minor=%d\n",
            MAJOR(dev_num), MINOR(dev_num));
 
-    // 分配设备结构体
     dev = kmalloc(sizeof(struct switches_dev), GFP_KERNEL);
     if (!dev)
     {
@@ -215,7 +202,6 @@ int switches_init(void)
     memset(dev, 0, sizeof(struct switches_dev));
     init_waitqueue_head(&dev->read_wait);
 
-    // 分配缓冲区
     dev->buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
     if (!dev->buffer)
     {
@@ -223,16 +209,13 @@ int switches_init(void)
         goto fail_buffer;
     }
 
-    // 初始化互斥锁
     mutex_init(&dev->lock);
 
     INIT_DELAYED_WORK(&dev->delay_work1, delay_work_func);
 
-    // 初始化字符设备
     cdev_init(&dev->cdev, &fops);
     dev->cdev.owner = THIS_MODULE;
 
-    // 添加字符设备到系统
     result = cdev_add(&dev->cdev, dev_num, 1);
     if (result)
     {
@@ -240,7 +223,6 @@ int switches_init(void)
         goto fail_cdev;
     }
 
-    // 创建设备类
     char_class = class_create(THIS_MODULE, CLASS_NAME);
     if (IS_ERR(char_class))
     {
@@ -249,7 +231,6 @@ int switches_init(void)
         goto fail_class;
     }
 
-    // 创建设备
     char_device = device_create(char_class, NULL, dev_num, NULL, DEVICE_NAME);
     if (IS_ERR(char_device))
     {
@@ -276,7 +257,6 @@ fail_malloc:
     return result;
 }
 
-// 模块退出
 void switches_exit(void)
 {
     cancel_delayed_work_sync(&dev->delay_work1);

+ 13 - 13
test_app/lcd_app.c

@@ -8,7 +8,7 @@
 
 #define LCD_DEVICE "/dev/lcd2002"
 
-/* IOCTL 命令定义 - 必须与驱动一致 */
+/* IOCTL command definition - must be consistent with the driver */
 #define LCD_IOCTL_MAGIC     'L'
 #define LCD_IOCTL_CLEAR     _IO(LCD_IOCTL_MAGIC, 0)
 #define LCD_IOCTL_HOME      _IO(LCD_IOCTL_MAGIC, 1)
@@ -20,7 +20,7 @@ struct lcd_pos {
     unsigned char row;
 };
 
-/* 显示控制参数 */
+/* Display control parameters */
 #define DISPLAY_ON  0x04
 #define DISPLAY_OFF 0x00
 #define CURSOR_ON   0x02
@@ -40,7 +40,7 @@ void test_basic_display(void)
     write(fd, "Hello, Intel ADL!", 17);
     sleep(2);
     
-    /* 写入第二行 */
+    /* write to the second line */
     struct lcd_pos pos = {0, 1};
     ioctl(fd, LCD_IOCTL_SET_CURSOR, &pos);
     write(fd, "N97 Platform", 12);
@@ -58,17 +58,17 @@ void test_cursor_and_blink(void)
     ioctl(fd, LCD_IOCTL_SET_CURSOR, &pos);
     write(fd, "See me?", 7);
     
-    /* 打开光标 */
+    /* Turn on the cursor */
     unsigned char ctrl[3] = {DISPLAY_ON, CURSOR_ON, BLINK_OFF};
     ioctl(fd, LCD_IOCTL_DISPLAY_CTRL, ctrl);
     sleep(2);
     
-    /* 打开闪烁 */
+    /* Turn on the flashing */
     ctrl[2] = BLINK_ON;
     ioctl(fd, LCD_IOCTL_DISPLAY_CTRL, ctrl);
     sleep(2);
     
-    /* 恢复正常 */
+    /* return to normal*/
     ctrl[1] = CURSOR_OFF;
     ctrl[2] = BLINK_OFF;
     ioctl(fd, LCD_IOCTL_DISPLAY_CTRL, ctrl);
@@ -80,7 +80,7 @@ void test_long_text_wrap(void)
     
     ioctl(fd, LCD_IOCTL_CLEAR);
     
-    /* 写入超过20个字符,测试自动换行 */
+    /* Write more than 20 characters to test automatic line wrapping */
     write(fd, "This is a long text that should wrap to next line automatically", 61);
     sleep(3);
 }
@@ -90,11 +90,11 @@ void test_special_chars(void)
     printf("Test 4: Special Characters\n");
     
     ioctl(fd, LCD_IOCTL_CLEAR);
-    write(fd, "Line1\nLine2", 11);  /* \n应该换行 */
+    write(fd, "Line1\nLine2", 11);  /* \nShould wrap */
     sleep(2);
     
     ioctl(fd, LCD_IOCTL_CLEAR);
-    write(fd, "Test\rOverwrite", 14);  /* \r应该回车 */
+    write(fd, "Test\rOverwrite", 14);  /* \rshould press Enter */
     sleep(2);
 }
 
@@ -107,12 +107,12 @@ void test_full_display(void)
     char line1[21], line2[21];
     int i;
     
-    /* 第一行数字 */
+    /* the first line of numbers */
     for (i = 0; i < 20; i++)
         line1[i] = '0' + (i % 10);
     line1[20] = '\0';
     
-    /* 第二行字母 */
+    /* The second letter */
     for (i = 0; i < 20; i++)
         line2[i] = 'A' + (i % 26);
     line2[20] = '\0';
@@ -155,7 +155,7 @@ int main(int argc, char *argv[])
     
     printf("LCD opened successfully\n\n");
     
-    /* 运行测试 */
+    /* Run Test */
     test_basic_display();
     printf("\n");
     
@@ -174,7 +174,7 @@ int main(int argc, char *argv[])
     test_clear_and_home();
     printf("\n");
     
-    /* 结束显示 */
+    /* End Display */
     ioctl(fd, LCD_IOCTL_CLEAR);
     write(fd, "Test Complete!", 14);
     struct lcd_pos pos = {4, 1};

+ 0 - 7
test_app/power_app.c

@@ -16,7 +16,6 @@ int main() {
     char buffer[BUFFER_SIZE];
     int ret;
 
-    // 1. 以非阻塞方式打开设备节点(也可以阻塞,但select会管理)
     fd = open(DEVICE_PATH, O_RDONLY | O_NONBLOCK);
     if (fd < 0) {
         perror("open device failed");
@@ -26,15 +25,12 @@ int main() {
     printf("Waiting for data from %s (select mode)...\n", DEVICE_PATH);
 
     while (1) {
-        // 2. 清空文件描述符集,并加入我们的fd
         FD_ZERO(&read_fds);
         FD_SET(fd, &read_fds);
 
-        // 3. 设置超时时间(例如5秒)
         timeout.tv_sec = 5;
         timeout.tv_usec = 0;
 
-        // 4. 等待fd可读
         ret = select(fd + 1, &read_fds, NULL, NULL, &timeout);
 
         if (ret < 0) {
@@ -46,7 +42,6 @@ int main() {
             continue;
         }
 
-        // 5. 检查是否是我们的fd可读
         if (FD_ISSET(fd, &read_fds)) {
             memset(buffer, 0, BUFFER_SIZE);
             ret = read(fd, buffer, BUFFER_SIZE - 1);
@@ -60,8 +55,6 @@ int main() {
                 break;
             } else {
                 printf("Received %d bytes: %s\n", ret, buffer);
-                // 根据实际数据格式处理
-                // 例如解析电池电量等信息
                 if (strstr(buffer, "battery") != NULL) {
                     printf("  -> Battery related data\n");
                 }

+ 11 - 27
test_app/setss.c

@@ -7,19 +7,19 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 
-// 定义选项结构体
+//7-segment digital tube
 typedef struct {
-    char *f_arg;      // -f 选项的参数
-    int r_flag;       // -r 选项的标志
-    int d_flag;       // -d 选项的标志
-    char *str_arg;    // 最后的字符串参数
+    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");
@@ -32,20 +32,16 @@ void print_usage(const char *program_name) {
     printf("  %s -r -f data.txt world\n", program_name);
 }
 
-// 解析命令行参数
 int parse_arguments(int argc, char *argv[], Options *opts) {
     int opt;
     int ret = 0;
-    int f_option_count = 0;  // 统计 -f 出现的次数
+    int f_option_count = 0; 
     
-    // 初始化选项结构体
     memset(opts, 0, sizeof(Options));
     
-    // 使用getopt循环解析选项
     while ((opt = getopt(argc, argv, "f:rdh")) != -1) {
         switch (opt) {
             case 'f':
-                // -f 选项,必须跟参数
                 flash_flag = atoi(optarg);
                 opts->f_arg = optarg;
                 f_option_count++;
@@ -53,27 +49,23 @@ int parse_arguments(int argc, char *argv[], Options *opts) {
                 break;
                 
             case 'r':
-                // -r 选项,不跟参数
                 read_flag = 1;
                 opts->r_flag = 1;
                 printf("[DEBUG] -r option enabled\n");
                 break;
                 
             case 'd':
-                // -d 选项,不跟参数
                 dp_flag = 1;
                 opts->d_flag = 1;
                 printf("[DEBUG] -d option enabled\n");
                 break;
                 
             case 'h':
-                // 帮助选项
                 print_usage(argv[0]);
-                return 0;  // 正常退出
+                return 0; 
                 
             case '?':
-                // getopt会自动打印错误信息
-                return -1;  // 解析错误
+                return -1;
                 
             default:
                 fprintf(stderr, "Unexpected option: %c\n", opt);
@@ -81,15 +73,12 @@ int parse_arguments(int argc, char *argv[], Options *opts) {
         }
     }
     
-    // 检查 -f 选项出现次数(可选,根据需求)
     if (f_option_count > 1) {
         fprintf(stderr, "Error: -f option can only be used once\n");
         return -1;
     }
     
-    // 检查是否有额外的参数(最后的字符串)
     if (optind < argc) {
-        // 如果有多个剩余参数,取第一个作为字符串,其余的忽略或报错
         if (argc - optind > 1) {
             fprintf(stderr, "Warning: Extra arguments after string will be ignored\n");
         }
@@ -108,16 +97,14 @@ int parse_arguments(int argc, char *argv[], Options *opts) {
 
         printf("[DEBUG] String argument: %s\n", opts->str_arg);
     } else {
-        // 如果没有提供最后的字符串参数,报错
         fprintf(stderr, "Error: Missing required string argument\n");
         print_usage(argv[0]);
         return -1;
     }
     
-    return 1;  // 解析成功
+    return 1;
 }
 
-// 显示解析结果
 void show_results(Options *opts) {
     printf("\n=== Parsing Results ===\n");
     
@@ -147,25 +134,22 @@ int main(int argc, char *argv[]) {
     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");
         return 1;
     }
     
-    // 显示解析结果
     show_results(&opts);
     fd = open("/dev/ssegment", O_RDWR);
     if(fd < 0)

+ 36 - 51
test_app/test_ssegment.c

@@ -6,13 +6,12 @@
 #include <string.h>
 
 #define PORT_80 0x80
-#define SCAN_DELAY 5000  // 5ms扫描延时
+#define SCAN_DELAY 5000
 
-// 7段数码管段码表 (共阴极)
 const unsigned char segment_codes[] = {
     0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,  // 0-7
     0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71,  // 8-F
-    0x00, 0x40                                       // 熄灭, 横杠
+    0x00, 0x40                                       // Off, horizontal bar
 };
 
 typedef struct {
@@ -22,30 +21,23 @@ typedef struct {
 
 DisplayContext ctx = {1, 0};
 
-// 信号处理函数
 void signal_handler(int sig) {
-    printf("\n正在退出...\n");
+    printf("\nExiting...\n");
     ctx.running = 0;
-    outb(0x00, PORT_80);  // 清空显示
+    outb(0x00, PORT_80);  // Clear Display
 }
 
-// 初始化I/O权限
+// Initialize I/O permissions
 int init_io() {
     if (iopl(3) < 0) {
         perror("iopl failed");
         return -1;
     }
     
-    // 或者使用ioperm(更精确的权限控制)
-    // if (ioperm(PORT_80, 2, 1) < 0) {
-    //     perror("ioperm failed");
-    //     return -1;
-    // }
-    
     return 0;
 }
 
-// 显示单个数字在指定位置
+// Display a single number at the specified position
 void display_digit(int digit, int position) {
     unsigned char code;
     
@@ -55,7 +47,7 @@ void display_digit(int digit, int position) {
         code = segment_codes[digit];
     }
     
-    // 位置0使用低4位,位置1使用高4位(取决于硬件连接)
+    // Position 0 uses low 4 bits, and position 1 uses high 4 bits (depending on hardware connection)
     if (position == 0) {
         outb(code, PORT_80);
     } else {
@@ -63,27 +55,27 @@ void display_digit(int digit, int position) {
     }
 }
 
-// 显示两位数字
+// Display two digits
 void display_two_digits(int num) {
     char value = num & 0xff;
     outb(value, PORT_80);
     return;
     int tens = num / 10;
     int ones = num % 10;
-    int scan_count = 50;  // 扫描次数
+    int scan_count = 50; 
     
     for (int i = 0; i < scan_count && ctx.running; i++) {
-        // 显示十位
+        // Display ten digits
         outb(segment_codes[tens], PORT_80);
         usleep(SCAN_DELAY);
         
-        // 显示个位
+        //  Display one digit
         outb(segment_codes[ones], PORT_80);
         usleep(SCAN_DELAY);
     }
 }
 
-// 显示16进制数字
+// Display a number in hexadecimal format
 void display_hex(int value) {
     char values = value & 0xff;
     outb(values, PORT_80);
@@ -97,7 +89,7 @@ void display_hex(int value) {
     // }
 }
 
-// 特效显示:闪烁
+// Display a number in decimal format
 void blink_display(int num, int times) {
     for (int i = 0; i < times && ctx.running; i++) {
         display_two_digits(num);
@@ -108,7 +100,7 @@ void blink_display(int num, int times) {
     }
 }
 
-// 特效显示:滚动
+// Scroll a text message across the display
 void scroll_display(const char *text) {
     int len = strlen(text);
     
@@ -129,38 +121,31 @@ int main(int argc, char *argv[]) {
     int choice = 0;
     int value;
     
-    printf("\n=== Intel ADL N97 Port 80 数码管控制程序 ===\n");
-    printf("版本: 1.0\n");
-    printf("平台: Ubuntu 22.04\n\n");
     
-    // 初始化I/O权限
     if (init_io() < 0) {
-        printf("错误: 无法获取I/O权限,请使用sudo运行\n");
+        printf("error\n");
         return 1;
     }
     
-    // 设置信号处理
     signal(SIGINT, signal_handler);
     
-    // 测试硬件连接
-    printf("正在测试硬件连接...\n");
     for (int i = 0; i < 3 && ctx.running; i++) {
-        outb(0xFF, PORT_80);  // 全亮
+        outb(0xFF, PORT_80);
         usleep(300000);
-        outb(0x00, PORT_80);  // 全灭
+        outb(0x00, PORT_80);
         usleep(200000);
     }
-    printf("测试完成\n\n");
+    printf("test finish\n\n");
     
     while (ctx.running) {
-        printf("\n请选择模式:\n");
-        printf("1. 显示数字 (0-99)\n");
-        printf("2. 显示16进制 (00-FF)\n");
-        printf("3. 闪烁显示\n");
-        printf("4. 滚动显示\n");
-        printf("5. 计数器\n");
-        printf("6. 退出\n");
-        printf("选择: ");
+        printf("\nPlease select a mode:\n");
+        printf("1. Show Numbers (0-99)\n");
+        printf("2. Display Hex (00-FF)\n");
+        printf("3. Flashing display\n");
+        printf("4. Scrolling\n");
+        printf("5. counter\n");
+        printf("6. exit\n");
+        printf("select: ");
         
         if (scanf("%d", &choice) != 1) {
             while(getchar() != '\n');
@@ -169,40 +154,40 @@ int main(int argc, char *argv[]) {
         
         switch(choice) {
             case 1:
-                printf("输入数字 (0-99): ");
+                printf("Enter numbers (0-99): ");
                 scanf("%d", &value);
                 if (value >= 0 && value <= 99) {
-                    printf("显示 %d\n", value);
+                    printf("show %d\n", value);
                     display_two_digits(value);
                 }
                 break;
                 
             case 2:
-                printf("输入16进制值 (00-FF): ");
+                printf("Enter hexadecimal value (00-FF): ");
                 scanf("%x", &value);
                 if (value >= 0 && value <= 0xFF) {
-                    printf("显示 0x%02X\n", value);
+                    printf("show 0x%02X\n", value);
                     display_hex(value);
                 }
                 break;
                 
             case 3:
-                printf("输入数字和闪烁次数: ");
+                printf("Enter numbers and flashes: ");
                 scanf("%d %d", &value, &choice);
                 blink_display(value, choice);
                 break;
                 
             case 4:
-                printf("输入数字串: ");
+                printf("Input digital string: ");
                 char text[10];
                 scanf("%s", text);
                 scroll_display(text);
                 break;
                 
             case 5:
-                printf("计数器模式 (按Ctrl+C退出)\n");
+                printf("Counter mode (press Ctrl+C to exit)\n");
                 for (int i = 0; i <= 99 && ctx.running; i++) {
-                    printf("\r计数: %d", i);
+                    printf("\rcount: %d", i);
                     fflush(stdout);
                     display_two_digits(i);
                 }
@@ -214,13 +199,13 @@ int main(int argc, char *argv[]) {
                 break;
                 
             default:
-                printf("无效选择\n");
+                printf("Invalid selection\n");
         }
     }
     
     // 清理
     outb(0x00, PORT_80);
-    printf("\n程序退出\n");
+    printf("\nexit\n");
     
     return 0;
 }

+ 98 - 106
test_app/watchdog_app.c

@@ -1,11 +1,3 @@
-
-/*
- * it87_wdt_test.c - IT87 看门狗驱动测试程序
- *
- * 编译: gcc -o it87_wdt_test it87_wdt_test.c -Wall
- * 运行: sudo ./it87_wdt_test [选项]
- */
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -17,178 +9,178 @@
 #include <linux/watchdog.h>
 
 #define WATCHDOG_DEV "/dev/watchdog"
-#define DEFAULT_KEEPALIVE 5  // 默认喂狗间隔(秒)
+#define DEFAULT_KEEPALIVE 5
 
 static int wdt_fd = -1;
 static volatile int running = 1;
-static int test_mode = 0;      // 0=正常喂狗, 1=停止喂狗测试重启, 2=触发喂狗后退出
+static int test_mode = 0;      // 0=normal dog feeding, 1=stop dog feeding test restart, 2=exit after triggering dog feeding
 
-/* 信号处理:优雅退出 */
+/* Signal Processing: Graceful Exit */
 static void signal_handler(int sig)
 {
-    printf("\n[%d] 收到信号 %d,准备退出...\n", getpid(), sig);
+    printf("\n[%d] Receive signal %d,exit...\n", getpid(), sig);
     running = 0;
 }
 
-/* 打印使用说明 */
+/* Print instructions */
 static void print_usage(const char *prog)
 {
-    printf("IT87 看门狗驱动测试程序\n\n");
-    printf("用法: %s [选项]\n\n", prog);
-    printf("选项:\n");
-    printf("  -h           显示帮助\n");
-    printf("  -t <秒>      设置喂狗间隔 (默认: %d秒)\n", DEFAULT_KEEPALIVE);
-    printf("  -T <秒>      设置看门狗超时时间 (需要驱动支持)\n");
-    printf("  -m           测试模式: 启动后停止喂狗,测试系统重启\n");
-    printf("  -e           测试模式: 喂狗一次后立即退出(测试 nowayout)\n");
-    printf("  -i           获取看门狗信息\n");
-    printf("  -c           启用魔法关闭字符 'V'\n");
-    printf("  -d           禁用看门狗(如果支持)\n");
-    printf("\n示例:\n");
-    printf("  %s                    # 正常测试,每5秒喂狗\n", prog);
-    printf("  %s -t 2               # 每2秒喂狗一次\n", prog);
-    printf("  %s -m -t 10          # 10秒后停止喂狗,系统应该重启\n", prog);
-    printf("  %s -e                 # 测试 nowayout 模式\n", prog);
-    printf("\n警告: 使用 -m 或 -e 选项会导致系统重启!\n");
+    printf("IT87 Watchdog Driver Test Program\n\n");
+    printf("Usage: %s [Option]\n\n", prog);
+    printf("Option:\n");
+    printf("  -h           Show Help\n");
+    printf("  -t <second>      Set dog feeding interval (Default: %dsecond)\n", DEFAULT_KEEPALIVE);
+    printf("  -T <second>      Set the watchdog timeout (driver support required)\n");
+    printf("  -m           Test mode: Stop feeding the dog after startup, test system reboot\n");
+    printf("  -e           Test mode: Exit immediately after feeding the dog once (testing nowayout)\n");
+    printf("  -i           Get watchdog information\n");
+    printf("  -c           Enable magic to close characters 'V'\n");
+    printf("  -d           Disable the watchdog (if supported)\n");
+    printf("\nExample:\n");
+    printf("  %s                    # Normal test, feed the dog every 5 seconds\n", prog);
+    printf("  %s -t 2               # Feed the dog every 2 seconds\n", prog);
+    printf("  %s -m -t 10          # Stop feeding the dog after 10 seconds, the system should restart\n", prog);
+    printf("  %s -e                 # Test nowayout mode\n", prog);
+    printf("\nWarning: Using the -m or -e option will cause the system to restart!\n");
 }
 
-/* 获取看门狗信息 */
+/* Get watchdog information */
 static void get_watchdog_info(int fd)
 {
     struct watchdog_info info;
 
     if (ioctl(fd, WDIOC_GETSUPPORT, &info) < 0) {
-        perror("WDIOC_GETSUPPORT 失败");
+        perror("WDIOC_GETSUPPORT Failure");
         return;
     }
 
-    printf("\n========== 看门狗信息 ==========\n");
-    printf("标识: %s\n", info.identity);
-    printf("固件版本: %u\n", info.firmware_version);
-    printf("选项支持:\n");
-    if (info.options & WDIOF_OVERHEAT)    printf("  - 过热检测\n");
-    if (info.options & WDIOF_FANFAULT)    printf("  - 风扇故障\n");
-    if (info.options & WDIOF_EXTERN1)     printf("  - 外部信号1\n");
-    if (info.options & WDIOF_EXTERN2)     printf("  - 外部信号2\n");
-    if (info.options & WDIOF_POWERUNDER)  printf("  - 电源不足\n");
-    if (info.options & WDIOF_CARDRESET)   printf("  - 卡片重启\n");
-    if (info.options & WDIOF_POWEROVER)   printf("  - 电源过载\n");
-    if (info.options & WDIOF_SETTIMEOUT)  printf("  - 设置超时时间 ✓\n");
-    if (info.options & WDIOF_MAGICCLOSE)  printf("  - 魔法关闭 ✓\n");
-    if (info.options & WDIOF_PRETIMEOUT)  printf("  - 预超时\n");
-    if (info.options & WDIOF_ALARMONLY)   printf("  - 仅报警\n");
-    if (info.options & WDIOF_KEEPALIVEPING) printf("  - 喂狗支持 ✓\n");
+    printf("\n========== Watchdog Information ==========\n");
+    printf("Logo: %s\n", info.identity);
+    printf("Firmware Version: %u\n", info.firmware_version);
+    printf("Option support:\n");
+    if (info.options & WDIOF_OVERHEAT)    printf("  - Overheat Detection\n");
+    if (info.options & WDIOF_FANFAULT)    printf("  - Fan malfunction\n");
+    if (info.options & WDIOF_EXTERN1)     printf("  - External signal1\n");
+    if (info.options & WDIOF_EXTERN2)     printf("  - External signal2\n");
+    if (info.options & WDIOF_POWERUNDER)  printf("  - Insufficient power\n");
+    if (info.options & WDIOF_CARDRESET)   printf("  - Card restart\n");
+    if (info.options & WDIOF_POWEROVER)   printf("  - Power overload\n");
+    if (info.options & WDIOF_SETTIMEOUT)  printf("  - Set timeout ✓\n");
+    if (info.options & WDIOF_MAGICCLOSE)  printf("  - Magic Off ✓\n");
+    if (info.options & WDIOF_PRETIMEOUT)  printf("  - Pre-timeout\n");
+    if (info.options & WDIOF_ALARMONLY)   printf("  - Alarm only\n");
+    if (info.options & WDIOF_KEEPALIVEPING) printf("  - Support feeding the dog ✓\n");
     printf("================================\n\n");
 }
 
-/* 获取当前超时时间 */
+/* Get the current timeout */
 static int get_timeout(int fd)
 {
     int timeout = 0;
     if (ioctl(fd, WDIOC_GETTIMEOUT, &timeout) < 0) {
-        perror("WDIOC_GETTIMEOUT 失败");
+        perror("WDIOC_GETTIMEOUT fail");
         return -1;
     }
     return timeout;
 }
 
-/* 设置超时时间 */
+/* Set timeout */
 static int set_timeout(int fd, int timeout)
 {
-    printf("设置超时时间为 %d 秒...\n", timeout);
+    printf("Set the timeout to %d second...\n", timeout);
     if (ioctl(fd, WDIOC_SETTIMEOUT, &timeout) < 0) {
-        perror("WDIOC_SETTIMEOUT 失败");
+        perror("WDIOC_SETTIMEOUT fail");
         return -1;
     }
-    printf("实际设置的超时时间: %d 秒\n", timeout);
+    printf("The actual timeout set: %d second\n", timeout);
     return 0;
 }
 
-/* 喂狗(keepalive) */
+/* (keepalive) */
 static int keepalive(int fd)
 {
     int dummy;
     if (ioctl(fd, WDIOC_KEEPALIVE, &dummy) < 0) {
-        perror("WDIOC_KEEPALIVE 失败");
+        perror("WDIOC_KEEPALIVE fail");
         return -1;
     }
     return 0;
 }
 
-/* 禁用看门狗 */
+/* Disable the watchdog */
 static int disable_watchdog(int fd)
 {
-    printf("尝试禁用看门狗...\n");
-    /* 方法1: 魔法关闭字符 */
+    printf("Try to disable the watchdog...\n");
+    /* Method 1: Magic Close Character */
     if (write(fd, "V", 1) != 1) {
-        perror("魔法关闭字符写入失败");
+        perror("Magic failed to write character");
         return -1;
     }
-    printf("已发送魔法关闭字符 'V'\n");
+    printf("Magic shutdown character sent 'V'\n");
     return 0;
 }
 
-/* 主测试循环 */
+/* Main Test Loop */
 static void test_loop(int fd, int keepalive_interval, int mode)
 {
     int count = 0;
     time_t start_time = time(NULL);
 
-    printf("\n========== 开始测试 ==========\n");
+    printf("\n========== Start testing ==========\n");
     printf("PID: %d\n", getpid());
-    printf("喂狗间隔: %d 秒\n", keepalive_interval);
-    printf("当前超时设置: %d 秒\n", get_timeout(fd));
+    printf("Keepalive interval: %d seconds\n", keepalive_interval);
+    printf("Current timeout setting: %d seconds\n", get_timeout(fd));
 
     if (mode == 1) {
-        printf("\n⚠️  测试模式: 将在 %d 秒后停止喂狗,系统应该重启!\n",
+        printf("\n⚠️  Test mode: Will stop feeding the dog after %d seconds, the system should restart!\n",
                keepalive_interval * 3);
     } else if (mode == 2) {
-        printf("\n⚠️  测试模式: 喂狗一次后立即退出,测试 nowayout\n");
+        printf("\n⚠️  Test mode: Exit immediately after feeding the dog once (testing nowayout)\n");
     } else {
-        printf("\n正常模式: 按 Ctrl+C 停止\n");
+        printf("\nNormal mode: Press Ctrl+C to stop\n");
     }
     printf("==============================\n\n");
 
-    /* 第一次喂狗(启动看门狗) */
+    /* First keepalive (start watchdog) */
     if (keepalive(fd) < 0) {
-        fprintf(stderr, "初始喂狗失败\n");
+        fprintf(stderr, "Initial keepalive failed\n");
         return;
     }
-    printf("[%3d] 初始喂狗完成,看门狗已启动\n", count++);
+    printf("[%3d] Initial keepalive completed, watchdog started\n", count++);
 
     if (mode == 2) {
-        /* 测试模式: 立即退出 */
-        printf("立即退出,如果 nowayout=1,系统将在超时后重启\n");
+        /* Test mode: exit immediately */
+        printf("Exit immediately, if nowayout=1, the system will restart after timeout\n");
         return;
     }
 
-    /* 主循环 */
+    /* Main loop */
     while (running) {
         sleep(keepalive_interval);
 
         if (!running)
             break;
 
-        /* 测试模式1: 在指定次数后停止喂狗 */
+        /* Test mode 1: stop feeding after specified times */
         if (mode == 1 && count >= 3) {
-            printf("\n⚠️  故意停止喂狗!系统应在 %d 秒后重启...\n",
+            printf("\n⚠️  Intentionally stop feeding the dog! The system should restart in %d seconds...\n",
                    get_timeout(fd));
-            printf("等待重启中(按 Ctrl+C 可尝试中断)...\n");
+            printf("Waiting for restart (Ctrl+C can try to interrupt)...\n");
 
-            /* 继续循环但不喂狗 */
+            /* Continue loop but don't feed */
             while (1) {
                 sleep(1);
             }
         }
 
-        /* 正常喂狗 */
+        /* Normal keepalive */
         if (keepalive(fd) < 0) {
-            fprintf(stderr, "喂狗失败\n");
+            fprintf(stderr, "Keepalive failed\n");
             break;
         }
 
         time_t elapsed = time(NULL) - start_time;
-        printf("[%3d] 已喂狗 (运行时间: %ld 秒)\n", count++, elapsed);
+        printf("[%3d] Keepalive fed (running time: %ld seconds)\n", count++, elapsed);
         fflush(stdout);
     }
 }
@@ -202,7 +194,7 @@ int main(int argc, char *argv[])
     int magic_close = 0;
     int disable = 0;
 
-    /* 解析命令行参数 */
+    /* Parse command line arguments */
     while ((opt = getopt(argc, argv, "ht:T:meicd")) != -1) {
         switch (opt) {
         case 'h':
@@ -211,7 +203,7 @@ int main(int argc, char *argv[])
         case 't':
             keepalive_interval = atoi(optarg);
             if (keepalive_interval < 1) {
-                fprintf(stderr, "错误: 喂狗间隔必须 >= 1 秒\n");
+                fprintf(stderr, "Error: keepalive interval must be >= 1 second\n");
                 return 1;
             }
             break;
@@ -219,10 +211,10 @@ int main(int argc, char *argv[])
             new_timeout = atoi(optarg);
             break;
         case 'm':
-            test_mode = 1;  // 停止喂狗测试重启
+            test_mode = 1;  // stop feeding test restart
             break;
         case 'e':
-            test_mode = 2;  // 立即退出测试 nowayout
+            test_mode = 2;  // exit immediately test nowayout
             break;
         case 'i':
             show_info = 1;
@@ -239,30 +231,30 @@ int main(int argc, char *argv[])
         }
     }
 
-    /* 注册信号处理 */
+    /* Register signal handler */
     signal(SIGINT, signal_handler);
     signal(SIGTERM, signal_handler);
 
-    printf("IT87 看门狗测试程序\n");
-    printf("打开设备: %s\n", WATCHDOG_DEV);
+    printf("IT87 Watchdog Test Program\n");
+    printf("Opening device: %s\n", WATCHDOG_DEV);
 
-    /* 打开看门狗设备 */
-    /* O_CLOEXEC: 防止子进程继承,但看门狗通常需要保持打开 */
+    /* Open watchdog device */
+    /* O_CLOEXEC: prevent child process inheritance, but watchdog usually needs to stay open */
     wdt_fd = open(WATCHDOG_DEV, O_WRONLY);
     if (wdt_fd < 0) {
-        perror("无法打开看门狗设备(需要 root 权限?)");
-        fprintf(stderr, "提示: 尝试 sudo %s\n", argv[0]);
+        perror("Cannot open watchdog device (need root privileges?)");
+        fprintf(stderr, "Hint: try sudo %s\n", argv[0]);
         return 1;
     }
 
-    printf("设备打开成功 (fd=%d)\n", wdt_fd);
+    printf("Device opened successfully (fd=%d)\n", wdt_fd);
 
-    /* 获取信息 */
+    /* Get information */
     if (show_info) {
         get_watchdog_info(wdt_fd);
     }
 
-    /* 设置新的超时时间 */
+    /* Set new timeout */
     if (new_timeout > 0) {
         if (set_timeout(wdt_fd, new_timeout) < 0) {
             close(wdt_fd);
@@ -270,37 +262,37 @@ int main(int argc, char *argv[])
         }
     }
 
-    /* 显示当前超时 */
+    /* Show current timeout */
     int current_timeout = get_timeout(wdt_fd);
     if (current_timeout > 0) {
-        printf("当前看门狗超时: %d 秒\n", current_timeout);
+        printf("Current watchdog timeout: %d seconds\n", current_timeout);
     }
 
-    /* 禁用看门狗 */
+    /* Disable watchdog */
     if (disable) {
         if (disable_watchdog(wdt_fd) < 0) {
-            fprintf(stderr, "禁用看门狗失败(可能 nowayout=1)\n");
+            fprintf(stderr, "Failed to disable watchdog (nowayout may be 1)\n");
         }
         close(wdt_fd);
         return 0;
     }
 
-    /* 主测试循环 */
+    /* Main test loop */
     test_loop(wdt_fd, keepalive_interval, test_mode);
 
-    /* 清理 */
-    printf("\n关闭看门狗设备...\n");
+    /* Cleanup */
+    printf("\nClosing watchdog device...\n");
 
     if (magic_close) {
-        /* 尝试魔法关闭 */
-        printf("发送魔法关闭字符 'V'...\n");
+        /* Try magic close */
+        printf("Sending magic close character 'V'...\n");
         if (write(wdt_fd, "V", 1) != 1) {
-            perror("魔法关闭失败");
+            perror("Magic close failed");
         }
     }
 
     close(wdt_fd);
-    printf("测试程序结束\n");
+    printf("Test program ended\n");
 
     return 0;
 }

+ 2 - 26
writeprotect.c

@@ -18,9 +18,8 @@
 #define CLASS_NAME "writeprotect_class"
 #define BUFFER_SIZE 1024
 
-// 可以通过模块参数指定主设备号和次设备号
-static int writeprotect_major = 56; // 默认主设备号
-static int writeprotect_minor = 90;   // 默认次设备号
+static int writeprotect_major = 56; 
+static int writeprotect_minor = 90; 
 module_param(writeprotect_major, int, S_IRUGO);
 module_param(writeprotect_minor, int, S_IRUGO);
 MODULE_PARM_DESC(writeprotect_major, "Major device number");
@@ -31,7 +30,6 @@ static struct device *char_device = NULL;
 static struct cdev my_cdev;
 static dev_t dev_num;
 
-// 设备结构体
 struct writeprotect_dev
 {
     char *buffer;
@@ -48,7 +46,6 @@ static void delay_work_func(struct work_struct *work)
     printk(KERN_INFO "delay_work_func\n");
 }
 
-// 文件打开操作
 static int writeprotect_open(struct inode *inode, struct file *filp)
 {
     struct writeprotect_dev *dev;
@@ -61,7 +58,6 @@ static int writeprotect_open(struct inode *inode, struct file *filp)
     return 0;
 }
 
-// 文件释放操作
 static int writeprotect_release(struct inode *inode, struct file *filp)
 {
     // release_region(PORT_80, 1);
@@ -69,7 +65,6 @@ static int writeprotect_release(struct inode *inode, struct file *filp)
     return 0;
 }
 
-// 读操作 - 支持cat命令
 static ssize_t writeprotect_read(struct file *filp, char __user *buf,
                              size_t count, loff_t *f_pos)
 {
@@ -82,7 +77,6 @@ static ssize_t writeprotect_read(struct file *filp, char __user *buf,
     if (mutex_lock_interruptible(&dev->lock))
         return -ERESTARTSYS;
 
-    // 这里read_count没有固定为4个字节,是为了便于后续扩展
     if (count > dev->size)
     {
         read_count = dev->size;
@@ -105,7 +99,6 @@ out:
     return ret;
 }
 
-// 写操作
 static ssize_t writeprotect_write(struct file *filp, const char __user *buf,
                               size_t count, loff_t *f_pos)
 {
@@ -114,19 +107,16 @@ static ssize_t writeprotect_write(struct file *filp, const char __user *buf,
     size_t available;
     int ret = 0;
 
-    // 加锁
     if (mutex_lock_interruptible(&dev->lock))
     {
         return -ERESTARTSYS;
     }
 
-    // 计算可写数据量
     if (count > BUFFER_SIZE)
     {
         count = BUFFER_SIZE;
     }
 
-    // 拷贝数据
     ret = copy_from_user(dev->buffer, buf, count);
     if (ret != 0)
     {
@@ -141,7 +131,6 @@ static ssize_t writeprotect_write(struct file *filp, const char __user *buf,
 out:
     mutex_unlock(&dev->lock);
 
-    // 调度延迟工作
     if (ret == 0)
     {
         schedule_delayed_work(&dev->delay_work1, msecs_to_jiffies(10));
@@ -149,7 +138,6 @@ out:
     return count;
 }
 
-// 文件操作结构体
 static struct file_operations fops = {
     .owner = THIS_MODULE,
     .open = writeprotect_open,
@@ -158,7 +146,6 @@ static struct file_operations fops = {
     .write = writeprotect_write,
 };
 
-// 模块初始化
 int writeprotect_init(void)
 {
     int result;
@@ -166,17 +153,14 @@ int writeprotect_init(void)
     printk(KERN_INFO "writeprotect: Initializing driver with major=%d, minor=%d\n",
            writeprotect_major, writeprotect_minor);
 
-    // 检查主设备号是否有效
     if (writeprotect_major <= 0)
     {
         printk(KERN_ALERT "writeprotect: Invalid major number %d\n", writeprotect_major);
         return -EINVAL;
     }
 
-    // 构建设备号
     dev_num = MKDEV(writeprotect_major, writeprotect_minor);
 
-    // 注册设备号 - 使用指定的主设备号
     result = register_chrdev_region(dev_num, 1, DEVICE_NAME);
     if (result < 0)
     {
@@ -188,7 +172,6 @@ int writeprotect_init(void)
     printk(KERN_INFO "writeprotect: Registered with major=%d, minor=%d\n",
            MAJOR(dev_num), MINOR(dev_num));
 
-    // 分配设备结构体
     dev = kmalloc(sizeof(struct writeprotect_dev), GFP_KERNEL);
     if (!dev)
     {
@@ -197,7 +180,6 @@ int writeprotect_init(void)
     }
     memset(dev, 0, sizeof(struct writeprotect_dev));
 
-    // 分配缓冲区
     dev->buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
     if (!dev->buffer)
     {
@@ -205,16 +187,13 @@ int writeprotect_init(void)
         goto fail_buffer;
     }
 
-    // 初始化互斥锁
     mutex_init(&dev->lock);
 
     INIT_DELAYED_WORK(&dev->delay_work1, delay_work_func);
 
-    // 初始化字符设备
     cdev_init(&dev->cdev, &fops);
     dev->cdev.owner = THIS_MODULE;
 
-    // 添加字符设备到系统
     result = cdev_add(&dev->cdev, dev_num, 1);
     if (result)
     {
@@ -222,7 +201,6 @@ int writeprotect_init(void)
         goto fail_cdev;
     }
 
-    // 创建设备类
     char_class = class_create(THIS_MODULE, CLASS_NAME);
     if (IS_ERR(char_class))
     {
@@ -231,7 +209,6 @@ int writeprotect_init(void)
         goto fail_class;
     }
 
-    // 创建设备
     char_device = device_create(char_class, NULL, dev_num, NULL, DEVICE_NAME);
     if (IS_ERR(char_device))
     {
@@ -258,7 +235,6 @@ fail_malloc:
     return result;
 }
 
-// 模块退出
 void writeprotect_exit(void)
 {
     cancel_delayed_work_sync(&dev->delay_work1);