活动介绍

请优化这段代码,执行ioctl报错无效的参数:#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <netinet/in.h> #include <net/if.h> #include <arpa/inet.h> #include <linux/route.h> int main() { int fd; struct rtentry route; struct sockaddr_in *addr; memset(&route, 0, sizeof(route)); route.rt_dst.sa_family = AF_INET; addr = (struct sockaddr_in *)&route.rt_gateway; addr->sin_family = AF_INET; fd = socket(AF_INET, SOCK_DGRAM, 0); if (ioctl(fd, SIOCRTMSG, &route) == -1) { perror("ioctl"); exit(1); } close(fd); printf("Gateway address: %s\n", inet_ntoa(addr->sin_addr)); return 0; }

时间: 2024-03-10 19:50:09 浏览: 331
这段代码的问题在于使用了已经过时的 SIOCRTMSG ioctl 命令,并且没有对错误进行恰当的处理。可以使用更现代化的方法,如使用 netlink socket 来获取网关地址。以下是更新后的代码: ```c++ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> #include <arpa/inet.h> #define MAX_PAYLOAD 1024 int main() { int sockfd; struct sockaddr_nl sa; struct nlmsghdr *nlh; char buffer[MAX_PAYLOAD]; struct rtmsg *rtm; struct rtattr *rta; int len; memset(&sa, 0, sizeof(sa)); sa.nl_family = AF_NETLINK; nlh = (struct nlmsghdr *)buffer; rtm = (struct rtmsg *)NLMSG_DATA(nlh); nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); nlh->nlmsg_type = RTM_GETROUTE; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (sockfd == -1) { perror("socket"); exit(1); } if (bind(sockfd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { perror("bind"); exit(1); } if (send(sockfd, nlh, nlh->nlmsg_len, 0) == -1) { perror("send"); exit(1); } while ((len = recv(sockfd, buffer, MAX_PAYLOAD, 0)) > 0) { for (nlh = (struct nlmsghdr *)buffer; NLMSG_OK(nlh, len); nlh = NLMSG_NEXT(nlh, len)) { if (nlh->nlmsg_type == NLMSG_DONE) { break; } else if (nlh->nlmsg_type == NLMSG_ERROR) { perror("recv"); exit(1); } else if (nlh->nlmsg_type == RTM_NEWROUTE) { rtm = (struct rtmsg *)NLMSG_DATA(nlh); if (rtm->rtm_table != RT_TABLE_MAIN) { continue; } rta = (struct rtattr *)RTM_RTA(rtm); len = RTM_PAYLOAD(nlh); for (; RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) { if (rta->rta_type == RTA_GATEWAY) { struct in_addr *addr = (struct in_addr *)RTA_DATA(rta); printf("Gateway address: %s\n", inet_ntoa(*addr)); close(sockfd); return 0; } } } } } close(sockfd); return 0; } ``` 这个程序使用 netlink socket 发送 RTM_GETROUTE 请求来获取路由表,并遍历路由表中的每个条目,找到目标路由条目,并从中提取出网关地址。此方法可以避免使用已经过时的 ioctl 命令,并且可以正确地处理错误。
阅读全文

相关推荐

运行报错:sendto: No such device or address,帮我分析代码有没有问题,代码如下:#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include #include #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #include <net/ethernet.h> #define ETH_IF_NAME "eth0" // 使用的网络接口名称 #define TEST_PACKET_SIZE 64 // 测试包大小 #define TEST_PAYLOAD "PHY Loopback Test" int create_raw_socket(const char *ifname) { int sockfd; struct ifreq ifr; // 创建原始套接字 if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { perror("socket"); return -1; } // 获取网络接口索引 memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1); if (ioctl(sockfd, SIOCGIFINDEX, &ifr) < 0) { perror("ioctl SIOCGIFINDEX"); close(sockfd); return -1; } // 绑定套接字到网络接口 struct sockaddr_ll sll; memset(&sll, 0, sizeof(sll)); sll.sll_family = AF_PACKET; sll.sll_ifindex = ifr.ifr_ifindex; sll.sll_protocol = htons(ETH_P_ALL); if (bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0) { perror("bind"); close(sockfd); return -1; } return sockfd; } int send_test_packet(int sockfd, const char *ifname) { char buffer[TEST_PACKET_SIZE]; struct ether_header *eth_hdr = (struct ether_header *)buffer; struct sockaddr_ll sll; struct ifreq ifr; // 获取网络接口的MAC地址 memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1); if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) { perror("ioctl SIOCGIFHWADDR"); return -1; } // 构建以太网帧 memset(buffer, 0, TEST_PACKET_SIZE); memcpy(eth_hdr->ether_dhost, ifr.ifr_hwaddr.sa_data, ETH_ALEN); // 目标MAC地址(回环) memcpy(eth_hdr->ether_shost, ifr.ifr_hwaddr.sa_data, ETH_ALEN); // 源MAC地址 eth_hdr->ether_type = htons(ETH_P_IP); // 以太网类型(IP) // 填充测试数据 memcpy(buffer + sizeof(struct ether

代码是这样写的:#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include #include #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #include <net/ethernet.h> #define ETH_IF_NAME "eth0" // 使用的网络接口名称 #define TEST_PACKET_SIZE 64 // 测试包大小 #define TEST_PAYLOAD "PHY Loopback Test" int create_raw_socket(const char *ifname) { int sockfd; struct ifreq ifr; // 创建原始套接字 if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { perror("socket"); return -1; } // 获取网络接口索引 memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1); if (ioctl(sockfd, SIOCGIFINDEX, &ifr) < 0) { perror("ioctl SIOCGIFINDEX"); close(sockfd); return -1; } // 绑定套接字到网络接口 struct sockaddr_ll sll; memset(&sll, 0, sizeof(sll)); sll.sll_family = AF_PACKET; sll.sll_ifindex = ifr.ifr_ifindex; sll.sll_protocol = htons(ETH_P_ALL); if (bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0) { perror("bind"); close(sockfd); return -1; } return sockfd; } int send_test_packet(int sockfd, const char *ifname) { char buffer[TEST_PACKET_SIZE]; struct ether_header *eth_hdr = (struct ether_header *)buffer; struct sockaddr_ll sll; struct ifreq ifr; // 获取网络接口的MAC地址 memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1); if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) { perror("ioctl SIOCGIFHWADDR"); return -1; } // 构建以太网帧 memset(buffer, 0, TEST_PACKET_SIZE); memcpy(eth_hdr->ether_dhost, ifr.ifr_hwaddr.sa_data, ETH_ALEN); // 目标MAC地址(回环) memcpy(eth_hdr->ether_shost, ifr.ifr_hwaddr.sa_data, ETH_ALEN); // 源MAC地址 eth_hdr->ether_type = htons(ETH_P_IP); // 以太网类型(IP) // 填充测试数据 memcpy(buffer + sizeof(struct ether_header), TEST_PAYLOAD, strlen(TEST_PAYLOAD));

#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include "scull.h" void write_proc(void); void read_proc(void); int main(int argc, char **argv){ if(argc == 1){ puts( "Usage: scull_test [write|read]"); exit(0); } if( !strcmp(argv[1],"write")) write_proc(); else if(!strcmp(argv[1],"read")) read_proc(); else puts( "scull_test: invalid command! "); return 0; } void write_proc(){ int fd, len,quit = 0; char buf[ 100]; fd = open(DEVICE_FILE,O_WRONLY); if(fd <= 0){ printf("Error opening device file %s for writing!\n",DEVICE_FILE); exit(1); } printf( "input 'exit' to exit!"); while( !quit) { printf( "\n write>> "); fgets(buf, 100,stdin); if(!strcmp(buf, "exit\n")) quit =1; while(ioctl(fd,SCULL_QUERY_NEW_MSG)) usleep(1000); len=write(fd, buf, strlen(buf)); if(len<0){ printf( "Error writing to device %s !\n" ,SCULL_NAME); close(fd); exit(1); } printf("%d bytes written to device %s!\n",len- 1,SCULL_NAME); } close(fd); } void read_proc(){ printf("\n read<< "); while(!ioctl(fd,SCULL_QUERY_NEW_MSG)) usleep(1000);// get the msg length len=ioctl(fd, SCULL_QUERY_MSG_LENGTH, NULL); if(len){ if(buf!=NULL) free(buf); buf = malloc(sizeof(char)*(len+1)); len = read(fd, buf, len); if(len < 0){ printf("Error reading from device %s!", SCULL_NAME); }else{ if(!strcmp(buf,"exit\n")){ ioctl(fd, SCULL_RESET); // reset quit = 1; printf("%s\n",buf); }else printf("%s\n",buf); } } free(buf); close(fd); }

