【移远QuecPython】EC800M物联网开发板的内置GNSS定位的恶性BUG(目前没有完全的解决方案)

【移远QuecPython】EC800M物联网开发板的内置GNSS定位的恶性BUG(目前没有完全的解决方案)

GNSS配置如下:
【移远QuecPython】EC800M物联网开发板的内置GNSS定位获取(北斗、GPS和GNSS)

测试视频(包括BUG复现):

【移远QuecPython】EC800M物联网开发板的内置GNSS定位的恶性BUG(目前没有完全的解决方案)

文章目录

  • 程序跑飞BUG
  • 主线程占用BUG(可以解决)
  • BUG可能原因猜想和目前解决方案
    • GNSS数据缓存越界
    • 线程优先级占用
    • 目前解决方案
  • 附录:列表的赋值类型和py打包
    • 列表赋值
      • BUG复现
      • 代码改进
      • 优化
      • 总结
    • py打包

程序跑飞BUG

BUG复现:
在我之前的文章中 我在main函数中放了一个死循环
每隔1s 就读一次GNSS数据 同时通过串口打印出来
其中 跑了25次后 GNSS数据有效
我发现 大概跑了20次后(也就是第45次) 程序会直接跑死 然后大概等个30s又会恢复
恢复以后又能继续读取 且不会再次跑死

此次跑死之前 已经进行了打印 并且串口输出一致 如图:
在这里插入图片描述
相关函数都在我上一篇文章中

于是我进行了如下测试:

  1. 注释串口发送 只用print 发现仍然存在
  2. 将time.sleep(1)替换成一个for循环delay 发现无法读取GNSS数据 遂引出第二个BUG
  3. 保留GNSS初始化 将读取GNSS注释 只用串口打印一个次数或只用print打印 发现仍然存在
  4. 将GNSS初始化注释 GNSS读取注释 只用串口和print打印一个次数 发现没有BUG
  5. 保留GNSS初始化 注释GNSS读取 在室内进行串口和print测试 发现没有BUG

情况3和情况2我都在视频里面一起放出来了

由此可见 出现BUG时 就是GNSS模块初始化上电以后 并且需要获取到数据以后(不管是否进行读取) 都会出现这个BUG

主线程占用BUG(可以解决)

上文提到的第2种情况
写了一个简单延时:

def delay(n):for i in range(n):for j in range(500):i=i
delay(500)

实测这个延时大概也就是1s时间 比1s稍微大一点点
如图:
GNSS数据始终没有(如果数据无效 也会返回NMEA-0183协议的数据 只不过里面的值不存在)
并且一直保持这样
在这里插入图片描述

BUG可能原因猜想和目前解决方案

此py环境其实是一种虚拟环境
底层是RTOS 然后RTOS生成一个Python里面跑命令行的环境 最后再通过这个环境执行py代码
也就是三层嵌套

GNSS数据缓存越界

观察到 在GNSS初始化上电成功 并能读出第一条数据开始 过了大约30s 就会跑死
并且特别稳定 每次都是那个计数点
所以 可能就是在此期间 底层寄存器的缓存越界 导致出现跑飞BUG
但是 等跑飞恢复以后 又能一直持续工作 所以可能是初始化的指针位置没给对?
有待考证

线程优先级占用

RTOS主要负责寄存器和CPU的任务调度
那么 就有可能 在主线程中跑了死循环 导致GNSS模块的线程无法执行初始化
但是这一点手册并没有提到 只是说会抢占LTE资源
有待考证

目前解决方案

多线程解决
中断优先级>线程>主线程
该方法可以解决GNSS被线程占用的问题 但无法解决跑飞的问题
另外 不建议使用多线程 其中一个原因就是 如果不强制关闭或者复位 线程使用不安全很容易越界

附录:列表的赋值类型和py打包

列表赋值

BUG复现

闲来无事写了个小程序 代码如下:

# -*- coding: utf-8 -*-
"""
Created on Fri Nov 19 19:47:01 2021@author: 16016
"""a_list = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']
#print(len(a_list))
#b_list = ['','','','','','','','','','','','','','','','']
c_list = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]
#for i in range(16):
if len(a_list):for j in range(16):a_list[j]=str(a_list[j])+'_'+str(j)print("序号:",j)print('a_list:\n',a_list)c_list[j]=a_listprint('c_list[0]:\n',c_list[0])print('\n')
#        b_list[j]=a_list[7],a_list[8]
#        print(b_list[j])# 写入到Excel:
#print(c_list,'\n')    

