基于D1开发板的 微信/支付宝 物联网(MQTT)支付平台
-
准备工作(支付宝沙盒信息获取)
登录 开发者中心控制台 (alipay.com) 使用支付宝进行登录。
进入沙箱环境 开放平台-沙箱环境 (alipay.com)
如果《RSA2密钥(公钥模式) 》的查看是灰色的,点击启用。点击查看可获取应用公钥,应用私钥和支付宝公钥。
下载并安装沙盒版的支付宝应用。通过提供的账号登录沙盒版支付宝,进行付款。
(微信个人无法申请 APPID 等信息,且没有提供沙盒平台,所以无法进行测试。提供的 JAR 包里面是有晕哥提供的 APPID 等信息,可以进行测试。提供的 java 源码已经将微信的 APPID 等信息删除)
服务器端搭建
linux 平台搭建
sudo apt install openjdk-8-jdk mosquitto
修改 D1PayServer.jar 压缩包中的 zfbinfo.properties 文件,将 appid,public_key(应用公钥),private_key(应用私钥),alipay_public_key(支付宝公钥)替换成自己支付宝沙盒提供的。
然后将 D1PayServer.jar 上传至 linux 平台运行。
java -jar D1PayServer.jar
运行效果:
客户端运行
烧写 tina_d1-nezha_uart0.img 镜像,内核已经修改为默认 HDMI 输出,分辨率为 480P(720x480)。
连接 wifi
wifi_connect_ap_test GL-MT300N-V2-0be goodlife
修改应用配置文件:
vim /bin/D1Pay/D1PayClientConfig.json { "device_id":"kw", "mqtt_server_ip":"192.168.8.108", "mqtt_sub_top":"d1_pay_client", "mqtt_pub_top":"d1_pay_server", "fb":"/dev/fb0", "input":"/dev/input/event2" }
修改 mqtt_server_ip 为自己的 mqtt 服务器的地址,input 修改为自己的触摸设配。
运行应用程序
root@TinaLinux:/# d1_pay_launche
运行效果(使用的HDMI屏幕,拥有触摸,分辨率 800x480),完成支付后将会播报语音以及控制一个 GPIO 输出 5 秒的高电平。
客户端添加一个商品信息
商品信息保存在 /bin/D1Pay/ProductList/ 目录下,每一件商品对应一个文件夹。每一个文件夹都有 Image.png ProductDescribe.txt文件,Image.png为 350x350 像素的商品图片,ProductDescribe.txt为描述文件,包含商品名,价格,付款成功后控制的 GPIO,以及商品详细介绍。
. ├── D1 Board │ ├── Image.png │ └── ProductDescribe.txt ├── D1 IC │ ├── Image.png │ └── ProductDescribe.txt └── XR806 Board ├── Image.png └── ProductDescribe.txt
ProductDescribe.txt 文件第一行为商品名字,第二行为价格(价格必须保留小数两位),第三(商品id)行为付款成功后控制的 GPIO(1-GPIOD11, 2-GPIO12, 3-GPIO13)。余下信息均为商品描述信息。
cat D1 Board/ProductDescribe.txt D1 Board 599.99 1 CPU : C906 64bit RISC-V 32 KB I-cache + 32 KB D-cache DSP : HiFi4 DSP 600MHz 32 KB I-cache + 32 KB D-cache 64 KB I-ram + 64 KB D-ram Memory : DDR2/DDR3, up to 2 GB SD3.0/eMMC 5.0, SPI Nor/Nand Flash
客户端与服务端数据交互格式
通信数据采用 json 数据,定义的数据存在多余的,部分并没有使用到
客户端发送订单信息至服务器
{ "device_id":"kw", 设备id "msg_type":"0", 0客户端发送订单 1服务器返回收款信息至客户端 2支付成功服务器返回至客户端 "product_id":"1", 商品id 用于控制 GPIO "product_name":"D1 IC", 商品名称 "pay_way":"0", 0支付宝 1微信 "price":"34.97" 价格 }
服务器返回生成的支付二维码信息至客户端
{ "device_id":"kw", 设备id "msg_type":"1", 0客户端发送订单 1服务器返回收款信息至客户端 2支付成功服务器返回至客户端 "product_id":"1", 商品id 用于控制 GPIO "pay_way":"0", 0支付宝 1微信 "return":"ok", ok err "price":"34.97", 价格 "out_trade_no":"63827381363", 订单号 "pay_qrcode":"xxxweduwqcfgy3t72" 用于生成二维码 }
支付成功服务器返回至客户端,支付失败则不返回
{ "device_id":"kw", 设备id "msg_type":"2", 0客户端发送订单 1服务器返回收款信息至客户端 2支付成功服务器返回至客户端 "product_id":"1", 商品id 用于控制 GPIO "pay_way":"0", 0支付宝 1微信 "return":"ok", ok err "price":"34.97", 价格 "out_trade_no":"63827381363" 订单号 }
服务器端工程结构
eva@ubuntu:~/Desktop/d1_pay_server_master$ tree . ├── D1PayServer │ ├── pom.xml │ ├── resource │ │ └── zfbinfo.properties │ ├── src │ │ ├── main │ │ │ └── java │ │ │ └── com │ │ │ └── nuist │ │ │ └── kw │ │ │ └── D1PayServer │ │ │ ├── AliPayThread.java │ │ │ ├── App.java │ │ │ ├── CommonUtils.java │ │ │ ├── MyConfig.java │ │ │ ├── OrderInformation.java │ │ │ ├── PaymentInformation.java │ │ │ ├── PayThread.java │ │ │ ├── ResultInformation.java │ │ │ └── WxPayThread.java
zfbinfo.properties 保存支付宝 APPID 等信息
App.java 初始化一个 mqtt 服务器,main 入口
MyConfig.java 微信 APPID 等信息
PayThread.java 当 mqtt 服务器收到一个订单消息,进行判断是支付宝支付,还是微信支付,然后开启相应的支付处理线程
AliPayThread.java 支付宝支付线程,负责请求支付二维码,循环判断订单支付结果,3 分钟未支付,则不再处理。
WxPayThread.java 微信支付线程,负责请求支付二维码,循环判断订单支付结果,3 分钟未支付,则不再处理。
OrderInformation.java PaymentInformation.java ResultInformation.java 负责构造通信数据字符串。
Maven 项目依赖
<!-- 微信sdk --> <dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> <version>0.0.3</version> </dependency> <!-- 支付宝sdk --> <dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-sdk-java</artifactId> <version>4.10.209.ALL</version> </dependency> <!-- mqtt sdk --> <dependency> <groupId>org.eclipse.paho</groupId> <artifactId>org.eclipse.paho.client.mqttv3</artifactId> <version>1.2.5</version> </dependency> <!-- json --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency>
客户端工程结构
客户端代码结构如下,app 存放的是应用代码,build 存放的是编译生成的 .o 文件以及顶层 Makefile(使用的百问网的 lvgl 移植的 Makefile),build.sh 编译脚本,lirary 存放的是库源码,Makefile 硬链接指向 build/Makefile,out 为输出的应用程序目录。
eva@ubuntu:~/Desktop/d1_pay_client$ . ├── app │ ├── app.mk │ ├── include │ ├── launcher_ui.c # UI 界面 │ ├── launcher_ui.h │ ├── lv_drv_init.c # 驱动初始化 │ ├── lv_drv_init.h │ ├── main.c # 程序入口 │ ├── mqtt_client.c # mqtt 客户端初始化 数据处理 │ ├── mqtt_client.h │ ├── pin_control.c # 引脚控制,增加引脚修改该文件 │ ├── pin_control.h │ ├── play_pay_result.c # 语音播报 │ ├── play_pay_result.h │ ├── untilities.c # 提供一些函数 │ └── untilities.h ├── build │ └── Makefile ├── build.sh ├── lirary ├── Makefile └── out ├── bin ├── etc └── lib
build.sh 中指定编译工具链,通过 ./build.sh 进行编译,./build.sh clean 进行清除编译中间文件。
修改引脚修改 pin_control.c 如下部分(计算公式 32*n+i)
mosquitto编译
应用程序使用了 mosquitto 库,build.sh并不会去编译它,所以这个需要单独编译,编译完成后,将库拷贝到 out/lib 目录下。mosquitto 在 lirary 目录下,在 lirary 目录下新建一个 mosquitto-risc 目录,用于保存编译输出文件。
设置交叉编译工具链
vim ~/.bashrc export PATH=$PATH:/home/eva/d1/D1/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/bin/ source ~/.bashrc
交叉编译 uuid
tar -vxf libuuid-1.0.3.tar.gz ./configure --prefix=/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc CC=riscv64-unknown-linux-gnu-gcc --host=riscv64-unknown-linux-gnu make && make install
交叉编译 openssl 库
tar -vxf openssl-1.0.2g.tar.gz ./config no-asm shared --prefix=/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc #删除Makefile中的-m64(一共有两个),修改Makefile中的 CC= riscv64-unknown-linux-gnu-gcc AR= riscv64-unknown-linux-gnu-ar $(ARFLAGS) r RANLIB= riscv64-unknown-linux-gnu-ranlib NM= riscv64-unknown-linux-gnu-nm make && make install
交叉编译 mosquitto
tar -vxf mosquitto-1.5.tar.gz make WITH_SRV=no CC=riscv64-unknown-linux-gnu-gcc CXX=riscv64-unknown-linux-gnu-g++ CFLAGS="-I /home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc/include -I /home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc/include" LDFLAGS="-L/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc/lib -L/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc/lib -lssl -lcrypto -luuid" make DESTDIR=/home/eva/Desktop/d1_pay_client/lirary/mosquitto-risc install
D1 内核配置
配置编译环境
source build/envsetup.sh lunch d1_nezha-tina
开启 nfs
make kernel_menuconfig File systems ---> [*] Network File Systems ---> │ │ <*> NFS client support │ │ │ │ <*> NFS client support for NFS version 2 │ │ │ │ [*] NFS client support for NFS version 3 │ │ │ │ [*] NFS client support for the NFSv3 ACL protocol extension│ │ │ │ [*] NFS client support for NFS version 4 │ │ │ │ [*] NFS client support for NFSv4.1 │ │ │ │ [*] NFS client support for NFSv4.2 │ │ │ │ (kernel.org) NFSv4.1 Implementation ID Domain │ │ │ │ [*] NFSv4.1 client support for migration │ │ │ │ [*] Use the legacy NFS DNS resolver
修改开机默认 HDMI 输出(如果开机不是默认 HDMI 输出,开机后再启动 HDMI 输出,会输出有问题)
修改 uboot 设备树文件
./D1/device/config/chips/d1/configs/nezha/uboot-board.dts 214 行 disp_init_enable = <1>; disp_mode = <0>; - screen0_output_type = <1>; - screen0_output_mode = <4>; - - screen1_output_type = <3>; - screen1_output_mode = <10>; - - screen1_output_format = <0>; - screen1_output_bits = <0>; - screen1_output_eotf = <4>; - screen1_output_cs = <257>; - screen1_output_dvi_hdmi = <2>; - screen1_output_range = <2>; - screen1_output_scan = <0>; - screen1_output_aspect_ratio = <8>; - - dev0_output_type = <1>; - dev0_output_mode = <4>; + screen0_output_type = <3>; + screen0_output_mode = <10>; + + screen0_output_format = <0>; + screen0_output_bits = <0>; + screen0_output_eotf = <4>; + screen0_output_cs = <257>; + screen0_output_dvi_hdmi = <2>; + screen0_output_range = <2>; + screen0_output_scan = <0>; + screen0_output_aspect_ratio = <8>; + + screen1_output_type = <1>; + screen1_output_mode = <4>; + + dev0_output_type = <4>; + dev0_output_mode = <2>; dev0_screen_id = <0>; - dev0_do_hpd = <0>; - - dev1_output_type = <4>; - dev1_output_mode = <10>; - dev1_screen_id = <1>; - dev1_do_hpd = <1>; + dev0_do_hpd = <1>; def_output_dev = <0>; hdmi_mode_check = <1>;
修改 linux 设备树文件
./D1/device/config/chips/d1/configs/nezha/linux-5.4/board.dts 1128 行 disp_init_enable = <1>; disp_mode = <0>; - screen0_output_type = <1>; - screen0_output_mode = <4>; - - screen1_output_type = <3>; - screen1_output_mode = <10>; - - screen1_output_format = <0>; - screen1_output_bits = <0>; - screen1_output_eotf = <4>; - screen1_output_cs = <257>; - screen1_output_dvi_hdmi = <2>; - screen1_output_range = <2>; - screen1_output_scan = <0>; - screen1_output_aspect_ratio = <8>; - - dev0_output_type = <1>; - dev0_output_mode = <4>; + screen0_output_type = <3>; + screen0_output_mode = <10>; + + screen0_output_format = <0>; + screen0_output_bits = <0>; + screen0_output_eotf = <4>; + screen0_output_cs = <257>; + screen0_output_dvi_hdmi = <2>; + screen0_output_range = <2>; + screen0_output_scan = <0>; + screen0_output_aspect_ratio = <8>; + + screen1_output_type = <1>; + screen1_output_mode = <4>; + + dev0_output_type = <4>; + dev0_output_mode = <2>; dev0_screen_id = <0>; - dev0_do_hpd = <0>; - - dev1_output_type = <4>; - dev1_output_mode = <10>; - dev1_screen_id = <1>; - dev1_do_hpd = <1>; + dev0_do_hpd = <1>; def_output_dev = <0>; hdmi_mode_check = <1>;
dev0_output_mode 为分辨率,这里设置为 480P
enum disp_tv_mode { DISP_TV_MOD_480I = 0, DISP_TV_MOD_576I = 1, DISP_TV_MOD_480P = 2, DISP_TV_MOD_576P = 3, DISP_TV_MOD_720P_50HZ = 4, DISP_TV_MOD_720P_60HZ = 5, DISP_TV_MOD_1080I_50HZ = 6, DISP_TV_MOD_1080I_60HZ = 7, DISP_TV_MOD_1080P_24HZ = 8, DISP_TV_MOD_1080P_50HZ = 9, DISP_TV_MOD_1080P_60HZ = 0xa, /***/
编译 uboot
cboot muboot
进入顶层目录,编译其它部分
make -j8 pack
代码,固件下载
D1PayPack.zip演示视频
-
卧槽!大工程啊~
-
此回复已被删除! -
用 ffmpeg 命令行把楼主的mp4转码了:
"D:\Downloads\ffmpeg-N-98443-gf719f86990-win64-shared\ffmpeg.exe" -i "D:\Downloads\录制_2021_11_18_16_42_02_768.mp4" -vcodec libx264 -acodec copy x.mp4
-
编译了 freetype 能够显示中文了
输出目录 /home/eva/Desktop/d1_pay_client/lirary/freetype-tmp
freetype 目录 /home/eva/Desktop/d1_pay_client/lirary/freetype-2.11.0
交叉工具链 riscv64-unknown-linux-gnu-gcc./configure --host=riscv64-unknown-linux-gnu --enable-shared --enable-static --with-zlib=no --with-bzip2=no --with-png=no --with-harfbuzz=no make make DESTDIR=/home/eva/Desktop/d1_pay_client/lirary/freetype-tmp install
-
-
-
有没有哪位大佬玩起来了?
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号