#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <termios.h> #include //串口初始化功能函数,fd:串口驱动设备的文件描述符 int tty_init(int fd) { //串口参数结构体 struct termios old_uart,new_uart; //清空结构体变量内容,memset bzero(&old_uart,sizeof(struct termios)); bzero(&new_uart,sizeof(struct termios)); //获取串口属性,旧的串口 tcgetattr(fd,&old_uart); //设置原始属性,重新设置属性 cfmakeraw(&new_uart); //激活本地连接CLOCAL与接收使能CREAD的选项 new_uart.c_cflag |= CLOCAL|CREAD; //设置输出、输入波特率 cfsetospeed(&new_uart, B115200); cfsetispeed(&new_uart, B115200); //设置数据位为8位 new_uart.c_cflag &= ~CSIZE; new_uart.c_cflag |= CS8; //无校验位 new_uart.c_cflag &= ~PARENB; //1个停止位 new_uart.c_cflag &= ~CSTOPB; //设置等待时间、最小接收字符个数 new_uart.c_cc[VTIME] = 0; new_uart.c_cc[VMIN] = 1; new_uart.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //本地模式设置为原始模式 //清空缓冲区 tcflush(fd,TCIOFLUSH); //设置串口属性到文件中 -- 生效属性 tcsetattr(fd, TCSANOW,&new_uart); return 0; } void *BLE_Send(void *arg) { int ble_fd = *(int *)arg; //获取文件描述符 char *s_msg = (char *)malloc(1024); //申请写入数据的空间 while(1) { printf("send:"); //从键盘输入数据保存到msg中 fgets(s_msg,1024,stdin); write(ble_fd,s_msg,strlen(s_msg)); //写数据 if(strncmp(s_msg,"quit",4)==0) { memset(s_msg,0,1024); break; } //清空内存 memset(s_msg,0,1024); } //释放堆空间 free(s_msg); } void *BLE_Recv(void *arg) { int ble_fd = *(int *)arg; //获取文件描述符 char *r_msg = (char *)malloc(1024); //申请接收数据的空间 while(1) { //读取串口接收的数据 read(ble_fd,r_msg,1024); printf("recv:%s\n",r_msg); if(strncmp(r_msg,"quit",4)==0) { memset(r_msg,0,1024); break; } //清空内存 memset(r_msg,0,1024); } //释放堆空间 free(r_msg); } int main(int argc,char *argv[]) { pthread_t ble_tid1=0,ble_tid2=0; //访问串口1驱动 int ble_fd = open("/dev/ttySAC1",O_RDWR); if(ble_fd==-1) { printf("open BLE error...\n"); return -1; } //串口初始化 tty_init(ble_fd); //串口数据读写线程 pthread_create(&ble_tid1,NULL,BLE_Send,(void *)&ble_fd); pthread_create(&ble_tid2,NULL,BLE_Recv,(void *)&ble_fd); //接合线程 pthread_join(ble_tid1,NULL); pthread_join(ble_tid2,NULL); //关闭文件 close(ble_fd); return 0; }用c语言修改代码:使用蓝牙通信,手机发送“prev”显示上一张图片,发送"next"显示下一张图片

我的意思是给#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/mman.h> #include #include <SDL2/SDL.h> // 图形显示库 #define DEVICE "/dev/video0" #define WIDTH 640 #define HEIGHT 480 #define FORMAT V4L2_PIX_FMT_YUYV struct buffer { void *start; size_t length; }; int main() { int fd = open(DEVICE, O_RDWR); // 初始化SDL SDL_Init(SDL_INIT_VIDEO); SDL_Window *window = SDL_CreateWindow("Camera", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, 0); SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0); SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YUY2, // 匹配YUYV格式 SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT); // 精简的V4L2初始化流程(省略错误检查) struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, .fmt.pix = {.width = WIDTH, .height = HEIGHT, .pixelformat = FORMAT} }; ioctl(fd, VIDIOC_S_FMT, &fmt); struct v4l2_requestbuffers req = { .count = 4, .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, .memory = V4L2_MEMORY_MMAP }; ioctl(fd, VIDIOC_REQBUFS, &req); struct buffer *buffers = calloc(req.count, sizeof(*buffers)); for (int i = 0; i < req.count; i++) { struct v4l2_buffer buf = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, .memory = V4L2_MEMORY_MMAP, .index = i }; ioctl(fd, VIDIOC_QUERYBUF, &buf); buffers[i].length = buf.length; buffers[i].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); ioctl(fd, VIDIOC_QBUF, &buf); // 直接入队 } // 启动视频流 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ioctl(fd, VIDIOC_STREAMON, &type); // 精简的显示循环 SDL_Event event; while(1) { SDL_PollEvent(&event); if(event.type == SDL_QUIT) break; struct v4l2_buffer buf = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, .memory = V4L2_MEMORY_MMAP }; ioctl(fd, VIDIOC_DQBUF, &buf); // 获取帧 // 直接渲染到屏幕(无需文件保存) SDL_UpdateTexture(texture, NULL, buffers[buf.index].start, WIDTH*2); SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); ioctl(fd, VIDIOC_QBUF, &buf); // 重新入队 } // 清理资源 ioctl(fd, VIDIOC_STREAMOFF, &type); close(fd); SDL_DestroyTexture(texture); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; } 这个加注释