我在程序中 做了一个16次的for循环 把列表a的每个值后面依次加上"_"和循环序号
比如循环第x次 就是把第x位加上_x 这一位变成x_x 我在输出测试中 列表a的每一次输出也是对的
循环16次后列表a应该变成[‘0_0’, ‘1_1’, ‘2_2’, ‘3_3’, ‘4_4’, ‘5_5’, ‘6_6’, ‘7_7’, ‘8_8’, ‘9_9’, ‘10_10’, ‘11_11’, ‘12_12’, ‘13_13’, ‘14_14’, ‘15_15’] 这也是对的

同时 我将每一次循环时列表a的值 写入到空列表c中 比如第x次循环 就是把更改以后的列表a的值 写入到列表c的第x位
第0次循环后 c[0]的值应该是[‘0_0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘10’, ‘11’, ‘12’, ‘13’, ‘14’, ‘15’] 这也是对的
但是在第1次循环以后 c[0]的值就一直在变 变成了c[x]的值
相当于把c_list[0]变成了c_list[1]…以此类推 最后得出的列表c的值也是每一项完全一样
我不明白这是怎么回事
我的c[0]只在第0次循环时被赋值了 但是后面它的值跟着在改变

如图:
在这里插入图片描述
第一次老出bug 赋值以后 每次循环都改变c[0]的值 搞了半天都没搞出来
无论是用appen函数添加 还是用二维数组定义 或者增加第三个空数组来过渡 都无法解决

代码改进

后来在我华科同学的指导下 突然想到赋值可以赋的是个地址 地址里面的值一直变化 导致赋值也一直变化 于是用第二张图的循环套循环深度复制实现了

代码如下:

# -*- coding: utf-8 -*-
"""
Created on Fri Nov 19 19:47:01 2021@author: 16016
"""a_list = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']
#print(len(a_list))
#b_list = ['','','','','','','','','','','','','','','','']
c_list = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]
#for i in range(16):
if len(a_list):for j in range(16):a_list[j]=str(a_list[j])+'_'+str(j)print("序号:",j)print('a_list:\n',a_list)for i in range(16):c_list[j].append(a_list[i])print('c_list[0]:\n',c_list[0])print('\n')
#        b_list[j]=a_list[7],a_list[8]
#        print(b_list[j])# 写入到Excel:
print(c_list,'\n')    

解决了问题

在这里插入图片描述

优化

第三次是请教了老师 用copy函数来赋真值

代码如下:

# -*- coding: utf-8 -*-
"""
Created on Fri Nov 19 19:47:01 2021@author: 16016
"""a_list = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']
#print(len(a_list))
#b_list = ['','','','','','','','','','','','','','','','']
c_list = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]
#for i in range(16):
if len(a_list):for j in range(16):a_list[j]=str(a_list[j])+'_'+str(j)print("序号:",j)print('a_list:\n',a_list)c_list[j]=a_list.copy()print('c_list[0]:\n',c_list[0])print('\n')
#        b_list[j]=a_list[7],a_list[8]
#        print(b_list[j])# 写入到Excel:
#print(c_list,'\n')    

同样能解决问题
在这里插入图片描述
最后得出问题 就是指针惹的祸!

a_list指向的是个地址 而不是值 a_list[i]指向的才是单个的值 copy()函数也是复制值而不是地址

如果这个用C语言来写 就直观一些了 难怪C语言是基础 光学Python不学C 遇到这样的问题就解决不了

C语言yyds Python是什么垃圾弱智语言

总结

由于Python无法单独定义一个值为指针或者独立的值 所以只能用列表来传送
只要赋值是指向一个列表整体的 那么就是指向的一个指针内存地址 解决方法只有一个 那就是将每个值深度复制赋值(子列表内的元素提取出来重新依次连接) 或者用copy函数单独赋值

如图测试:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
部分代码:

# -*- coding: utf-8 -*-
"""
Created on Sat Nov 20 16:45:48 2021@author: 16016
"""def text1():A=[1,2,3]B=[[],[],[]]for i in range(len(A)):A[i]=A[i]+iB[i]=Aprint(B)def text2():A=[1,2,3]B=[[],[],[]]A[0]=A[0]+0B[0]=Aprint(B)A[1]=A[1]+1B[1]=Aprint(B)A[2]=A[2]+2B[2]=Aprint(B)if __name__ == '__main__':text1()print('\n')text2()

py打包

