RPi--lab8网络矩阵显示
2016-06-27 19:58
495 查看
Lab8 : 网络LED矩阵显示器 - 嵌入式与计算机网络
前言
前言
本次实验延续上次实验的环境,使用MAX7219驱动8x8点阵。上位机使用Ubuntu 14.04,下位机使用Raspberry pi 2。 使用的还是上次实验编译好的非阻塞式写入点阵支持内核模块。 控制点阵显示字符 通过write函数向device写入数据即可。
#include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int Matrix; #define ALLCHAR "0123456789abcdefghijklmnopqrstuvwxyz" int main(){ Matrix = open("/dev/matrix", O_WRONLY); if (Matrix < 0){ fprintf(stderr, "Cound not open matrix device"); exit(1); } write(Matrix, ALLCHAR, strlen(ALLCHAR)); return 0; }
编写网络程序接受TCP请求 使用linux下的socket编程,接受外部TCP请求,并将其发送来的所有数据写入matrix设备即可实现显示功能。 Socket流程图 | 图自Linux的SOCKET编程详解:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/socket.h> int Matrix; int server; #define PORT 8080 #define ADDR "0.0.0.0" #define QUEUE 20 #define BUFF_SIZE 2048 main(){ // 打开matrix Matrix = open("/dev/matrix", O_WRONLY); if (Matrix < 0){ fprintf(stderr, "Cound not open matrix device\n"); exit(1); } // 建立服务器 int server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); struct sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = inet_addr(ADDR); serverAddr.sin_port = htons(PORT); // 绑定ip以及端口 if (bind(server, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1){ fprintf(stderr, "Count not bind %s:%d\n", ADDR, PORT); exit(1); } if (listen(server, QUEUE) == -1){ fprintf(stderr, "Listen error\n"); exit(1); } printf("Server running at %s:%d\n", ADDR, PORT); while (1){ struct sockaddr_in clientAddr; socklen_t length = sizeof(clientAddr); // 对连入的连接进行处理 int conn = accept(server, (struct sockaddr*)&clientAddr, &length); if (conn < 0){ fprintf(stderr, "Connect error"); exit(1); } printf("A new connection from %s:%d\n", inet_ntoa(clientAddr.sin_addr), clientAddr.sin_port); // 处理连接发送过来的字符 while (1){ char receiveBuf[BUFF_SIZE]; int count; memset(receiveBuf, 0, sizeof(receiveBuf)); // 接收字符 count = recv(conn, receiveBuf, sizeof(receiveBuf), 0); // 如果接收到的字符为空,则表示离开 if (count == 0){ close(conn); break; } // 将接收到的所有字符发送给matrix进行显示 write(Matrix, receiveBuf, count); } } close(server); return 0; }
树莓派本地连入:
上位机远程连入:
使用线程处理多个连接 上一节的程序使用的是阻塞式的处理连接,这将导致服务器每次accept了一个连接之后,无法再处理其余连接。 而这种情况的处理方式有很多。可以使用一个线程对应一个socket fd的方式进行阻塞式监听。也可以使用IO多路复用,如select、poll、epoll,在单线程的环境下进行高效的网络IO操作。 使用线程的方式对于阻塞式程序的改动较小,基本上逻辑还是一致的。
………… void* serverRecv(void* data){ int conn = *(int*)data; while (1){ char receiveBuf[BUFF_SIZE]; int count; memset(receiveBuf, 0, sizeof(receiveBuf)); count = recv(conn, receiveBuf, sizeof(receiveBuf), 0); if (count == 0){ close(conn); break; } write(Matrix, receiveBuf, count); } pthread_exit(NULL); return NULL; } ………… int main(){ ………… printf("Server running at %s:%d\n", ADDR, PORT); while (1){ pthread_t thread; struct sockaddr_in clientAddr; socklen_t length = sizeof(clientAddr); int conn = accept(server, (struct sockaddr*)&clientAddr, &length); int result; if (conn < 0){ fprintf(stderr, "Connect error"); exit(1); } printf("A new connection from %s:%d\n", inet_ntoa(clientAddr.sin_addr), clientAddr.sin_port); result = pthread_create(&thread, NULL, serverRecv, &conn); if (result < 0){ printf("Create thread error\n"); exit(1); } } ………… }
相关文章推荐
- 我的 ARM+Linux 学习路线
- 开发学习记录之看门狗驱动
- 时钟+温度+遥控设置,综合时钟例子
- Linux下运行openwebos- -(转)
- Linux下运行openwebos- -(转)
- BusyBox 简化嵌入式 Linux 系统
- EGL 学习
- 嵌入式开发设计方法变化的背景
- 嵌入式人才的发展方向
- 汇编调用c函数为什么要设置栈
- 三角函数的实现
- 嵌入式桌面操作系统使用与制作攻略
- 嵌入式系统烧写uboot/bootloader/kernel的一般方法
- 甲骨文收购Sleepycat 丰富嵌入式产品线
- 嵌入式Linux操作系统学习规划
- 基于嵌入式多芯片模组的微机保护平台
- 嵌入式系统中常用文件系统的制作总结
- 嵌入式C语言基础教程一
- 汇总Dotfuscator自定义规则中的元素选择
- 3. 类型限定符