#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H ----------------------------------------------- #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } 以上两个是.h和.cpp代码 --------------------------------------------------------- <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <rect> <x>0</x> <y>0</y> <width>932</width> <height>628</height> </rect> <string>MainWindow</string> <widget class="QWidget" name="centralwidget"> <widget class="QPushButton" name="pb_connect"> <rect> <x>40</x> <y>20</y> <width>89</width> <height>25</height> </rect> <string>连接</string> </widget> <widget class="QPushButton" name="pb_led0"> <rect> <x>40</x> <y>70</y> <width>89</width> <height>25</height> </rect> <string>led0_on</string> </widget> <widget class="QPushButton" name="pb_led1"> <rect> <x>40</x> <y>110</y> <width>89</width> <height>25</height> </rect> <string>led1_on</string> </widget> <widget class="QPushButton" name="pb_led2"> <rect> <x>40</x> <y>150</y> <width>89</width> <height>25</height> </rect> <string>led2_on</string> </widget> <widget class="QPushButton" name="pb_feng"> <rect> <x>40</x> <y>190</y> <width>89</width> <height>25</height> </rect> <string>feng_on</string> </widget> <widget class="QPushButton" name="pb_buzzer"> <rect> <x>140</x> <y>20</y> <width>89</width> <height>25</height> </rect> <string>蜂鸣器_on</string> </widget> <widget class="QPushButton" name="pb_humiture"> <rect> <x>140</x> <y>70</y> <width>89</width> <height>25</height> </rect> <string>温湿度_on</string> </widget> <widget class="QPushButton" name="pb_photosensitive"> <rect> <x>140</x> <y>110</y> <width>89</width> <height>25</height> </rect> <string>光敏_on</string> </widget> <widget class="QPushButton" name="pb_infrared"> <rect> <x>140</x> <y>150</y> <width>89</width> <height>25</height> </rect> <string>人体红外_on</string> </widget> <widget class="QPushButton" name="pb_camera"> <rect> <x>140</x> <y>190</y> <width>89</width> <height>25</height> </rect> <string>摄像头_on</string> </widget> <widget class="QTextBrowser" name="textBrowser"> <rect> <x>350</x> <y>10</y> <width>421</width> <height>211</height> </rect> </widget> </widget> <widget class="QMenuBar" name="menubar"> <rect> <x>0</x> <y>0</y> <width>932</width> <height>28</height> </rect> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui> 以上是.ui代码 --------------------------------------------------------- 目前项目进度: 当前项目结构如下: DXM1txst: DXM1txst.pro Headers: fsmpBeeper.h fsmpElectric.h fsmpEvents.h fsmpFan.h fsmpLed.h fsmpLight.h fsmpProximity.h fsmpsevensegLed.h fsmpTempHum.h fsmpvibrator.h mainwindow.h Sources: main.cpp mainwindow.cpp Forms: mainwindow.ui qtcreator内:ui界面中已经有组件:pb_connect(连接按钮)、pb_led0(电灯1开关按钮)、pb_led1(电灯2开关按钮)、pb_led2(电灯3开关按钮)、pb_feng(风扇开关按钮)、pb_buzzer(蜂鸣器开关按钮)、pb_humiture(温湿度传感器开关按钮)、pb_photosensitive(光敏传感器开关按钮)、pb_infrared(人体红外传感器开关按钮)、pb_camera(摄像头开关按钮)、textBrowser(用于接收和发布的消息显示)。 华清远见元宇宙实验中心物联网仿真系统内:所需的所以硬件的3D场景设计完毕,M4网关单元的Mqtt配置为: 地址:mqtt.yyzlab.com.cn 端口:1883 与应用层、云端交互的Topic: 订阅:1752365375766/APP2AIOTSIM 发布:1752365375766/AIOTSIM2APP 与硬件交互的Topic: 订阅:1752365382482/Device2AIOTSIM 发布:1752365382482/AIOTSIM2Device 与华清远见元宇宙实验中心物联网仿真系统内硬件开关发布的控制码为:电灯0开:{"lamp":true,"id":0},电灯0关:{"lamp":false,"id":0},电灯1开:{"lamp":true,"id":1},电灯1关:{"lamp":false,"id":1},电灯2开:{"lamp":true,"id":2},电灯2关:{"lamp":false,"id":2},风扇开:{"fan":true,"id":0},风扇关:{"fan":false,"id":0},人体红外传感器开:{"infrared ":true,"id":0},人体红外传感器关:{"infrarrared ":false,"id":0},温湿度传感器:{"tem":38.8,"hum":65.7,"id":0},光敏传感器:{"light":43037.0,"id":0} Stm32mp157开发板:所有需要的硬件部署完毕,硬件的.h代码如下(硬件的.h代码已经放入qtcreator项目下的Headers文件夹下,且硬件的所有.h文件内代码都不能再进行修改): fsmpBeeper.h: #ifndef FSMPBEEPER_H #define FSMPBEEPER_H /*************************************************************************** * * 类名:fsmpBeeper * 功能说明:扩展板 蜂鸣器 * 公有函数: * fsmpBeeper() * bool setRate(uint32_t rate) 设置频率 * bool start(void) 启动蜂鸣器 * bool stop(void) 关闭蜂鸣器 * * 信号: * 无 * * *************************************************************************/ #include <QObject> #include #include <string.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <QIODevice> /* FSMP开发板(linux)蜂鸣器操作类 v0 2023/1/9 by 张城 */ class fsmpBeeper:public QObject{ Q_OBJECT public: explicit fsmpBeeper(const char *device = "/dev/input/event0", QObject *parent = nullptr) :QObject(parent) { event.type = EV_SND; time.tv_sec = 1; time.tv_usec = 0; event.time = time; beeper_fd = ::open(device,O_RDWR); if(beeper_fd < 0) { perror("open_beeper"); return; } }; ~fsmpBeeper() { ::close(beeper_fd); } /* * Description: 设置频率值 * input: rate 频率 * output: null * return: 成功true/失败false */ bool setRate(uint32_t rate = 1000) { if(rate > 0) { event.code = SND_TONE; event.value = rate; return true; } return false; } /* * Description: start设备 * input: null * output: null * return: 成功true/失败false */ bool start(void) { int ret = write(beeper_fd, &event, sizeof(struct input_event)); if(ret < 0) { perror("write"); return false; } return true; } /* * Description: 关闭设备 * input: null * output: null * return: 成功true/失败false */ bool stop(void) { struct input_event event; event.type = EV_SND; event.code = SND_BELL; event.value = 0000; time.tv_sec = 1; time.tv_usec = 0; event.time = time; int ret = write(beeper_fd, &event, sizeof(struct input_event)); if(ret < 0) { perror("write"); return false; } return true; } private: int beeper_fd; //设备文件描述符 struct input_event event; struct timeval time; }; #endif // FSMPBEEPER_H ------------------------------------------------------- fsmpElectric.h: #ifndef ELC_H #define ELC_H /*************************************************************************** * * 类名:fsmpElectric * 功能说明:扩展板 电气信息检测 * 公有函数: * fsmpElectric() * float voltagemV(void) 获取电压mv(旋钮控制) * float currentmA(void) 获取电流ma(板载设备真实电流) * * 信号: * 无 * * *************************************************************************/ #include <QObject> #include #include <string.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <QIODevice> #include <stdint.h> #include <QDebug> class fsmpElectric:public QObject{ Q_OBJECT public: explicit fsmpElectric(QObject *parent = nullptr) :QObject(parent) { } ~fsmpElectric(){ } float voltagemV(void) { electric_fd1 = open("/sys/bus/iio/devices/iio:device3/in_voltage1_raw",O_RDONLY|O_NONBLOCK); if(electric_fd1 < 0) { perror("open"); return -1; } char buf[10] = {0}; int ret = read(electric_fd1,buf,sizeof(buf)); if(ret < 0) { perror("read"); return -1; } int val = 0; sscanf(buf,"%d",&val); ::close(electric_fd1); return (float)3300 * val / 65536; } float currentmA(void) { electric_fd0 = open("/sys/bus/iio/devices/iio:device3/in_voltage0_raw",O_RDONLY|O_NONBLOCK); if(electric_fd0 < 0) { perror("open"); return -1; } char buf[10] = {0}; int ret = read(electric_fd0,buf,sizeof(buf)); if(ret < 0) { perror("read"); return -1; } int val = 0; sscanf(buf,"%d",&val); ::close(electric_fd0); return ((((float)3300 * val) /65536)/(10 + 100*1000 + 1000)) * 1000 / 0.1; } private: int electric_fd0; //设备文件描述符 int electric_fd1; //设备文件描述符 }; #endif // ELC_H ------------------------------------------------------- fsmpEvents.h: #ifndef ENV_H #define ENV_H /*************************************************************************** * * 类名:fsmpEvents * 功能说明:扩展板 按钮、人体红外、光闸管、火焰 * 公有函数: * fsmpEvents() * 信号: * void lightTriggered(); 光闸管阻隔 * void flameDetected(); 火焰检测 * void peopleDetected(bool); 人体红外发现true/离开false * void keyPressed(int keynum); 按键按下 keynum: 1、2、3 * void keyRelessed(int keynum); 按键释放 keynum: 1、2、3 * * *************************************************************************/ #include <QObject> #include #include <string.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <QIODevice> #include <QTimer> #include #include <sys/ioctl.h> #include <QDebug> #include <QProcess> #include <QThread> #include <stdio.h> #include <stdlib.h> class fsmpEvents:public QObject{ Q_OBJECT signals: /* edge trigle !!!*/ void lightTriggered();//光电开关 void flameDetected();//火焰检测 void peopleDetected(bool);//人体红外 void keyPressed(int keynum); void keyRelessed(int keynum); public: explicit fsmpEvents(QObject *parent = nullptr):QObject(parent) { this->gpio_F_open(); this->gpio_E_open(); fs_timer = new QTimer(this); connect(fs_timer,SIGNAL(timeout()),this,SLOT(time_out())); fs_timer->start(10); }; private: bool gpio_F_open(const char *device = "/dev/gpiochip5") { int ret; int fd = open(device,O_RDONLY|O_NONBLOCK); if(fd < 0) { fprintf(stderr,"open"); return false; } event_req.lineoffset = 9; //TODO event_req.handleflags = GPIOHANDLE_REQUEST_INPUT; event_req.eventflags = GPIOEVENT_REQUEST_FALLING_EDGE|GPIOEVENT_REQUEST_RISING_EDGE; ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &event_req); // event测试的时候用这个 if (ret == -1) { ret = -errno; fprintf(stderr, "Failed to issue GET LINEHANDLE IOCTL (%d)\n", ret); } key_1_fd = event_req.fd; int flags = fcntl(key_1_fd,F_GETFL,0); flags |= O_NONBLOCK; fcntl(key_1_fd,F_SETFL,flags); event_req.lineoffset = 8; //TODO event_req.handleflags = GPIOHANDLE_REQUEST_INPUT; event_req.eventflags = GPIOEVENT_REQUEST_BOTH_EDGES; ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &event_req); // event测试的时候用这个 if (ret == -1) { ret = -errno; fprintf(stderr, "Failed to issue GET LINEHANDLE IOCTL (%d)\n", ret); } key_3_fd = event_req.fd; flags = fcntl(key_3_fd,F_GETFL,0); flags |= O_NONBLOCK; fcntl(key_3_fd,F_SETFL,flags); #if 0 event_req.lineoffset = 5; //TODO event_req.handleflags = GPIOHANDLE_REQUEST_INPUT; event_req.eventflags = GPIOEVENT_REQUEST_BOTH_EDGES; ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &event_req); // event测试的时候用这个 if (ret == -1) { ret = -errno; fprintf(stderr, "Failed to issue GET LINEHANDLE IOCTL (%d)\n", ret); } fire_fd = event_req.fd; flags = fcntl(fire_fd,F_GETFL,0); flags |= O_NONBLOCK; fcntl(fire_fd,F_SETFL,flags); #endif // fire req.lineoffsets[0] = 5; req.flags = GPIOHANDLE_REQUEST_INPUT; // strcpy(req.consumer_label, "fire"); req.lines = 1; memcpy(req.default_values, &data, sizeof(req.default_values)); ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req); if (ret == -1) { fprintf(stderr, "Failed to issue %s (%d), %s\n", "GPIO_GET_LINEHANDLE_IOCTL", ret, strerror(errno)); } fire_fd = req.fd; // key2 req.lineoffsets[0] = 7; req.flags = GPIOHANDLE_REQUEST_INPUT; // strcpy(req.consumer_label, "key2"); req.lines = 1; memcpy(req.default_values, &data, sizeof(req.default_values)); ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req); if (ret == -1) { fprintf(stderr, "Failed to issue %s (%d), %s\n", "GPIO_GET_LINEHANDLE_IOCTL", ret, strerror(errno)); } key_2_fd = req.fd; // people req.lineoffsets[0] = 12; req.flags = GPIOHANDLE_REQUEST_INPUT; // strcpy(req.consumer_label, "key2"); req.lines = 1; memcpy(req.default_values, &data, sizeof(req.default_values)); ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req); if (ret == -1) { fprintf(stderr, "Failed to issue %s (%d), %s\n", "GPIO_GET_LINEHANDLE_IOCTL", ret, strerror(errno)); } people_fd = req.fd; return true; } bool gpio_E_open(const char *device = "/dev/gpiochip4") { int ret; int fd = open(device,O_RDONLY|O_NONBLOCK); if(fd < 0) { fprintf(stderr,"open"); return false; } event_req.lineoffset = 15; //TODO event_req.handleflags = GPIOHANDLE_REQUEST_INPUT; event_req.eventflags = GPIOEVENT_REQUEST_BOTH_EDGES; ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &event_req); // event测试的时候用这个 if (ret == -1) { ret = -errno; fprintf(stderr, "Failed to issue GET LINEHANDLE IOCTL (%d)\n", ret); } light_trigger_fd = event_req.fd; int flags = fcntl(light_trigger_fd,F_GETFL,0); flags |= O_NONBLOCK; fcntl(light_trigger_fd,F_SETFL,flags); return true; } /* * Description: 关闭设备 * input: null * output: null * return: 成功true/失败false */ bool close(void); public slots: void time_out() { static int key_1_flag = 0; static int key_2_flag = 0; static int key_3_flag = 0; static int light_trigger_flag = 0; static int people_flag = 0; static int flame_flag = 0; //捕获key_1按下 read(key_1_fd,&event_data,sizeof (event_data)); if(event_data.id == 2) { key_1_flag = 1; emit(this->keyPressed(1)); //qDebug()<<"key_1 pressed"; event_data.id = 0; } else if(event_data.id == 1 && key_1_flag==1) { key_1_flag = 0; emit keyRelessed(1); //qDebug()<<"key_1 relessed"; } event_data.id = 0; //捕获key_2按下 int ret = ioctl(key_2_fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); if (ret == -1) { ret = -errno; fprintf(stderr, "Failed to issue %s (%d), %s\n", "GPIOHANDLE_GET_LINE_VALUES_IOCTL", ret, strerror(errno)); exit(ret); } //qDebug() << "==========" << data.values[0]; if(data.values[0] ==0&&key_2_flag==0) { emit(this->keyPressed(2)); key_2_flag = 1; //qDebug()<<"key_2 pressed"; } else if(data.values[0] ==1&&key_2_flag==1) { key_2_flag = 0; emit keyRelessed(2); //qDebug()<<"key_2 relessed"; } //event_data.id = 0; //捕获key_3按下 read(key_3_fd,&event_data,sizeof (event_data)); //qDebug() << "key3 "<< event_data.id; if(event_data.id == 2 && key_3_flag==0) { key_3_flag = 1; emit(this->keyPressed(3)); //qDebug()<<"key_3 pressed"; event_data.id = 0; } else if(event_data.id == 1 && key_3_flag==1) { key_3_flag = 0; emit keyRelessed(3); //qDebug()<<"key_3 relessed"; } event_data.id = 0; //捕获光电开关 read(light_trigger_fd,&event_data,sizeof (event_data)); if(event_data.id == 1 && light_trigger_flag==0) { //qDebug()<<"light triggered"; light_trigger_flag = 1; emit(this->lightTriggered()); } else light_trigger_flag = 0; event_data.id = 0; //捕获people coming ret = ioctl(people_fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); if (ret == -1) { ret = -errno; fprintf(stderr, "Failed to issue %s (%d), %s\n", "GPIOHANDLE_GET_LINE_VALUES_IOCTL", ret, strerror(errno)); exit(ret); } if(data.values[0] ==1&&people_flag==0) { emit(this->peopleDetected(true)); people_flag = 1; //qDebug()<<"people coming"; } else if(data.values[0] ==0&&people_flag==1) { people_flag = 0; emit(this->peopleDetected(false)); //qDebug()<<"people leave"; } #if 0 //捕获火焰检测 read(fire_fd,&event_data,sizeof (event_data)); qDebug() << "------------------"<<event_data.id; if(event_data.id == 2 && flame_flag == 0) { qDebug()<<"flamedetection on"; flame_flag = 1; emit(this->flameDetected(true)); event_data.id = 0; } else if(event_data.id == 0 && flame_flag == 1) { qDebug()<<"flamedetection off"; flame_flag = 0; emit(this->flameDetected(false)); event_data.id = 0; } #endif //捕获key_2按下 ret = ioctl(fire_fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); if (ret == -1) { ret = -errno; fprintf(stderr, "Failed to issue %s (%d), %s\n", "GPIOHANDLE_GET_LINE_VALUES_IOCTL", ret, strerror(errno)); exit(ret); } //qDebug() << data.values[0]; if(data.values[0] ==1&&flame_flag==0) { emit(this->flameDetected()); flame_flag = 1; //qDebug()<<"flame on"; } else flame_flag = 0; } private: struct gpiohandle_request req; struct gpiohandle_data data; struct gpiochip_info chip_info; struct gpioevent_request event_req; struct gpioevent_data event_data; struct gpiod_chip *gpiochip5; struct gpiod_line *gpioline5_7; int key_1_fd; //设备文件描述符 int key_2_fd; int key_3_fd; int light_trigger_fd; int people_fd; int fire_fd; QTimer * fs_timer; }; #endif //ENV_H ------------------------------------------------------- fsmpFan.h: #ifndef FAN_H #define FAN_H /*************************************************************************** * * 类名:fsmpFan * 功能说明:扩展板 风扇控制 * 公有函数: * fsmpFan() * void start(void) 开启风扇) * void stop(void) 关闭风扇 * void setSpeed(int speed) 设置风扇速度(0-255) * 信号: * 无 * * *************************************************************************/ #include <QObject> #include #include <string.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <QIODevice> class fsmpFan:public QObject{ Q_OBJECT public: explicit fsmpFan(QObject *parent = nullptr):QObject(parent) { const char *device = "/sys/class/hwmon/hwmon1/pwm1"; fan_fd = ::open(device,O_WRONLY|O_TRUNC); if(fan_fd < 0) { perror("open fan"); return; } fan_speed = 0; }; ~fsmpFan(){ ::close(fan_fd); } /* * Description: 关闭设备 * input: null * output: null * return: 成功true/失败false */ void stop(void) { write(fan_fd,"0",strlen("0")); } /* * Description: start设备 * input: null * output: null * return: 成功true/失败false */ void start(void) { char speedstr[100] = {0}; sprintf(speedstr, "%d", fan_speed); write(fan_fd, speedstr, strlen(speedstr)); } /* * Description: 控制风扇转速 * intput: speed 转速 * output: null * return: null */ void setSpeed(int speed) { fan_speed = speed%255; } private: int fan_fd; //设备文件描述符 int fan_speed; }; #endif // FAN_H ------------------------------------------------------- fsmpLeds.h: #ifndef LED_H #define LED_H /*************************************************************************** * * 类名:fsmpLeds * 功能说明:扩展板 3颗灯泡 * 公有函数: * fsmpLeds() * bool on(lednum x) 开灯 lednum: fsmpLeds::LED1/fsmpLeds::LED2/fsmpLeds::LED3 * bool off(lednum x) 关灯 lednum: fsmpLeds::LED1/fsmpLeds::LED2/fsmpLeds::LED3 * 信号: * 无 * * *************************************************************************/ #include <QObject> #include #include <string.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <QIODevice> class fsmpLeds:public QObject{ Q_OBJECT public: enum lednum{ LED1, LED2, LED3 }; explicit fsmpLeds(QObject *parent = nullptr) :QObject(parent) { led_fd1 = ::open("/sys/class/leds/led1/brightness",O_WRONLY|O_TRUNC); if(led_fd1 < 0) { perror("open led1"); return ; } led_fd2 = ::open("/sys/class/leds/led2/brightness",O_WRONLY|O_TRUNC); if(led_fd2 < 0) { perror("open led2"); return ; } led_fd3 = ::open("/sys/class/leds/led3/brightness",O_WRONLY|O_TRUNC); if(led_fd3 < 0) { perror("open led3"); return ; } } ~fsmpLeds() { ::close(led_fd1); ::close(led_fd2); ::close(led_fd3); } /* * Description: 开启设备,默认/sys/class/leds/led1/brightness * input: lednum * output: null * return: 成功true/失败false */ bool on(lednum x) { int fd; if(x == LED1) fd = led_fd1; else if(x == LED2) fd = led_fd2; else if(x == LED3){ fd = led_fd3; } int ret = write(fd,"1",1); if(ret < 0) { return false; } return true; } /* * Description: 关闭设备 * input: null * output: null * return: 成功true/失败false */ bool off(lednum x) { int fd; if(x == LED1) fd = led_fd1; else if(x == LED2) fd = led_fd2; else if(x == LED3){ fd = led_fd3; } int ret = write(fd,"0",1); if(ret < 0) { return false; } return true; } private: int led_fd1; //设备文件描述符 int led_fd2; //设备文件描述符 int led_fd3; //设备文件描述符 }; #endif // LED_H ------------------------------------------------------- fsmpLight.h: #ifndef LIGHT_H #define LIGHT_H /*************************************************************************** * * 类名:fsmpLight * 功能说明:扩展板 光照强度检测 * 公有函数: * fsmpLight() * double getValue(void) 获取光照强度 * * 信号: * 无 * * *************************************************************************/ #include <QObject> #include #include <string.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <QIODevice> #include <QDebug> class fsmpLight:public QObject{ Q_OBJECT public: explicit fsmpLight(QObject *parent = nullptr) :QObject(parent) { light_fd = ::open("/sys/bus/iio/devices/iio:device1/in_illuminance_input",O_RDONLY|O_NONBLOCK); if(light_fd < 0) { perror("open"); return; } } ~fsmpLight() { ::close(light_fd); } /* * Description: 获取光照强度 * input: null * output: null * return: current light */ double getValue(void) { char buf[10] = {0}; int ret = read(light_fd,buf,10); if(ret < 0) { perror("read"); return false; } double num; sscanf(buf, "%lf", &num); lseek(light_fd, 0, SEEK_SET); return num; } private: int light_fd; //设备文件描述符 }; #endif // LIGHT_H ------------------------------------------------------- fsmpProximity.h: #ifndef FSMPPROXIMITY_H #define FSMPPROXIMITY_H /*************************************************************************** * * 类名:fsmpProximity * 功能说明:扩展板 红外接近传感器(和光照传感器一起) * 公有函数: * fsmpProximity() * double getValue(void) 获取接近情况(0-2048越接近数据越大) * * 信号: * 无 * * *************************************************************************/ #include <QObject> #include #include <string.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <QIODevice> #include <QDebug> class fsmpProximity:public QObject{ Q_OBJECT public: explicit fsmpProximity(QObject *parent = nullptr) :QObject(parent) { proximity_fd = ::open("/sys/bus/iio/devices/iio:device1/in_proximity_raw",O_RDONLY|O_NONBLOCK); if(proximity_fd < 0) { perror("open"); return; } } ~fsmpProximity() { ::close(proximity_fd); } /* * Description: 获取distence * input: null * output: null * return: current light */ int getValue(void) { char buf[10] = {0}; int ret = read(proximity_fd,buf,10); if(ret < 0) { perror("read"); return false; } int num; sscanf(buf, "%d", &num); lseek(proximity_fd, 0, SEEK_SET); return num; } private: int proximity_fd; //设备文件描述符 }; #endif // FSMPPROXIMITY_H ------------------------------------------------------- fsmpSevensegLed.h: #ifndef FSMPSEVENSEGLED_H #define FSMPSEVENSEGLED_H /*************************************************************************** * * 类名:fsmpSevensegLed * 功能说明:扩展板 七段数码管 * 公有函数: * fsmpSevensegLed() * void display(int value) 显示4位以内整数 * void display(const char *str) 显示4位字符,注:仅支持 a、b、c、d、e * * 信号: * 无 * * *************************************************************************/ #include <stdint.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <getopt.h> #include <fcntl.h> #include <sys/ioctl.h> #include #include #include <QThread> #include <stdlib.h> #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) class fsmpSevensegLed:public QThread{ Q_OBJECT public: explicit fsmpSevensegLed(QObject *parent = nullptr) :QThread(parent) { memset(data, 0, sizeof(data)); device = "/dev/spidev0.0"; bits = 8; speed = 400000; delay = 0; } void display(int value) { data[3] = value%10; data[2] = value/10%10; data[1] = value/100%10; data[0] = value/1000%10; } //"abcde" void display(const char *str) { data[3] = (strlen(str)-1 >= 0)?(str[strlen(str)-1] - 'a')+10:0; data[2] = (strlen(str)-2 >= 0)?(str[strlen(str)-2] - 'a')+10:0; data[1] = (strlen(str)-3 >= 0)?(str[strlen(str)-3] - 'a')+10:0; data[0] = (strlen(str)-4 >= 0)?(str[strlen(str)-4] - 'a')+10:0; } private: void run() { int ret = 0; int fd; fd = open(device, O_RDWR); //打开设备文件 if (fd < 0) pabort("can't open device"); /* * spi mode //设置spi设备模式 */ ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); //写模式 if (ret == -1) pabort("can't set spi mode"); /* * bits per word //设置每个字含多少位 */ ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); //写每个字含多少位 if (ret == -1) pabort("can't set bits per word"); /* * max speed hz //设置速率 */ ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); //写速率 if (ret == -1) pabort("can't set max speed hz"); //打印模式,每字多少位和速率信息 printf("spi mode: %d\n", mode); printf("bits per word: %d\n", bits); printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); //transfer(fd); //传输测试 int i = 0; int pos = 0; unsigned char buf[2]; while(1) { pos = 1 << (i % 4); buf[0] = pos; buf[1] = num[data[i]]; if (write(fd, buf, 2) < 0) perror("write"); i++; if (i == 4) { i = 0; } usleep(3500); } } static void pabort(const char *s) { perror(s); abort(); } const char *device; uint8_t mode; uint8_t bits; uint32_t speed; uint16_t delay; int data[4]; unsigned char num[20] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; }; #endif // FSMPSEVENSEGLED_H ------------------------------------------------------- fsmpTempHum.h: #ifndef TEMPHUM_H #define TEMPHUM_H /*************************************************************************** * * 类名:fsmpTempHum * 功能说明:扩展板 温度湿度 * 公有函数: * fsmpTempHum() * double temperature(void) 提取温度 * double humidity(void) 提取湿度 * * 信号: * 无 * * *************************************************************************/ #include <QObject> #include #include <string.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <QIODevice> #include <stdint.h> #include <QDebug> class fsmpTempHum:public QObject{ Q_OBJECT public: explicit fsmpTempHum(QObject *parent = nullptr) :QObject(parent) { } double temperature(void) { int temp_raw = 0; int temp_offset = 0; float temp_scale = 0; open_device_int("iio:device0","in_temp_raw",&temp_raw); open_device_int("iio:device0","in_temp_offset",&temp_offset); open_device_float("iio:device0","in_temp_scale",&temp_scale); return (temp_raw + temp_offset) * temp_scale / 1000; } double humidity(void) { int hum_raw = 0; int hum_offset = 0; float hum_scale = 0; open_device_int("iio:device0","in_humidityrelative_raw",&hum_raw); open_device_int("iio:device0","in_humidityrelative_offset",&hum_offset); open_device_float("iio:device0","in_humidityrelative_scale",&hum_scale); return (hum_raw + hum_offset) * hum_scale / 1000; } private: bool open_device_int(const char *device, const char *filename, int *val) { int ret = 0; int fd; char temp[128] = {0}; sprintf(temp, "/sys/bus/iio/devices/%s/%s", device, filename); fd = open(temp,O_RDONLY|O_NONBLOCK); if(fd < 0) { perror("open"); return false; } char buf[10] = {0}; ret = read(fd,buf,sizeof(buf)); if(ret < 0) { perror("read"); return false; } sscanf(buf,"%d",val); ::close(fd); return true; } bool open_device_float(const char *device, const char *filename, float *val) { int ret = 0; int fd; char temp[128] = {0}; sprintf(temp, "/sys/bus/iio/devices/%s/%s", device, filename); fd = open(temp,O_RDONLY|O_NONBLOCK); if(fd < 0) { perror("open"); return false; } char buf[10] = {0}; ret = read(fd,buf,sizeof(buf)); if(ret < 0) { perror("read"); return false; } sscanf(buf,"%f",val); ::close(fd); return true; } private: int temp_hum_fd;; //设备文件描述符 }; #endif // TEMPHUM_H ------------------------------------------------------- fsmpVibrator.h: #ifndef VIBRATOR_H #define VIBRATOR_H /*************************************************************************** * * 类名:fsmpVibrator * 功能说明:扩展板 振动马达 * 公有函数: * fsmpVibrator() * bool setParameter(int strong_magnitude, int timems) 设置振动强度(0-0xffff)及时长(ms) * bool start(void) 启动马达 * bool stop(void) 停止马达 * * 信号: * 无 * * *************************************************************************/ #include <QObject> #include #include <string.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <QIODevice> #include <sys/ioctl.h> #include <QDebug> class fsmpVibrator:public QObject{ Q_OBJECT public: explicit fsmpVibrator(QObject *parent = nullptr) :QObject(parent) { vibrator_fd = ::open("/dev/input/event1", O_RDWR|O_NONBLOCK); if(vibrator_fd < 0) { perror("open vibrator"); } } ~fsmpVibrator() { ::close(vibrator_fd); } /* * Description:设置 * input:频率 * output:null * return:成功true/失败false */ bool setParameter(int strong_magnitude = 0xFFFF, int timems = 5000) { //qDebug()<<strong_magnitude<<timems; effect.type = FF_RUMBLE, effect.id = -1, effect.u.rumble.strong_magnitude = strong_magnitude; effect.u.rumble.weak_magnitude = 0; effect.replay.length = timems; effect.replay.delay = 0; if (ioctl(vibrator_fd, EVIOCSFF, &effect) < 0) { printf("Error creating new effect: %s\n", strerror(errno)); return false; } return true; } bool start(void) { struct input_event play = { .type = EV_FF, .code = (__U16_TYPE)effect.id, .value = 1 }; int ret = write(vibrator_fd, (const void*) &play, sizeof(play)); if(ret < 0) { perror("vibrator on"); return false; } //qDebug()<<"start"; return true; } bool stop(void) { struct input_event play = { .type = EV_FF, .code = (__U16_TYPE)effect.id, .value = 0 }; int ret = write(vibrator_fd, (const void*) &play, sizeof(play)); if(ret < 0) { perror("vibrator off"); return false; } //qDebug()<<"stop"; return true; } private: int vibrator_fd;//设备文件描述符 struct ff_effect effect; }; #endif // VIBRATOR_H ------------------------------------------------------- 项目目的: 在Linux下通过qtcreator编写后通过st-mp1构建部署到远程Linux主机后,在Stm32mp157开发板上能够控制本身的硬件同时也能同步控制华清远见元宇宙实验中心物联网仿真系统内的模拟硬件。并且通过Desktop Qt5.12.12 GCC64bit构建部署到Deploy Configuration时,能够控制Stm32mp157开发板上的硬件同时也能同步控制华清远见元宇宙实验中心物联网仿真系统内的模拟硬件。 设计要求: 1. 通过点击pb_connect(连接按钮)按钮可以连接到云端mqtt,连接成功则弹出小窗提示连接成功并自动绑定订阅与发布功能、连接失败则弹出小窗提示连接失败,弹出的小窗有一个确定键,点击确定关闭小窗。 2. 点击按钮pb_led0打开Stm32mp157开发板上的LD1灯且同步打开华清远见元宇宙实验中心物联网仿真系统内的电灯0,此时按钮pb_led0上的文本(初始化为led0_on)变更为led0_off。再次点击按钮pb_led0时关闭Stm32mp157开发板上的LD1灯且同步关闭华清远见元宇宙实验中心物联网仿真系统内的电灯0,此时按钮pb_led0上的文本(此时为led0_off)变更为led0_on。按钮pb_led1和pb_led2也是相同理论。 3. 点击按钮pb_feng打开Stm32mp157开发板上的风扇且同步打开华清远见元宇宙实验中心物联网仿真系统内的风扇,此时按钮pb_feng上的文本(初始化为feng_on)变更为feng_off。再次点击按钮pb_feng时关闭Stm32mp157开发板上的风扇且同步关闭华清远见元宇宙实验中心物联网仿真系统内的风扇,此时按钮pb_feng上的文本(此时为feng_off)变更为feng_on。 4. 点击按钮pb_buzzer打开Stm32mp157开发板上的蜂鸣器,此时按钮pb_buzzer上的文本(初始化为:蜂鸣器_on)变更为蜂鸣器_off。再次点击按钮pb_buzzer时关闭Stm32mp157开发板上的蜂鸣器,此时按钮pb_buzzer上的文本(此时为:蜂鸣器_off)变更为蜂鸣器_on。 5. 点击按钮pb_humiture时,打开Stm32mp157开发板上的温湿度传感器并将数据显示在textBrowser组件上。此时按钮pb_humiture上的文本(初始化为:温湿度_on)变更为温湿度_off。再次点击按钮pb_humiture时关闭Stm32mp157开发板上的温湿度传感器,此时按钮pb_humiture上的文本(此时为:温湿度_off)变更为温湿度_on。(需添加功能:打开Stm32mp157开发板上的温湿度传感器后,当温度超过30度时蜂鸣器会立即开启,低于30度或者直接点击按钮pb_buzzer都可关闭蜂鸣器) 6. 点击按钮pb_photosensitive时,打开Stm32mp157开发板上的光敏传感器并将数据显示在textBrowser组件上。此时按钮pb_photosensitive上的文本(初始化为:光敏_on)变更为光敏_off。再次点击按钮pb_photosensitive时关闭Stm32mp157开发板上的光敏传感器,此时按钮pb_photosensitive上的文本(此时为:光敏_off)变更为光敏_on。 7. 点击按钮pb_infrared时,打开Stm32mp157开发板上的人体红外传感器并将数据显示在textBrowser组件上。此时按钮pb_infrared上的文本(初始化为:人体红外_on)变更为人体红外_off。再次点击按钮pb_infrared时关闭Stm32mp157开发板上的人体红外传感器,此时按钮pb_infrared上的文本(此时为:人体红外_off)变更为人体红外_on。 8. 点击按钮pb_camera时打开Stm32mp157开发板上的摄像头并将采集到的图像在屏幕界面的右侧显示出来(目前项目中没有设计用于显示摄像头采集图像显示的组件,需要添加)。此时按钮pb_camera上的文本(初始化为:摄像头_on)变更为摄像头off。再次点击按钮pb_camera时关闭Stm32mp157开发板上的摄像头,此时按钮pb_camera上的文本(此时为:摄像头_off)摄像头_on,并关闭摄像头采集的图像显示界面。 结合以上代码及要求,进行完整详细的项目开发,如有需要可以添加项目结构内缺失的文件(项目结构内缺失硬件的.cpp文件),硬件.h文件不可进行修改。整合后将项目的所有文件发我,让我复制粘贴就能直接使用

