本篇论文目录导航:
【题目】
网络化智能化仓储管理系统探析
【第一章】
物联网与仓储管理体系的融合分析绪论
【第二章】
仓储管理系统整体框架概述
【第三章】
仓储系统移植及环境搭建
【第四章】仓储管理系统主程序设计
【第五章】
仓储系统采集终端设计
【结论/参考文献】
多仓库远程移动监控的实现研究结论与参考文献
第四章系统主程序设计
4.1 前端数据中心主程序的各个模块介绍
该系统的主程序是由远程控制模块和本地监控模块组成的,本节将具体介绍两大模块的实现。
核心的服务器主要用于各个管理系统中的仓库的库存货物情况和报警情况等信息。我们能够进入前端的数据库观看所有信息。
前端的数据库储存各个仓库的详细信息,主要包括仓库生鲜区的温度,干货区的湿度,光感信息,入库数刷卡信息验证后,可通过手动操作键盘自行修改填写取出或者进入仓库的货物种类和数量。用户也可以在HTML页面上手动更改环境参数的临界报警值和报警后通知的手机端用户的手机号码。
本地监控主要由实时监测温度湿度、实时监测光照的强度和RFID采集到的信息这三个部分组成。[31-33]
实时监测仓库内的温度和湿度,适用的是温湿度监测芯片,当采集到的信息超过在HTML页面设定的临界值时,系统会产生警报,报警器响起,GSM模块会自动的向用户发送温湿度报警的信息。
RFID出入库货物信息采集模块能够将RFID采集来的货物进出的种类和前端数据中心,并保存起来。
4.2 主要的十个线程
该主系统主要由十个线程组成。它们分别是
pthread_client_request():处理消息队列请求的线程;
pthread_sqlite():数据库操作线程;
pthread_refresh():实时共享内存刷新数据线程;
pthread_analysis():M0数据信息的分析线程;
pthread_transfer():接收M0数据信息的线程;
pthread_sms():收发短信线程;
pthread_uart_cmd():控制M0各外设的命令发送线程;
pthread_led():A8上的LED控制线程;
pthread_buzzer():A8上的蜂鸣器控制线程;
pthread_camera():A8上的摄像头的控制线程。
各线程间的关系如图4.1所示。
4.3 各进程间采用的通信机制
1.数据存储在内存中的PIPE机制,PIPE运用在具有亲缘关系的进程与进程之间。
2.异步通讯方式也是唯一的异步通讯方式signal.
3.可用于任意进程与进程之间fifo,具有文件名,并且经数据存储在了内存当中。
4.共享内存(share memory)是效率最高机制,但是需要同步和互斥机制的配合。
5.semaphore是为了能够实现同步和互斥机制,一般配合共享内存使用。
6.消息队列是按照消息类型来访问的,常常被用于CS架构下。
7.Socket套接字主要用于主机间的网络通信和本地间的通讯。[34-35]
4.4主程序各线程之间的同步机制
当主程序中十个线程中的一个加锁之后,其余的9个线程如果存在请求,那么它们将进入等待队列,该队列的排序是根据优先级的高低排列的,这种策略使得资源的分配变得更加的公平和高效。线程与线程之间有共享的全局变量,条件变量就是利用了这种共享的变量来实现同步的一种机制。当条件变量的条件还没有成立时,线程处于等待阶段,这是挂起。而另一个线程的条件变量的条件成立时,会发出条件成立的信号。为了防止线程间出现竞争。条件变量通常和互斥锁结合起来实现同步机制。
创建十个主线程,然后实现各线程的并发控制和处理,最后阻塞各个等待中的线程结束。具体流程图如图4.3所示。
4.5 接收 Cortex-M0 信息线程
该模块用于接收M0通过Zigbee传输来的信息。信息由发送端的Zigbee发送,再经过U转串传输到A8,该线程将串口发送来的信息逐一读取,然后再将信息插入信息链表,如果满足条件则会唤醒数据分析线程,然后继续监听串口直到下一次信息发送过来。流程图如图4.4所示。
4.6 数据分析线程
该线程主要分析并处理由Cortex-M0发送来的信息,开始时该线程处于睡眠状态,当遇到信息接受线程的激活后,取出信息,如果链表为空,线程将继续进入睡眠状态。
如果线程不为空,则检查信息的类型,如果为R类型则该信息为货物出入信息,将信息插入数据库链表中;如果为E类型,则该信息为环境信息,解析环境信息,如果没有超出环境信息临界值则修改信息led,警报器,风扇复位异常标志位,如果环境信息异常,发送消息控制led,警报器、风扇并修改激活短信发送线程的标志位。最后将信息插入数据库链表。插入完毕则唤醒数据库和刷新内存的线程。该线程流程图如图4.5所示。
4.7 处理消息队列请求线程
该线程的开辟是为了接受并处理消息队列中的请求,检测消息队列中相应标志位,然后从Cortex-A8发出命令对Cortex-M0上的硬件设备进行操作。例如当消息头为1L时即为led设备操作,将操作至传给led设备操作全局变量,激活led线程;当消息头为2L时即为警报器设备操作,将操作值传给buzzer设备操作全局变量,激活buzzer线程;当消息头为3L时即为摄像头设备操作,摄像头设备安装在Cortex-A8上,将操作值传给camera设备,激活摄像头线程[36-37];当信息头为4L时,激活M0控制命令链表,激活M0命令发送线程。当信息头即为短信接收方号码修改命令,能接收CGI修改中心号码;当信息头为11L时,接收PC机和手机的网关和ip地址,然后开启WIFI;当信息头为5L时,即为修改仓库报警信息上下限,然后将信息加入数据库链表,并激活数据库线程。处理消息队列请求线程流程图如图4.6所示。
4.8 数据库操作线程
该线程从创建一个操作链表开始进入第一层While(1)循环,然后进入pthread_cond_wait睡眠中,当其他的线程中调用到pthread_cond_signal本线程将被再次唤醒进入下一层while(1)循环,取出链表中的第一个结点,如果该结点中的信息为空,则程序会break跳出while(1)循环,回到上一层循环,并重新睡眠等待下一次的唤醒;如果第一个结点信息不是空,那么结点信息将会传入sqlite_task函数,移植循环取下一结点信息,知道该链表被全部取完。[37]Sq Lite_task函数会分析取到的结点信息的内容,然后调用相应的函数对数据库内的信息进行操作。数据库操作线程流程图如图4.7所示。
Sqlite_task()函数解析:标志位table_select_mask位为0时,表示要进行环境信息上下限的修改,env_operation_mask=1表示要修改上下限。标志位table_select_mask为1时collect_opration_mask=1表 示 获 取 的 信 息 为 时 间 环 境 信 息 ,collect_operation_mask=2,表 示 信 息 为 获 得 实 时 环 境 信 息 . 当 标 志 位table_select_mask=2时 ,goods_opration_mask=0表 示 有 货 物 的 进 入 信 息 ,goods_operation_mask=1表示有货物出库的信息,goods_operation_mask=3表示要获取现今仓库内的货物信息。
在数据库线程中共创建了三个表,这三个表分别如下图4.8所示。
注意:不管该函数是否成功返回,一定要用sqlite3_close(sqlite3 *db)来释放数据库文件句柄所占用的资源;
所谓的回调函数即通过函数指针来调用一个函数,当我们把一个函数的指针当做一个参数传递给调用函数的时候,这个参数就指向了我们想要去调用的函数。
打开一个存在的数据库或者创建一个新的数据库:
注意:sqlite3_exec()函数会首先执行SQL语句,当sql语句不为空的时候,那么进入回调函数。如果在my.db中已经有几行数据的信息,callback()会多次的被调用。
4.9 刷新共享内存线程
信息从USB串口发送过来以后,刷新内存共享线程就会被激活,该线程会自动将接收到的信息存入共享内存里面,这时我们就可以通过CGI来查看当前的实时信息。该线程初始时处于睡眠状态,被唤醒后会进行申请信号量的P操作,然后将信息存入共享内存中,最后做释放信号量的V[38].该线程的流程图如下:
struct env_info_clien_addr函数中的参数all_info_RT,存放仓库的实时信息。
Int函数中的参数semid存放信号灯,参数shmid存放共享内存。
pthread_cond_t函数的参数cond_sqlite所有能够把数据库操作线程唤醒的变量,cond_refresh参数存储存储数据库操作线程被唤醒的条件变量。
pthread_mutex_t函数中的参数mutex_refresh为数据刷新线程的互斥锁。mutex_slinklist为仓库的数据缓存链表互斥锁。mutex_global为数据实时保护互斥锁。
4.10 控制 Cortex-M0 的命令发送线程
该线程实现对Cortex-M0的外设设备的操作,信息由USB接口发送,直接经过Zigbee网络传输到Cortex-M0.考虑到时钟的时序,需要进行适当的延时,该线程的流程图如下:
4.11SMS 线程
我们通过shell命令来对Linux系统进行操作,通过ARM专有的汇编指令来对ARM进行操作,不难想象GPRS本身也具有专属的指令系统,即着名的“AT指令集”.最常用的AT指令分别有短信发送接收指令,网络通信指令,语音通话指令,存储消息指令等指令。所以AT的指令集是相当全面的,涵盖了几乎所有的功能。GSM短信收发主要通过两种方式,它们分别为pdu模式的发送接收短信方式和本地式的短信发送方式。本系统主要运用了本地式的短信发送接收模式,该模式相对于前者操作简单,缺点是只能发送英文,不能发送汉字,不具有汉字库。[38]
1.操作方式
首先将发送的模式设置成文本发送模式:AT+CMGF=1
再次设置接收方的电话号码:AT+CMGS=18600894146
最后输入要发送的内容:>hello world !
注意事项:当我们每写完一条指令的时候都要以回车结尾,当最后的时候出现“>”后才能输入信息。当把信息输入完毕时不能够再以回车结尾,要以“ctrl+z”这对组合键来作为结束符。因为回车的 ASCII 值为“/r”,“ctrl+z”在 ASCII 中值为“0X1a”,当编码的同时可以在输入信息的末尾进行字符串的拼接。
2.短信在PUD模式下的接收和发送
4.12 本章小结
本章主要对主程序的各个线程设计进行详细介绍。包括主线程之间的关系,主线程之间的通讯机制和同步机制。并详细说明了接收Cortex-M0信息和发送命令线程,数据库线程,处理消息队列线程,SMS线程,数据分析线程的实现。