c">目录
c" style="margin-left:40px;">1、 解决韦东山老师irda模块中断申请失败的bug
client%E6%B7%BB%E5%8A%A0%E5%A4%84%E7%90%86%E7%A8%8B%E5%BA%8F-toc" style="margin-left:40px;">2、 client添加处理程序
c" style="margin-left:40px;">3、 添加服务器处理程序和驱动处理句柄
c" style="margin-left:40px;">4、 处理数据读出不准确问题
c" style="margin-left:40px;">5、 修改后的展示
c="https://img-blog.csdnimg.cn/direct/1867aaf3fe984c95a1c046304a5c81f3.png" width="1200" />
irda需要通过中断来触发读操作c;申请中断需要引脚是输入模式c;但是先插入电机后引脚会变成输出模式c;所以插入驱动会报错。只要在init时加上一个引脚方向调整就好了。
<code class="language-cpp">/* 在入口函数 */ static int __init irda_init(void) {int err;int i;int count = sizeof(gpios)/sizeof(gpios[0]);printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);/*设置GPIO为输入方向*/err = gpio_direction_input(gpios[i].gpio);for (i = 0; i < count; i++){ gpios[i].irq = gpio_to_irq(gpios[i].gpio);setup_timer(&gpios[i].key_timer, key_timer_expire, (unsigned long)&gpios[i]);//timer_setup(&gpios[i].key_timer, key_timer_expire, 0);err = request_irq(gpios[i].irq, gpio_key_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, gpios[i].name, &gpios[i]);}/* 注册file_operations */major = register_chrdev(0, "cebss_irda", &gpio_key_drv); /* /dev/gpio_desc */gpio_class = class_create(THIS_MODULE, "cebss_irda_class");if (IS_ERR(gpio_class)) {printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major, "cebss_gpio_key");return PTR_ERR(gpio_class);}device_create(gpio_class, NULL, MKDEV(major, 0), NULL, "CEBSS_irda"); /* /dev/irda */return err; }code>
c="https://img-blog.csdnimg.cn/direct/007dfd7c97204b959fc367b528d9e868.png" width="872" />
<code class="language-cpp">/* TODO 传递参数后需改为使用通信结构体 */ /* TODO 所有的魔鬼数字都要进行定义 */ int select_driver(char * cmd, int acceptfd) {int opt = 0;int get_data = 0;MSG drv_msg;char *tx_buffer;char buf[32];char *irda_data="";DIRECTION direction;CMD drv_cmd;if('@' == cmd[0]){ #if (STD_ON == DEBUG)printf("cmd[0] = @\n"); #endif/*STD_ON == DEBUG*/drv_msg.device = extract_digit_number(cmd, 1, 3);printf("device is %d\n", drv_msg.device);/*TODO 后续需升级为多线程模式调用驱动*/switch(drv_msg.device){case 0:/*TODO 日志打印等级控制*//*TODO用设备结构体后这里要封装一下*/printf("LED!!!\n");if ('g' == cmd[4]){direction = direction_get;drv_cmd = cmd_no;led_handle(direction, &drv_cmd);if (cmd_close == drv_cmd){tx_buffer = "@000g0";}else if(cmd_open == drv_cmd){tx_buffer = "@000g1";}}else{if ('1' == cmd[5])drv_cmd = cmd_open;else if ('0' == cmd[5])drv_cmd = cmd_close;direction = direction_put;if (NOERROR == led_handle(direction, &drv_cmd)){tx_buffer = "@000p1";}else{tx_buffer = "@000p0";}} if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0){perror("send failed"); }break;case 1:printf("SR501!!!\n");/*TODO 这里封装成带回调函数的处理函数通过传入处理函数做数据处理*/if ('g' == cmd[4]){sr501_handle(&get_data);if (sr501_some == get_data){tx_buffer = "@001g1";}else if(sr501_nobody == get_data){tx_buffer = "@001g0";}} if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0){perror("send failed"); }break;case 2:printf("SR04!!!\n");if ('g' == cmd[4]){opt = sr04_handle(&get_data);if (NOERROR == opt){sprintf(buf,"@002g%03d", get_data);tx_buffer = buf;}else{tx_buffer = "@002e";}}printf(">>>>>>%s\n",tx_buffer); if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0){perror("send failed"); }break;case 3:printf("IRDA!!!\n");if ('g' == cmd[4]){opt = irda_handle(irda_data);if (NOERROR == opt){sprintf(buf,"@003g%s", irda_data);tx_buffer = buf;}else{tx_buffer = "@003e";}}printf(">>>>>>%s\n",tx_buffer); if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0){perror("send failed"); }break;case 4:printf("motor!!!\n");if ('s' == cmd[4]){if(0 == cmd[5]){/*/0 /n*/get_data = extract_digit_number(cmd, 6, (strlen(&cmd[5])-2));}else{get_data = -extract_digit_number(cmd, 6, (strlen(&cmd[5])-2));}printf("getdata == %d\n",get_data);opt = motor_handle(get_data);if (NOERROR == opt){tx_buffer = "@004s";}else{tx_buffer = "@004e";}} if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0){perror("send failed"); }break;case 5:printf("dht11!!!\n");break;case 6:printf("ds18b20!!!\n");break;case 7:printf("IIC!!!\n");break;case 8:printf("SPI!!!\n");break;default:printf("Unknown equipment!!!\n");}}else{printf("cmd[0] ERROR!!!\n");opt = ERROR;}opt = atoi(&cmd[1]);return opt; }code>
<code class="language-cpp">/* *author : xintianyu *function : Handle irda Settings *date : 2024-4-19 ----------------------- author date modify*/ int irda_handle(char *data) {/*传入参数后面要做通用处理使用空指针*/char *device = "/dev/CEBSS_irda";int buf[2];int ret = NOERROR;static int fd;/* 打开文件 */fd = open(device, O_RDWR);if (fd == -1){printf("can not open file %s\n", device);return ERROR;} read:if (read(fd, buf, 2) == 2){printf("get irda: deivce 0x%02x, data 0x%02x\n", buf[0], buf[1]);switch(buf[1]){case 0x00: goto read;case 0xa2: data="RED";break;case 0xe2: data="MENU";break;case 0x22: data="TEST";break;case 0x02: data="+";break;case 0xe0: data="back";break;default:data="";printf("no this key!!!\n");break;}}else{printf("get irda: -1\n");ret = ERROR;}close(fd);return ret; }code>
除非一直读不然会导致读出的数据都堆积
c="https://img-blog.csdnimg.cn/direct/9f8b29e920de4174a73c0605abd55538.png" width="1198" />
<code class="language-cpp">/* *author : xintianyu *function : Handle irda Settings *date : 2024-4-19 ----------------------- author date modify*/ int irda_handle(char *data) {/*传入参数后面要做通用处理使用空指针*/char *device = "/dev/CEBSS_irda";unsigned char buf[2];int ret = NOERROR;static int fd;/* 打开文件 */fd = open(device, O_RDWR);if (fd == -1){printf("can not open file %s\n", device);return ERROR;} read:if (read(fd, buf, 2) == 2){printf("get irda: deivce 0x%02x, data 0x%02x\n", buf[0], buf[1]);switch(buf[1]){case 0x00: goto read;case 0xa2: data="RED";break;case 0xe2: data="MENU";break;case 0x22: data="TEST";break;case 0x02: data="+";break;case 0xe0: data="back";break;default:data="";printf("no this key!!!\n");break;}}else{printf("get irda: -1\n");ret = ERROR;}close(fd);return ret; }code>
找到问题了c;我的buf是整型的因为是直接从上面copy的
c="https://img-blog.csdnimg.cn/direct/eaf8b6416b5049c28cd6256feb65cc66.png" width="1200" />
驱动这面是char
c="https://img-blog.csdnimg.cn/direct/288aaed7f0aa4191ae2083dde47bc09a.png" width="658" />
现在这面可以读到了
c="https://img-blog.csdnimg.cn/direct/110baa90e18240b7b22e9106869bbac7.png" width="968" />
但是拿到的是空数据
应该是作用域的问题
我不想用数组就用**好了
c="https://img-blog.csdnimg.cn/direct/e452985a18e24fa5aec1f27ba37be457.png" width="528" />
c="https://img-blog.csdnimg.cn/direct/8202ca5c714a4f018a4c86481e9a2a9b.png" width="900" />
果然可以拿到了c;我在来处理一下数据
client
<code class="language-cpp">''' fuction : 客户端程序 author : 辛天宇 date : 2024-4-13 ------------------------------- author date modify 辛天宇 2024-4-15 结合GUI和网络通信''' import show import tcp import tool import socket import global_vardef send_handle(window, client_socket, values):global_var.TX_BUF = values['txbuff'] print(f"txbuff={global_var.TX_BUF}")# 清理inputwindow['txbuff'].update(value='')data = global_var.TX_BUFclient_socket.sendall(data.encode())def quit_handel(client_socket):cmd='Q'client_socket.sendall(cmd.encode())tcp.disconnect_to_server(client_socket)def motor_handel(window, client_socket, values):i = int(values['MOTOR_I'])global_var.MOTOR_DATA = str(abs(i)%360)if i >= 0:global_var.MOTOR_DIRECTION='0'else:global_var.MOTOR_DIRECTION='1'message = 's'+global_var.MOTOR_DIRECTION+global_var.MOTOR_DATA# 清理inputwindow['MOTOR_I'].update(value='0')set_tx_buf('motor', message)send_cmd(client_socket)# 进行一次发送 def send_cmd(client_socket):data = global_var.TX_BUFclient_socket.sendall(data.encode())# 设置发送消息 def set_tx_buf(device, message): if device == 'sr04':global_var.TX_BUF = '@002'+messageif device == 'led':global_var.TX_BUF = '@000'+messageelif device == 'sr501':global_var.TX_BUF = '@001'+messageelif device == 'irda':global_var.TX_BUF = '@003'+messageelif device == 'motor':global_var.TX_BUF = '@004'+messageelif device == 'dht11':global_var.TX_BUF = '@005'+messageprint(f"dht11={global_var.TX_BUF}")elif device == 'ds18b20':global_var.TX_BUF = '@006'elif device == 'iic':global_var.TX_BUF = '@007'elif device == 'spi':global_var.TX_BUF = '@008'# 处理数据 def cmd_handle(window):cmd = global_var.RX_BUFif len(cmd) < 4:print("cmd ERROR")return -1if '@' == cmd[0]:# 目前驱动设备数量只有两位数if cmd[1] == '0':# LED: @000+1位命令位+1位数据位if cmd[2] == '0' and cmd[3] == '0':if cmd[5] == '1':print("LED Status change success")elif cmd[5] == '0':print("LED Status change failure")else:print("message ERROR")# SR501:@001+1位数据位elif cmd[2] == '0' and cmd[3] == '1':if cmd[5] == '1':print("有人")message='有人'window['SR501_O'].update(message)elif cmd[5] == '0':print("无人")message='无人'window['SR501_O'].update(message)else:print("message ERROR")# SR04elif cmd[2] == '0' and cmd[3] == '2':if cmd[4] == 'g':global_var.SR04_DATA = cmd[5:8]message = f"{global_var.SR04_DATA}cm"window['SR04_O'].update(message)else:print("SR04: message ERROR") #irdaelif cmd[2] == '0' and cmd[3] == '3':# message = cmd[5]# print(message)if cmd[4] == 'g':if cmd[5] == 'r':global_var.IRDA_DATA = "RED"elif cmd[5] == 'm':global_var.IRDA_DATA = "MENU"elif cmd[5] == 't':global_var.IRDA_DATA = "TEST"elif cmd[5] == '+':global_var.IRDA_DATA = "+"elif cmd[5] == 'b':global_var.IRDA_DATA = "BACK"elif cmd[5] == 'l':global_var.IRDA_DATA = "LEFT"elif cmd[5] == 'p':global_var.IRDA_DATA = "START"elif cmd[5] == 'r':global_var.IRDA_DATA = "RIGHT"elif cmd[5] == '0':global_var.IRDA_DATA = "0"elif cmd[5] == '1':global_var.IRDA_DATA = "1"elif cmd[5] == '2':global_var.IRDA_DATA = "2"elif cmd[5] == '-':global_var.IRDA_DATA = "-"elif cmd[5] == 'c':global_var.IRDA_DATA = "c"elif cmd[5] == '3':global_var.IRDA_DATA = "3"elif cmd[5] == '4':global_var.IRDA_DATA = "4"elif cmd[5] == '5':global_var.IRDA_DATA = "5"elif cmd[5] == '6':global_var.IRDA_DATA = "6"elif cmd[5] == '7':global_var.IRDA_DATA = "7"elif cmd[5] == '8':global_var.IRDA_DATA = "8"elif cmd[5] == '9':global_var.IRDA_DATA = "9"window['IRDA_O'].update(global_var.IRDA_DATA)#motorelif cmd[2] == '0' and cmd[3] == '4':if cmd[4] == 's':print("MOTOR: message SCUESS") else:print("MOTOR: message ERROR") #dht11elif cmd[2] == '0' and cmd[3] == '5':print(cmd[4:])global_var.TEM=cmd[4]+cmd[5]global_var.HUM=cmd[6]+cmd[7]#ds18b20elif cmd[2] == '0' and cmd[3] == '6':print(cmd[4:])#iicelif cmd[2] == '0' and cmd[3] == '7':print(cmd[4:])#spielif cmd[2] == '0' and cmd[3] == '8':print(cmd[4:])# 处理事件 def event_handle(window, client_socket):led = 0# 事件循环 while True: try:cmd_handle(window)event, values = window.read()if event == 'input':window['txbuff'].update(disabled=not values['input'])elif event == 'send':send_handle(window, client_socket, values)elif event == 'Clean':window['Output'].update(value='')elif event == 'dht11':set_tx_buf('dht11', '2525')send_cmd(client_socket)message = f"{global_var.TEM}°C {global_var.HUM}%"window['Getvalue'].update(message)elif event == 'ds18b20':set_tx_buf('ds18b20')send_cmd(client_socket)message = f"{global_var.TEM}°C"window['Getvalue'].update(message)elif event == 'Quit': quit_handel(client_socket) print(f"See you.............")breakelif event is None:print(f"xxxxxxxxxxxxxxxxxxxx")breakelif event == 'LED':if led % 2 == 0:set_tx_buf('led','p1')else:set_tx_buf('led','p0')led+=1if led > 100:led = 0send_cmd(client_socket)elif event == 'SR501':set_tx_buf('sr501','g')send_cmd(client_socket)elif event == 'SR04':set_tx_buf('sr04','g')send_cmd(client_socket)elif event == 'IRDA':set_tx_buf('irda','g')send_cmd(client_socket)elif event == 'MOTOR':motor_handel(window, client_socket, values)# 处理其他事件...except Exception as e:window.close()print(f"An error occurred: {e}")return 0# 接收服务器的响应data = client_socket.recv(512)# 将字节字符串转化为字符串global_var.RX_BUF = data.decode('utf-8')# print(f"rx......{global_var.RX_BUF}") window.close()return 0 def main():# 创建GUI对象window = show.show_window('DefaultNoMoreNagging')# 尝试连接到服务器 client_socket = tcp.connect_to_server()if client_socket is not None: event_handle(window, client_socket)if __name__ == '__main__':main() code>
c="https://img-blog.csdnimg.cn/direct/6a97ea63617e492ba843ad0345c1206d.png" width="891" />
c="https://img-blog.csdnimg.cn/direct/ce3d2ffd6150410abc871cf41e066fb8.png" width="924" />
c="https://img-blog.csdnimg.cn/direct/5543d6efccd644ab8b30c7be114d6c7d.png" width="842" />
按下IRDA会阻塞按下遥控器上的按键解析后会更新。
c="https://img-blog.csdnimg.cn/direct/e413458dfd734e2084cb75b40ec581e6.png" width="1088" />