#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { //注册gpio 64 65 66 67四个口 system(“echo 64 > /sys/class/gpio/export”); system(“echo 65 > /sys/class/gpio/export”); system(“echo 66 > /sys/class/gpio/export”); system(“echo 67 > /sys/class/gpio/export”); //初始化所有口为 输出模式 system(“echo ““out”” > /sys/class/gpio/gpio64/direction”); system(“echo ““out”” > /sys/class/gpio/gpio65/direction”); system(“echo ““out”” > /sys/class/gpio/gpio66/direction”); system(“echo ““out”” > /sys/class/gpio/gpio67/direction”); //初始化所有gpio 为1 不亮 system("echo ““1"” > /sys/class/gpio/gpio64/value”); system("echo ““1"” > /sys/class/gpio/gpio65/value”); system("echo ““1"” > /sys/class/gpio/gpio66/value”); system("echo ““1"” > /sys/class/gpio/gpio66/value”); while (1) { system("echo ““0"” > /sys/class/gpio/gpio64/value”); sleep(1); system("echo ““1"” > /sys/class/gpio/gpio64/value”); system("echo ""0"" > /sys/class/gpio/gpio65/value"); sleep(1); system("echo ""1"" > /sys/class/gpio/gpio65/value"); system("echo ""0"" > /sys/class/gpio/gpio66/value"); sleep(1); system("echo ""1"" > /sys/class/gpio/gpio66/value"); system("echo ""0"" > /sys/class/gpio/gpio67/value"); sleep(1); system("echo ""1"" > /sys/class/gpio/gpio67/value"); } return 0; }这个代码是用于在虚拟机上编译然后放置在Linux龙芯2k0300开发板的执行文件,按照这个模板帮我生成一个可以驱动在IIC协议下的四引脚数码管,让数码管四个数字都点亮,使用开发板的GPIO50(SDA)和GPIO51(SCL)两个引脚来连数码管的SDA和SCL,并告诉我你清晰的思路,代码的变量简单易懂,不要写的太长

