Browse Source

驱动cash驱动里面的调试代码

liu qidong [url ssh://qidong.liu@10.2.90.253:29418/] 1 tháng trước cách đây
mục cha
commit
5315f3d37d
2 tập tin đã thay đổi với 76 bổ sung72 xóa
  1. 12 19
      cash_drawers.c
  2. 64 53
      test_app/cash_app.c

+ 12 - 19
cash_drawers.c

@@ -28,14 +28,10 @@ struct cashd_device {
     unsigned char *buffer;
     size_t buffer_size;
     wait_queue_head_t read_wait;
-    wait_queue_head_t write_wait;
     struct mutex lock;
     struct cdev cdev;
     int dev_major;
     int dev_minor;
-    bool can_read;
-    bool can_write;
-    unsigned int ctl_status;
     unsigned int in_status;
     unsigned int status_changed;
     int last_status;
@@ -43,7 +39,7 @@ struct cashd_device {
     struct delayed_work delay_work2;
     void __iomem *gpio_ctl_reg_base;
     void __iomem *gpio_status_reg_base;
-    int count;
+    // int count; // debug code
 };
 
 static int cashd_major = 0;
@@ -76,15 +72,16 @@ static void gpio_status_delay_work_func(struct work_struct *work)
         dev->status_changed = 1;
         wake_up_interruptible(&dev->read_wait);
     }
-    dev->count++;
-    if(dev->count >= 50)
-    {
-        dev->count = 0;
-        dev->status_changed = 1;
-        printk("%s %s %d\n", __FILE__, __func__, __LINE__);
-        wake_up_interruptible(&dev->read_wait);
-    }
-    printk("%s %s %d\n", __FILE__, __func__, __LINE__);
+
+    // debug code
+    // dev->count++;
+    // if(dev->count >= 50)
+    // {
+    //     dev->count = 0;
+    //     dev->status_changed = 1;
+    //     printk("%s %s %d\n", __FILE__, __func__, __LINE__);
+    //     wake_up_interruptible(&dev->read_wait);
+    // }
     schedule_delayed_work(&dev->delay_work2, msecs_to_jiffies(100));
 }
 
@@ -180,7 +177,7 @@ static ssize_t cashd_write(struct file *filp, const char __user *buf,
     }
     if(dev->buffer[0] == 'o' || dev->buffer[0] == 'O')
     {
-        printk("%s %s %d minor=%d\n", __FILE__, __func__, __LINE__, dev->dev_minor);
+        // printk("%s %s %d minor=%d\n", __FILE__, __func__, __LINE__, dev->dev_minor);
 
         value = readl(dev->gpio_ctl_reg_base);
         value |= 0x1;
@@ -203,7 +200,6 @@ static unsigned int cashd_poll(struct file *filp, poll_table *wait)
         return POLLERR;
     
     poll_wait(filp, &dev->read_wait, wait);
-    // poll_wait(filp, &dev->write_wait, wait);
     
     mutex_lock(&dev->lock);
     if(dev->status_changed)
@@ -237,11 +233,8 @@ static int __init cashd_init_device(struct cashd_device *dev, int minor)
     dev->buffer_size = BUFFER_SIZE;
     dev->dev_major = cashd_major;
     dev->dev_minor = 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);
     INIT_DELAYED_WORK(&dev->delay_work1, gpio_ctl_delay_work_func);

+ 64 - 53
test_app/cash_app.c

@@ -6,18 +6,17 @@
 #include <errno.h>
 #include <sys/select.h>
 #include <sys/time.h>
+#include <pthread.h>
 
 #define BUFFER_SIZE 1024
 
+int mode = 0;
+int fd = 0;
+int thread_run = 1;
 void print_usage(const char *prog_name)
 {
-    fprintf(stderr, "使用方法: %s <mode> <device>\n", prog_name);
-    fprintf(stderr, "  mode: 1 - 阻塞方式读取\n");
-    fprintf(stderr, "        0 - 非阻塞方式读取\n");
-    fprintf(stderr, "  device: 字符设备路径 (例如: /dev/cash0)\n");
-    fprintf(stderr, "示例:\n");
-    fprintf(stderr, "  %s 1 /dev/cash0   # 阻塞方式读取\n", prog_name);
-    fprintf(stderr, "  %s 0 /dev/cash0   # 非阻塞方式读取\n", prog_name);
+    printf("%s 1 /dev/cashd0\n", prog_name);
+    printf("%s 0 /dev/cashd0\n", prog_name);
 }
 
 int set_nonblocking(int fd)
@@ -56,28 +55,29 @@ int set_blocking(int fd)
     return 0;
 }
 
