• 智慧物联仓储可视化管理系统


    智慧物联仓储可视化管理系统

    介绍

    在这里插入图片描述

    1.项目名称:基于cortex-A7的智慧物联仓储可视化管理系统

    2.开发语言:C、HTML

    3.开发平台:Ubuntu-18.4 Windows10

    4.linux内核版本 5.10

    5.硬件平台:STM32MP157a(cortex-A7 & cortex-M4)

    ​ STM32MP157a由 意法半导体提供

    6.开发工具:VIM、arm-linux-gnueabihf-gcc 、VSCode

    关于项目:

    ​ 项目主要实现了 客户端登录 boa 服务端实现对仓库的信息掌握和仓库的管理 ;客户端主要由网页提供人机交互支持(HTML) ;服务端主要由 BOA 服务器提供数据交互支持,网页后台由 CGI 处理;

    ​ 项目主要实现了对仓库温湿度、光照、货物数量的监控(可拓展视频监控) ;实现了对环境阈值设置的功能(温度上/下限 湿度上\下限 光照强度上\下限 等) ; 实现了对仓库设备节点操作的功能(灯光、风扇、警报、数码管等设备) ; 客户端通过网页登录服务器(客户信息由sqlite3数据库管理),可以实现对1号仓库(157a) 进行监控管理 ;

    ​ 当用户设置阈值时 ,通过网页传输给服务器,服务器接收到用户指令后 ,由指定CGI程序处理用户网页指令数据交由 数据处理 进程 来 处理用户指令,

    以设置阈值为例:

    ​ 数据处理 进程 会分配对应的 线程 来处理阈值设置事件,设置完阈值后,仓库设备会根据阈值的上下限 来控制仓库设备节点(如设置温度上\下限为 30-5 摄氏度 仓库温度超过 30 摄氏度则风扇开启(降温),低于5摄氏度led灯亮起(升温) ,并向用户发出高温警报(蜂鸣器响起) );

    ​ 用户查看仓库环境时 ,仓库要实时为用户提供当前仓库的环境数据 , 用户控制仓库设备节点时 ,要反馈给用户操作结果

    1.BOA移植

    BOA 服务器是一个小巧高效的web服务器

    移植步骤在 /01-boa移植/boa移植及错误解决

    boa开机自启动配置 
    进入~/nfs /rootfs/etc/init.d 目录下    
    打开 rcS 最后一行添加  /etc/boa/boa 
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    2.SQlite3移植

    移植步骤在 /02-sqlite3移植/sqlite的移植

    最重要的是配置gcc编译器,链接才不会报错gcc -lsqlite3

    我们参考 手册对 sqlite3 源码进行了编译 sqlite3 要运行在 157a 平台上(ARM 架构)
    所以我们需要修改 Makefile 对应的编译器   ./config --host arm-linux-gnueabi --prefix ./install
    --host:指定运行主机平台的  指定编译器编译源码
    --prefix:指定编译好的类库二进制文件的安装路径
    
    • 1
    • 2
    • 3
    • 4

    配置gcc编译器,链接gcc -lsqlite3不报错:

    污染交叉编译器
    1.将 include 目录下的 所有 .h 文件拷贝到 ~/toolchain/gcc-7.5.0/arm-linux-gnueabihf/include 下
    此操作解决包含头文件的问题cp ./*.h ~/toolchain/gcc-7.5.0/arm-linux-gnueabihf/include
    在这里插入图片描述

    2.将 install 目录下的 lib 目录下的 libsqlite3.* 所有文件 拷贝到 ~/toolchain/gcc-7.5.0/arm-linux-gnueabihf/lib 下
    ​ 在 install/lib cp libsqlite3.* ~/toolchain/gcc-7.5.0/arm-linux-gnueabihf/lib -arf
    ​ 此操作解决的是 使用sqlite3 时 链接库的问题 arm-linux-gnueabihf-gcc xxx.c -o xxx -lsqlite3

    在这里插入图片描述

    3.代码构成

    www :HTML网页交互

    一定要注意在 拷贝 www 文件时,要注意.html文件的可执行权限

    在这里插入图片描述

    driver :驱动、设备树、内核

    在这里插入图片描述

    4.获取代码路径

    解析都在代码中,帮助文档也在 1.tar.gz

    1.git智慧物联仓储可视化管理系统

    2.有道云:智慧物联仓储可视化管理系统

    5.成果展现

    1.登录页面:192.168.1.10

    在这里插入图片描述

    2.

    在这里插入图片描述

    2.1查看

    在这里插入图片描述

    按键1[KEY1]为入库操作,商品数量++,同时LED1、LED2状态发生改变

    在这里插入图片描述

    按键3[KEY3]为出库操作,商品数量–,同时LED3状态发生改变

    请添加图片描述

    按键2[KEY2]为切换温湿度显示操作

    在这里插入图片描述

    2.2设置阈值,超过阈值会有相应操作,如警报

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hhz3NmHT-1661322500348)(C:\Users\25222\AppData\Roaming\Typora\typora-user-images\1661314105850.png)]

    2.3控制

    在这里插入图片描述

    6.分析

    本项目的实现思路:
    由A7主程序 读取 [ 设备节点 ] 从A7发送过来的环境信息数据和货物信息数据 写入共享内存中,
    然后 网页程序(CGI)读取 共享内存 中的信息显示在网页上,
    {		
    	处理上层 下发的控制命令主线程: 读取消息队列msgid中的控制消息 到queuemsg,唤醒->读取数据线程1[pthr_t1]
    
    	线程1[pthr_t1]		:通过ioctl,读取A7内核的环境信息,写入buf中,		唤醒->仓库1处理线程pthr_t2
    
    	仓库1处理线程pthr_t2 :存放处理后的数据到envmsg,					唤醒->共享内存线程pthr_t4
    
    	共享内存线程pthr_t4 : 将处理完的数据拷贝到共享内存addr,		唤醒->接收网页下发的阈值的线程pthr_t6	
    	
    	接收网页下发的阈值的线程pthr_t6	:  将读取息队列的(节点200),网页设置阈值 赋值给限定阈值,便于报警线程pthr_t5使用  唤醒->报警线程pthr_t5
    
    	报警线程pthr_t5 : 处理过限阈值,唤醒->主线程
    
    	线程3 数码管显示温湿度 不使用信号量,不然代码执行太慢,余辉就灭了[msg.c的228]
    -----------------------------------------------------------------------------------------------------------------	
    0.   主 线程  ->读取消息队列msgid中的控制消息 到queuemsg     唤醒->读取数据线程1[pthr_t1]
    
    1.   读取数据线程1[pthr_t1]     ->从内核 读取数据     -> 唤醒 仓库1处理线程
    
    		线程3 数码管显示温湿度 不使用信号量,不然代码执行太慢,余辉就灭了[msg.c的228]
    
    2.   仓库1处理线程       ->将内核读取的数据处理     -> 唤醒 共享内存线程
    
    3.   刷新共享内存的线程        ->将处理完的数据拷贝到共享内存addr(上传到网页的数据,节点100) -->唤醒  接收网页下发的阈值的线程   
    
    4.   接收网页下发的阈值的线程   ->将读取息队列的(节点200),网页设置阈值 赋值给限定阈值    ->唤醒 报警线程
    
    5.   报警线程                ->处理超阈值                        ->唤醒主线程
    --------------------------------------------------------------	
    }		
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    本项目面试问答

    1. 这个项目还可以怎么优化?

    1.加装火焰传感器,
    在这里插入图片描述

    2.在msg.c文件中186行加入,实现商品数量、阈值,掉电不丢失;也就是第一次读取内核时,需要先从数据库读取商品数量,使用ioctl写入内核(在按键中断驱动key_irq.c中使用copy_from_user,初始化商品数量)

    1. 本项目最大的坑:

    因为我不是直接在开发板启动根目录 rootfs/ 下写代码,而是写完一个功能后,再拷贝到 rootfs/ ,
    而拷贝后会改变 .html、.cgi文件的 可执行权限,这个问题坑了我整整3天
    最后使用 cp -p 解决,为了保险起见又 使用 chmod +x
    所以我的copy.sh 脚本文件才全是 chmod +x

    #!/bin/bash
    cd /home/linux/hqyj/14project/02仓储/www/cgisource
    
    arm-linux-gnueabihf-gcc login.c cgic.c -o login.cgi  -lsqlite3  
    arm-linux-gnueabihf-gcc store1.c cgic.c -o store1.cgi -lsqlite3 
    arm-linux-gnueabihf-gcc operation.c cgic.c -o operation.cgi -lsqlite3 
    arm-linux-gnueabihf-gcc store1_set.c cgic.c -o store1_set.cgi
    arm-linux-gnueabihf-gcc store1_ctl.c cgic.c -o store1_ctl.cgi
    
    cp login.cgi ../cgi-bin/
    cp store1.cgi ../cgi-bin/
    cp operation.cgi ../cgi-bin/
    cp store1_set.cgi ../cgi-bin/
    cp store1_ctl.cgi ../cgi-bin/
    
    cd /home/linux/hqyj/14project/02仓储/www
    
    arm-linux-gnueabihf-gcc project.c msg.c -o pro -lsqlite3 -lpthread
    
    rm -rf  /home/linux/nfs/rootfs/www
    
    cp -rfp /home/linux/hqyj/14project/02仓储/www /home/linux/nfs/rootfs/
    
    cd /home/linux/nfs/rootfs/www/
    
    chmod +x *
    
    cd /home/linux/nfs/rootfs/www/cgi-bin/
    
    chmod +x *
    
    cd /home/linux/nfs/rootfs/www/cgisource/
    
    chmod +x *
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    看看这问题别人如何解决的:
    1.修改其权限,这一步非常重要,我就是因为这一步走了很多弯路
    2.cp -p命令保留文件权限

    1. 使用全局变量的坑

    共享的全局变量,在头文件里声明为extern的:不要初始化值

    extern int g; // 注意,不要初始化值!
    
    • 1

    extern int g=0;错误

    1. shmat返回值
    // create_mem()函数用于创建共享内存,首先使用ftok函数生成一个key,然后使用shmget函数创建一个共享内存段,最后使用shmat函数将共享内存段映射到进程的地址空间,并返回指向共享内存段的指针。
    char*create_mem()
    {
        key_t key = ftok("/root/",'z');
        int shmid = shmget(key,sizeof(char)*128,IPC_CREAT);
        char* share_me =(char *)shmat(shmid, 0, 0);
        return share_me;
    }
    
    char* share_me=create_mem();
    //在函数create_mem()中,share_me指针是一个局部变量,在函数结束后,share_me指针所指向的内存空间会被释放,但是由于share_me指针指向的是共享内存段,所以即使函数结束,share_me指针仍然可以访问共享内存段,因此不会报错。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • create_mem()函数返回的是 指向共享内存段的指针也就是一个地址值
    • 区分:
    char *GetMemory(void)
    {
        char p[] = "hello world";
        return p; /* char *p = (char *)malloc(100);strcpy(p,"Hello World!");这才是对的*/
    }//因为p的生命周期在GetMemory函数执行完了就被销毁了,str指向的是个野指针
    void Test(void)
    {
        char *str = NULL;
        str = GetMemory();
        printf(str);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    如何写好项目管理应聘简历?
    Paragon NTFS 15Mac上NTFS分区的必备工具
    leetcode做题笔记143. 重排链表
    【3dmax】怎么样让二维变三维
    在服务器上部署 Nginx 并设置图片服务器
    Forest + IDEA = 双倍快乐!ForestX 隆重登场
    基于BM1684移植YOLOV7
    Laravel 博客开发|后台项目管理
    易景地球网页版修改地球背景纹理方法
    android setContentView()源码解析
  • 原文地址:https://blog.csdn.net/qq_47355554/article/details/126504001