Pyinstaller打包exe(包括打包资源文件 绝不出错版)

依赖包及其对应的版本号

PyQt5 5.10.1
PyQt5-Qt5 5.15.2
PyQt5-sip 12.9.0

pyinstaller 4.5.1
pyinstaller-hooks-contrib 2021.3

Pyinstaller -F setup.py 打包exe

Pyinstaller -F -w setup.py 不带控制台的打包

Pyinstaller -F -i xx.ico setup.py 打包指定exe图标打包

打包exe参数说明:

-F:打包后只生成单个exe格式文件;

-D:默认选项,创建一个目录,包含exe文件以及大量依赖文件;

-c:默认选项,使用控制台(就是类似cmd的黑框);

-w:不使用控制台;

-p:添加搜索路径,让其找到对应的库;

-i:改变生成程序的icon图标。

如果要打包资源文件
则需要对代码中的路径进行转换处理
另外要注意的是 如果要打包资源文件 则py程序里面的路径要从./xxx/yy换成xxx/yy 并且进行路径转换
但如果不打包资源文件的话 最好路径还是用作./xxx/yy 并且不进行路径转换

def get_resource_path(relative_path):if hasattr(sys, '_MEIPASS'):return os.path.join(sys._MEIPASS, relative_path)return os.path.join(os.path.abspath("."), relative_path)

而后再spec文件中的datas部分加入目录
如:

a = Analysis(['cxk.py'],pathex=['D:\\Python Test\\cxk'],binaries=[],datas=[('root','root')],hiddenimports=[],hookspath=[],hooksconfig={},runtime_hooks=[],excludes=[],win_no_prefer_redirects=False,win_private_assemblies=False,cipher=block_cipher,noarchive=False)

而后直接Pyinstaller -F setup.spec即可

如果打包的文件过大则更改spec文件中的excludes 把不需要的库写进去(但是已经在环境中安装了的)就行

这些不要了的库在上一次编译时的shell里面输出
比如:
在这里插入图片描述

在这里插入图片描述
然后用pyinstaller --clean -F 某某.spec

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/180514.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Iceberg教程

目录 教程来源于尚硅谷1. 简介1.1 概述1.2 特性 2. 存储结构2.1 数据文件(data files)2.2 表快照(Snapshot)2.3 清单列表(Manifest list)2.4 清单文件(Manifest file)2.5 查询流程分析 3. 与Flink集成3.1 环境准备3.1.1 安装Flink3.1.2 启动Sql-Client 3.2 语法 教程来源于尚硅…

【RabbitMQ】RabbitMQ 消息的可靠性 —— 生产者和消费者消息的确认,消息的持久化以及消费失败的重试机制

文章目录 前言:消息的可靠性问题一、生产者消息的确认1.1 生产者确认机制1.2 实现生产者消息的确认1.3 验证生产者消息的确认 二、消息的持久化2.1 演示消息的丢失2.2 声明持久化的交换机和队列2.3 发送持久化的消息 三、消费者消息的确认3.1 配置消费者消息确认3.2…

Git从基础到实践

1.Git是用来做什么的? git就是一款版本控制软件,主要面向代码的管理。你可以理解为Git是一个代码的备份器,给你的每一次修改后的代码做个备份,防止丢失,这个是git最基本的功能。 其次,git不止备份,当你需要比对多…

NEFU数字图像处理(5)图像压缩编码

一、概述 1.1简介 图像压缩编码的过程是在图像存储或传输之前进行,然后再由压缩后的图像数据(编码数据)恢复出原始图像或者是原始图像的近似图像 无损压缩:在压缩过程中没有信息损失,可由编码数据完全恢复出原始图像有…

iOS App Store上传项目报错 缺少隐私政策网址(URL)解决方法

​ 一、问题如下图所示: ​ 二、解决办法:使用Google浏览器(翻译成中文)直接打开该网址 https://www.freeprivacypolicy.com/free-privacy-policy-generator.php 按照要求填写APP信息,最后将生成的网址复制粘贴到隐…

【SOC基础】单片机学习案例汇总 Part2:蜂鸣器、数码管显示

📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…

xilinx fpga ddr mig axi

硬件 参考: https://zhuanlan.zhihu.com/p/97491454 https://blog.csdn.net/qq_22222449/article/details/106492469 https://zhuanlan.zhihu.com/p/26327347 https://zhuanlan.zhihu.com/p/582524766 包括野火、正点原子的资料 一片内存是 1Gbit 128MByte 16bit …