-// 使用 select 实现阻塞读取
 void blocking_read(int fd)
 {
     fd_set read_fds;
+    struct timeval tv;
     char buffer[BUFFER_SIZE];
     int ret;
 
-    printf("阻塞模式:等待数据...\n");
+    printf("wait data...\n");
 
-    while (1)
+    while (thread_run)
     {
         FD_ZERO(&read_fds);
         FD_SET(fd, &read_fds);
+        tv.tv_sec = 1;
+        tv.tv_usec = 0;
 
-        // NULL 表示无限等待,直到有数据可读
-        ret = select(fd + 1, &read_fds, NULL, NULL, NULL);
+        ret = select(fd + 1, &read_fds, NULL, NULL, &tv);
 
         if (ret == -1)
         {
             if (errno == EINTR)
             {
-                continue; // 被信号中断,继续等待
+                continue;
             }
             perror("select error");
             break;
@@ -91,19 +91,18 @@ void blocking_read(int fd)
             if (n > 0)
             {
                 buffer[n] = '\0';
-                printf("读到 %zd 字节: %s\n", n, buffer);
+                printf("read %zd byte: %s\n", n, buffer);
 
-                // 如果读到 "quit" 或 "exit" 则退出
                 if (strncmp(buffer, "quit", 4) == 0 ||
                     strncmp(buffer, "exit", 4) == 0)
                 {
-                    printf("收到退出命令\n");
+                    printf("exit\n");
                     break;
                 }
             }
             else if (n == 0)
             {
-                printf("设备已关闭 (EOF)\n");
+                printf("close\n");
                 break;
             }
             else
@@ -118,7 +117,6 @@ void blocking_read(int fd)
     }
 }
 
-// 使用 select 实现非阻塞读取(带超时检测)
 void nonblocking_read(int fd)
 {
     fd_set read_fds;
@@ -126,87 +124,100 @@ void nonblocking_read(int fd)
     char buffer[BUFFER_SIZE];
     int ret;
 
-    printf("非阻塞模式:\n");
-
-    while (1)
+    while (thread_run)
     {
         memset(buffer, 0, sizeof(buffer));
         ssize_t n = read(fd, buffer, sizeof(buffer) - 1);
 
         if (n > 0)
         {
-            printf("读到 %zd 字节: %s\n", n, buffer);
+            printf("read %zd byte: %s\n", n, buffer);
         }
         sleep(1);
     }
 }
 
+void *read_pthread_func(void *arg)
+{
+    if (mode == 0)
+    {
+        if (set_nonblocking(fd) < 0)
+        {
+            return NULL;
+        }
+        nonblocking_read(fd);
+    }
+    else
+    {
+        if (set_blocking(fd) < 0)
+        {
+            return NULL;
+        }
+        blocking_read(fd);
+    }
+}
+
 int main(int argc, char *argv[])
 {
-    int mode;
     const char *device_path;
-    int fd;
     int open_flags;
+    int ret = 0;
+    char cmd = 0;
+    pthread_t  read_thread = 0;
 
-    // 检查参数
     if (argc != 3)
     {
         print_usage(argv[0]);
         return 1;
     }
 
-    // 解析模式
     mode = atoi(argv[1]);
     if (mode != 0 && mode != 1)
     {
-        fprintf(stderr, "错误: mode 必须是 0 或 1\n");
         print_usage(argv[0]);
         return 1;
     }
 
     device_path = argv[2];
-
-    // 打开设备
-    // 注意:select 对常规文件总是返回可读,但对字符设备通常能正确工作
-    // 为了更好的演示,我们以读写方式打开
     open_flags = O_RDWR;
 
     fd = open(device_path, open_flags);
     if (fd < 0)
     {
-        perror("打开设备失败");
-        fprintf(stderr, "设备: %s\n", device_path);
+        perror("open fail:");
         return 1;
     }
 
-    printf("成功打开设备: %s\n", device_path);
+    pthread_create(&read_thread, NULL, read_pthread_func, NULL);
 
-    // 根据模式设置阻塞/非阻塞
-    if (mode == 0)
+
+    while(1)
     {
-        // 非阻塞模式:设置 O_NONBLOCK 标志
-        if (set_nonblocking(fd) < 0)
+        printf("please input cmd: o/O-open q-quit\n");
+        scanf(" %c", &cmd);
+
+        if (cmd == 'o' || cmd == 'O')
         {
-            close(fd);
-            return 1;
+            ret = write(fd, &cmd, 1);
+            if (ret < 0)
+            {
+                perror("write fail:");
+                break;
+            }
         }
-        printf("设置为非阻塞模式\n");
-        nonblocking_read(fd);
-    }
-    else
-    {
-        // 阻塞模式:确保清除 O_NONBLOCK 标志
-        if (set_blocking(fd) < 0)
+        else if( cmd == 'q')
         {
-            close(fd);
-            return 1;
+            break;
+        }
+        else
+        {
+            printf("input error\n");
         }
-        printf("设置为阻塞模式\n");
-        blocking_read(fd);
     }
+    thread_run = 0;
+    pthread_join(read_thread, NULL);
 
     close(fd);
-    printf("程序退出\n");
 
     return 0;
-}
+}