最新推荐

recommend-type

PLC控制变频器:三菱与汇川PLC通过485通讯板实现变频器正反转及调速控制

内容概要:本文介绍了如何利用三菱和汇川PLC通过485通讯板实现变频器的正转、反转及调速控制。主要内容涵盖硬件配置、软件编程、具体控制逻辑及上机测试。文中详细描述了各个步骤的操作方法和注意事项,包括关键寄存器的设置及其含义。程序中有详细的中文注释,便于理解和维护。最终通过上机测试验证系统的稳定性和可靠性。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是熟悉PLC编程和变频器控制的专业人士。 使用场景及目标:适用于需要对电机进行精确控制的工业应用场景,如生产线、机械设备等。目标是提高控制系统灵活性和效率,确保系统稳定可靠。 其他说明:本文不仅提供理论指导,还附带实际操作经验,有助于读者更好地掌握相关技术和应用。
recommend-type

Python桌面版数独(五版)-优化选择模式触发新棋盘生成

Python桌面版数独(五版)-优化选择模式触发新棋盘生成
recommend-type

jmeter 下载使用5.6.3

jmeter 下载使用5.6.3
recommend-type

Web前端开发:CSS与HTML设计模式深入解析

《Pro CSS and HTML Design Patterns》是一本专注于Web前端设计模式的书籍,特别针对CSS(层叠样式表)和HTML(超文本标记语言)的高级应用进行了深入探讨。这本书籍属于Pro系列,旨在为专业Web开发人员提供实用的设计模式和实践指南,帮助他们构建高效、美观且可维护的网站和应用程序。 在介绍这本书的知识点之前,我们首先需要了解CSS和HTML的基础知识,以及它们在Web开发中的重要性。 HTML是用于创建网页和Web应用程序的标准标记语言。它允许开发者通过一系列的标签来定义网页的结构和内容,如段落、标题、链接、图片等。HTML5作为最新版本,不仅增强了网页的表现力,还引入了更多新的特性,例如视频和音频的内置支持、绘图API、离线存储等。 CSS是用于描述HTML文档的表现(即布局、颜色、字体等样式)的样式表语言。它能够让开发者将内容的表现从结构中分离出来,使得网页设计更加模块化和易于维护。随着Web技术的发展,CSS也经历了多个版本的更新,引入了如Flexbox、Grid布局、过渡、动画以及Sass和Less等预处理器技术。 现在让我们来详细探讨《Pro CSS and HTML Design Patterns》中可能包含的知识点: 1. CSS基础和选择器: 书中可能会涵盖CSS基本概念,如盒模型、边距、填充、边框、背景和定位等。同时还会介绍CSS选择器的高级用法,例如属性选择器、伪类选择器、伪元素选择器以及选择器的组合使用。 2. CSS布局技术: 布局是网页设计中的核心部分。本书可能会详细讲解各种CSS布局技术,包括传统的浮动(Floats)布局、定位(Positioning)布局,以及最新的布局模式如Flexbox和CSS Grid。此外,也会介绍响应式设计的媒体查询、视口(Viewport)单位等。 3. 高级CSS技巧: 这些技巧可能包括动画和过渡效果,以及如何优化性能和兼容性。例如,CSS3动画、关键帧动画、转换(Transforms)、滤镜(Filters)和混合模式(Blend Modes)。 4. HTML5特性: 书中可能会深入探讨HTML5的新标签和语义化元素,如`<article>`、`<section>`、`<nav>`等,以及如何使用它们来构建更加标准化和语义化的页面结构。还会涉及到Web表单的新特性,比如表单验证、新的输入类型等。 5. 可访问性(Accessibility): Web可访问性越来越受到重视。本书可能会介绍如何通过HTML和CSS来提升网站的无障碍访问性,比如使用ARIA标签(Accessible Rich Internet Applications)来增强屏幕阅读器的使用体验。 6. 前端性能优化: 性能优化是任何Web项目成功的关键。本书可能会涵盖如何通过优化CSS和HTML来提升网站的加载速度和运行效率。内容可能包括代码压缩、合并、避免重绘和回流、使用Web字体的最佳实践等。 7. JavaScript与CSS/HTML的交互: 在现代Web开发中,JavaScript与CSS及HTML的交云并用是不可或缺的。书中可能会讲解如何通过JavaScript动态地修改样式、操作DOM元素以及使用事件监听和响应用户交互。 8. Web框架和预处理器: 这本书可能会提到流行的Web开发框架和预处理器,比如Bootstrap、Foundation、Sass和Less等,它们是如何简化和加速开发流程的。 9. 测试和维护: 书中也可能包含关于如何测试网页以及如何持续优化和维护CSS和HTML代码的章节。例如,使用断言测试、自动化测试、性能分析工具等。 最后,鉴于文件名称列表中的“压缩包子文件”的表述,这可能是对“压缩包”文件的一种误译或误用,此处“压缩包”应该指的是包含该书籍PDF文件的压缩文件格式,如ZIP或RAR。而“Pro CSS and HTML Design Patterns.pdf”指的就是该书籍的PDF格式电子版文件。 以上所述,构成了《Pro CSS and HTML Design Patterns》一书可能包含的核心知识点。通过学习这些内容,Web前端开发者可以掌握更为高效和优雅的设计模式,从而在日常工作中更高效地解决实际问题。
recommend-type