【wp】2023鹏城杯初赛 Web web1(反序列化漏洞)

考点&#xff1a; 常规的PHP反序列化漏洞双写绕过waf 签到题 源码&#xff1a; <?php show_source(__FILE__); error_reporting(0); class Hacker{private $exp;private $cmd;public function __toString(){call_user_func(system, "cat /flag");} }class A {p…

Spring基础

文章目录 Spring基础IoC容器基础IoC理论第一个Spring程序Bean注册与配置依赖注入自动装配生命周期与继承工厂模式和工厂Bean注解开发 AOP面向切片配置实现AOP接口实现AOP注解实现AOP Spring基础 Spring是为了简化开发而生&#xff0c;它是轻量级的IoC和AOP的容器框架&#xff…

I/O多路转接之select

承接上文&#xff1a;I/O模型之非阻塞IO-CSDN博客 简介 select函数原型介绍使用 一个select简单的服务器的代码书写 select的缺点 初识select 系统提供select函数来实现多路复用输入/输出模型 select系统调用是用来让我们的程序监视多个文件描述符的状态变化的; 程序会停在s…

Vue3 实现 clipboard 复制功能

一个很小的交互功能&#xff0c;网上搜了一下有一个 vue3-clipboard 直接支持vue3&#xff0c;到github仓库看了下&#xff0c;原作者已经不维护这个项目了&#xff1a; 推荐使用 vueuse 自带的 useclipboard 功能&#xff0c;由 vue 团队维护&#xff0c;稳定性基本没问题 官…

数据结构构之顺序表

1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线…

MySQL连接时出现Host ‘::1‘ is not allowed to connect to this MySQL server

报错原因 之前想着要提高一下连接速度&#xff0c;所以在my.ini中加入了&#xff1a;skip-name-resolve&#xff0c;当时的数据库root账号设置的登录权限是%&#xff0c;因此没有出现连接错误&#xff0c;这次因为是新建数据库&#xff0c;root账号的登录权限默认是localhost&…

园区网真实详细配置大全案例

实现要求&#xff1a; 1、只允许行政部电脑对全网telnet管理 2、所有dhcp都在核心 3、wifi用户只能上外网&#xff0c;不能访问局域网其它电脑 4、所有接入交换机上bpdu保护 5、只允许vlan 10-40上网 5、所有接入交换机开dhcp snoop 6、所有的交换机指定核心交换机为ntp时间服务…

解决Visual Studio Code 控制台中文乱码问题

C和CPP运行编码指定 "code-runner.executorMap": {"c": "cd $dir && gcc -fexec-charsetGBK $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt","cpp": "cd $dir && g -fexec-charsetGBK $…

LV.12 D16 轮询与中断 学习笔记

一、CPU与硬件的交互方式 轮询 CPU执行程序时不断地询问硬件是否需要其服务&#xff0c;若需要则给予其服务&#xff0c;若不需要一段时间后再次询问&#xff0c;周而复始 中断 CPU执行程序时若硬件需要其服务&#xff0c;对应的硬件给CPU发送中断信号&#xff0c…

AD教程(六)现有元件模型的调用

AD教程&#xff08;六&#xff09;现有元件模型的调用 导入现有原理图 Altium Schematic Document (.SchDoc) 直接拖入AD即可 直接用现有原理图生成原理图库 点击设计&#xff0c;选择生成原理图库&#xff0c;进入归类设置界面&#xff08;用原理图直接生成原理图库&#xf…

如何实现多租户系统

shigen日更文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 不知道为什么&#xff0c;最近老是有一些失眠&#xff0c;凌晨睡&#xff0c;两点半还在醒着。脑子里想着自己生…

Linux flock和fcntl函数详解

文章目录 flock函数描述返回值和错误码笔记 fcntl函数描述复制文件描述符文件描述标志文件状态标志 咨询锁强制锁管理信号租赁文件和目录变更通知改变管道容量 返回值错误备注遗留问题 flock函数 主要功能是在已打开的文件应用或者删除共享锁或者独占锁。sys/file.h声明了这个…

使用Postman工具做接口测试 —— 环境变量与请求参数格式!

引言 在上一篇笔记我们主要介绍了接口测试的基础知识与基本功能&#xff0c;本章主要介绍如何使用postman做接口测试。 配置环境变量和全局变量 环境变量和全局变量 环境管理中还可以点击“Global”添加全局变量&#xff0c;环境变量只有当选择了该环境时才生效&#xff0c;…