Zotero 7数据同步:Attanger插件安装&设置,打造文献管理利器

/i.s3.glbimg.com/v1/AUTH_08fbf48bc0524877943fe86e43087e7a/internal_photos/bs/2018/L/j/ipKA8TRPyt4ptaG1DGww/t-m-01.png) # 1. Zotero 7数据同步简介 在数字时代,管理研究数据变得日益重要,而Zot
recommend-type

卷积神经网络的基础理论200字

<think>我们正在回答用户关于卷积神经网络(CNN)基础理论的询问。根据提供的引用资料,我们可以概述CNN的基本结构和工作原理。引用[1]提到CNN是一种前馈神经网络,信息从输入单向流动到输出。引用[2]指出CNN在图像处理等领域应用广泛,通过层次结构和参数调整实现模式识别。引用[3]说明CNN包含卷积层,使用卷积核提取局部特征,减少参数量,提高效率。引用[4]则提到了训练过程,包括前向传播、误差计算和反向传播(梯度下降)。因此,我们将从以下几个方面概述CNN:1.CNN的基本结构(卷积层、池化层、全连接层)2.卷积操作的工作原理(局部感受野、权重共享)3.训练过程(前向传播、损失函数、反
recommend-type

轻便实用的Java库类查询工具介绍

标题 "java2库类查询" 和描述表明,所提及的工具是一个专门用于查询Java库类的应用程序。此软件旨在帮助开发者快速地查找和引用Java的标准开发工具包(SDK)中包含的所有应用程序编程接口(API)类。通过这样的工具,开发者可以节省大量在官方文档或搜索引擎上寻找类定义和使用方法的时间。它被描述为轻巧且方便,这表明其占用的系统资源相对较少,同时提供直观的用户界面,使得查询过程简洁高效。 从描述中可以得出几个关键知识点: 1. Java SDK:Java的软件开发工具包(SDK)是Java平台的一部分,提供了一套用于开发Java应用软件的软件包和库。这些软件包通常被称为API,为开发者提供了编程界面,使他们能够使用Java语言编写各种类型的应用程序。 2. 库类查询:这个功能对于开发者来说非常关键,因为它提供了一个快速查找特定库类及其相关方法、属性和使用示例的途径。良好的库类查询工具可以帮助开发者提高工作效率,减少因查找文档而中断编程思路的时间。 3. 轻巧性:软件的轻巧性通常意味着它对计算机资源的要求较低。这样的特性对于资源受限的系统尤为重要,比如老旧的计算机、嵌入式设备或是当开发者希望最小化其开发环境占用空间时。 4. 方便性:软件的方便性通常关联于其用户界面设计,一个直观、易用的界面可以让用户快速上手,并减少在使用过程中遇到的障碍。 5. 包含所有API:一个优秀的Java库类查询软件应当能够覆盖Java所有标准API,这包括Java.lang、Java.util、Java.io等核心包,以及Java SE平台的所有其他标准扩展包。 从标签 "java 库 查询 类" 可知,这个软件紧密关联于Java编程语言的核心功能——库类的管理和查询。这些标签可以关联到以下知识点: - Java:一种广泛用于企业级应用、移动应用(如Android应用)、网站后端、大型系统和许多其他平台的编程语言。 - 库:在Java中,库是一组预打包的类和接口,它们可以被应用程序重复使用。Java提供了庞大的标准库,以支持各种常见的任务和功能。 - 查询:查询指的是利用软件工具搜索、定位和检索信息的过程。对于Java库类查询工具来说,这意味着可以通过类名、方法签名或其他标识符来查找特定的API条目。 最后,压缩包文件列表包含了两个文件:“java.dit”和“Java.exe”。其中“Java.exe”很可能是程序的可执行文件,而“java.dit”可能是一个数据文件,用于存储Java类的索引或数据。由于文件名后缀通常与文件类型相关联,但“dit”并不是一个常见的文件扩展名。这可能是一个特定于软件的自定义格式,或是一个打字错误。 总结来说,"java2库类查询" 是一个针对Java开发者的实用工具,它提供了一个轻量级、易用的平台来查询和定位Java标准库中的所有类和API。此工具对优化开发流程,减少查找Java类文档的时间大有裨益,尤其适合需要频繁查阅Java API的开发者使用。
recommend-type

【Zotero 7终极指南】:新手必备!Attanger插件全攻略与数据同步神技

# 1. Zotero 7与Attanger插件的介绍 在当今的学术研究和知识管理领域,高效的文献管理工具至关重要。Zotero 7作为一个流行的参考文献管理软件,因其强大的功能和用户友好的界面而受到专业人士的青睐。而Attanger插件则为Zotero 7带来了更多定制化和高级功能,极大地增强
recommend-type

MATLAB整段注释快捷键

<think>首先,用户的问题是:“MATLAB整段注释快捷键”,意思是“MATLAB整段注释快捷键”。我需要用中文回答。 根据规则: - 回答必须用中文。 - 回答完问题后,必须在末尾输出“§§相关问题§§”,然后提出3-5个相关问题。 - “§§相关问题§§”必须完整输出在第一行,禁止换行分散。 - 相关问题必须基于用户的问题和我的回答。 现在,回忆MATLAB的快捷键:在MATLAB中,整段注释通常使用快捷键Ctrl + R来注释选中的代码行,使用Ctrl + T来取消注释。用户问的是“整段注释”,所以我应该确认快捷键。 在MATLAB中: - 注释选中的行:Ctrl + R -
recommend-type

Eclipse Jad反编译插件:提升.class文件查看便捷性

反编译插件for Eclipse是一个专门设计用于在Eclipse集成开发环境中进行Java反编译的工具。通过此类插件,开发者可以在不直接访问源代码的情况下查看Java编译后的.class文件的源代码,这在开发、维护和学习使用Java技术的过程中具有重要的作用。 首先,我们需要了解Eclipse是一个跨平台的开源集成开发环境,主要用来开发Java应用程序,但也支持其他诸如C、C++、PHP等多种语言的开发。Eclipse通过安装不同的插件来扩展其功能。这些插件可以由社区开发或者官方提供,而jadclipse就是这样一个社区开发的插件,它利用jad.exe这个第三方命令行工具来实现反编译功能。 jad.exe是一个反编译Java字节码的命令行工具,它可以将Java编译后的.class文件还原成一个接近原始Java源代码的格式。这个工具非常受欢迎,原因在于其反编译速度快,并且能够生成相对清晰的Java代码。由于它是一个独立的命令行工具,直接使用命令行可以提供较强的灵活性,但是对于一些不熟悉命令行操作的用户来说,集成到Eclipse开发环境中将会极大提高开发效率。 使用jadclipse插件可以很方便地在Eclipse中打开任何.class文件,并且将反编译的结果显示在编辑器中。用户可以在查看反编译的源代码的同时,进行阅读、调试和学习。这样不仅可以帮助开发者快速理解第三方库的工作机制,还能在遇到.class文件丢失源代码时进行紧急修复工作。 对于Eclipse用户来说,安装jadclipse插件相当简单。一般步骤包括: 1. 下载并解压jadclipse插件的压缩包。 2. 在Eclipse中打开“Help”菜单,选择“Install New Software”。 3. 点击“Add”按钮,输入插件更新地址(通常是jadclipse的更新站点URL)。 4. 选择相应的插件(通常名为“JadClipse”),然后进行安装。 5. 安装完成后重启Eclipse,插件开始工作。 一旦插件安装好之后,用户只需在Eclipse中双击.class文件,或者右键点击文件并选择“Open With Jadclipse”,就能看到对应的Java源代码。如果出现反编译不准确或失败的情况,用户还可以直接在Eclipse中配置jad.exe的路径,或者调整jadclipse的高级设置来优化反编译效果。 需要指出的是,使用反编译工具虽然方便,但要注意反编译行为可能涉及到版权问题。在大多数国家和地区,反编译软件代码属于合法行为,但仅限于学习、研究、安全测试或兼容性开发等目的。如果用户意图通过反编译获取商业机密或进行非法复制,则可能违反相关法律法规。 总的来说,反编译插件for Eclipse是一个强大的工具,它极大地简化了Java反编译流程,提高了开发效率,使得开发者在没有源代码的情况下也能有效地维护和学习Java程序。但开发者在使用此类工具时应遵守法律与道德规范,避免不当使用。