离线win7上用anaconda离线创建虚拟环境

本文所需文件的下载路径为: 百度云链接:https://pan.baidu.com/s/14S-xkERRhQVNfV-dauVYzw 提取码:5hzn 第一步:安装anaconda。 win7系统不支持python3.9,因此不能在win7系统上安装过新的anaconda,否则会出现无法创建menu的错误。根据经验,win7支持 Anaconda3-2021.05-Windows-x86_64.exe 的安装。 建议把anaconda安装到D盘或E盘,因为创建虚拟环境需要占用较大内存,一个虚拟环境约需要占1G多的内存。 第二步:解压env.rar文件,拷贝到anaconda的安装路径下,替换原来的env文件夹。 在离线条件下,conda不能从零创建一个虚拟环境,需要从其他地方拷贝。我在联网的机器上创建了4个纯净的虚拟环境:base-env-py36;base-env-py37;base-env-py38;base-env-py39。 对应的python版本分别是python3.6,python3.7,python3.8,python3.9。 在安装完anaconda后,可将env.rar解压,替换anaconda安装路径下的env文件夹。此时,conda可以自动检测到这四个虚拟环境。之后,可基于这四个基础的虚拟环境创建新的虚拟环境。 第三步:使用clone创建新的虚拟环境。 在cmd命令行终端或anaconda prompt中输入以下指令创建新的虚拟环境。 conda create -n your_env_name --offline --clone path_to_existed_base_env 示例: conda create -n work-env-py37 --offline --clone E:\software-setups\Anaconda3\envs\base-env-py37 一般,为每一个项目单独创建一个虚拟环境,因此不建议直接使用本文提供的纯净虚拟环境。 第四步:给创建的虚拟环境安装需要的功能package,如numpy,tensorflow等。 建议先在联网的机器上下载好相关的依赖包,然后拷贝到离线机器上安装,具体可参考我的博客python环境迁移:从联网笔记本到离线服务器_wzg2016的博客-CSDN博客

NB-IoT和LTE远程通讯方案选择

方案一:基于NB-IoT低功耗远程传输技术 物联网的一个重要技术就是NB-IoT技术,其依托电信运营商传统蜂窝网络建立而成,信道上行采用SC—FDMA通信调制方式,下行采用OFDMA通信调制方式,信号发射功率为3dBm,可实现在现有电信网络的平滑升级,快速实现全面网络覆盖。信道占用带宽200KHz,可直接部署于GSM网络、UMTS网络或者TLE网络,信道有独立部署、带内部署、边带部署三种不同的部署方式。网络连接可靠性极高,比传统的GPRS覆盖能力增强20dB,单个基站可以接入5万个设备终端,最大覆盖范围可达15Km,还能提供全面的室内覆盖连接。频段由通信运营商网络授权,连接具有高安全性,便于安装和维护。所有基于低功耗的物联网领域的设备都可以接入到广域网的蜂窝数据连接,采用不需要中继的星型网络模式,应用了两种低功耗技术PSM和eDRX,低功耗设备的待机时间得到极大提升。因为拥有庞大的市场基础和芯片的低成本技术,所以使用成本大大降低。NB-IoT技术的广覆盖、高可靠性、高安全性、低成本、低功耗等特点,能够从根本上解决工业监测领域的诸多问题。 基于NB-IoT超低功耗远程传输应用,架构主要由带NB-IoT通信模组的监测终端、NB-IoT通信基站、物联网云平台、业务服务器、客户端管理软件等构成。具备NB-IoT通信功能的监测终端部署于工程现场后,监测终端会自动搜寻附近的NB-IoT通信基站,然后凭借基站信号注册到物联网云平台,该设备将上报和接收的数据汇报给物联网云平台,物联网云平台通过通信基站接收监测终端上传的状态数据,云平台的控制数据包发送到监测终端。 远程控制指令业务类型: 如设备远程开启/关闭、设备触发发送上行报告,下行极小数据量(十字节量级),其传输周期以天和小时为单位。 自主异常报告业务类型: 如烟雾报警探测器、设备工作异常等,上行极小数据量(十字节量级),其传输周期以年和月为单位。 软件远程更新业务类型: 如软件补丁/更新,上行下行较大数据量需求(千字节量级),周期多以天、小时为单位。 自主周期报告业务类型: 如公共事业的远程抄表、环境监测等,上行较小数据量(百字节量级),周期多以天、小时为单位。 NB-IoT适合数据量较小,以小时、天为周期进行交换数据,响应会延时。其次超过预定流量,移动收费通常是0.3元/Mb,电信是按照连接超过20000次,则0.001元/次。 随着3大运营商均已经发文明确2G的退网期限,Nb-Iot通信技术低功耗远程传输技术可能会有所限制。其次,NB-IoT适合低速率业务,更适合静态业务、数据量较小,且对时延低敏感、非连续移动、非实时传输数据的业务场景。 基于方案一可能会出现的问题,我们制定了第二套方案,基于LTE-Cat.1远程传输技术。 方案二:基于LTE-Cat.1远程传输技术 LTE-Cat.1,大家可以理解一个为低配版的4G通信技术。它的速率比我们手机使用的4G慢,但是成本也低;它完全使用现有的4G网络即可,运营商无需新建基站,网络覆盖可以说是最好的了,仅中国移动在全国就有450W座4G基站;相比NB-IoT,它的成本还是高,但是网络覆盖要优于NB-IoT;拥有跟LTE Cat.4相同的毫秒级传输时延,以及支持100公里/小时以上的移动速度。 NB-IOT技术和LTE技术的比较 1、NB-IOT技术: a) 介绍: NB-IoT是IoT领域一个新兴的技术,支持低功耗设备在广域网的蜂窝数据连接,也被叫作低功耗广域网(LPWAN)。NB-IoT支持待机时间长、对网络连接要求较高设备的高效连接。 b)网络架构: NB-IoT使用的是License频段,可采取带内、保护带或独立载波等三种部署方式,与现有网络共存。 c)优点: ①广覆盖,将提供改进的室内覆盖,在同样的频段下,NB-IoT比现有的网络增益20dB,相当于提升了100倍覆盖区域的能力。 ②二是具备支撑连接的能力,NB-IoT一个扇区能够支持10万个连接,支持低延时敏感度、超低的设备成本、低设备功耗和优化的网络架构 ③三是更低功耗,NB-IoT终端模块的待机时间可长达10年。 ④超低的模块成本,企业预期的单个接连模块不超过5美元。 d)缺点: ①NB-IoT是运营商建网和提供服务。 ②数据是由运营商中转,所以数据可能会存在泄露问题。 2、LTE-Cat.1技术: a)市场需求: ①3大运营商均已经发文明确2G的退网期限。 ②在新部署的物联网连接中NB-IoT、4G会逐步替代2G模组。 ③目前主流LTE Cat.4的价格依然过高。 ④NB-IoT在语音、短信以及连接时效性上略显不足。 ⑤LTE Cat.1隶属4G系列,可复用现有4G资源,实现产品快速上市还可降低成本。 b) LTE-CAT.1的优势: ①LTE Cat.1下行速率最大为10Mbps,上行5Mbps,能满足中低速的物联网业务市场。 ②运营商无需升级网络,只需简单的参数配置,允许Cat.1终端接入网络即可。 ③LTE Cat.1通信产品,有着比NB-IoT、2G模组更好的网络覆盖、更快的速度、更低的延时。 ④LTE Cat.1比传统LTE Cat.4模组拥有更低的成本、更低的功耗,非常适用于对性价比、时延性、网络覆盖、通信速度有要求的应用场景。 在某些产品应用中,NB-IoT确实有自己的优势: 1、NB-IoT是否适用于电力抄表? 电力抄表的场景分为用户侧通信和配网通信系统。电力负荷监控系统频段采用 230 MHz +1.8GHz 的 TD-LTE 专网。 用户电表的远程抄表采用过很多技术, 包括 GPRS、 3G、 LTE、 PLC、 Zigbee、 433MHz 等等,抄表频率的目标是 15 分钟一次采集和上传,每天 96 个点,以便实现电网的在线监 测控制。 中国等居住集中的地方主要是采用集中式抄表,主要有电力光纤集抄和 GPRS 集抄(占 比超过 50%),欧美等居住分散的地方主要采用独立抄表。 由于电力抄表供电不是问题,数据量相对较大,目前尚未体会到电力抄表利用 NB-IoT 的迫切需求。

基于stm32的自动循迹及自动搬运物联网图传小车

前言 本着技术本身的原则,写了这篇博客,为尚未接触嵌入式C编程,和正在学习C编程的同学提供一套完整的智能小车方案和学习思路。 本篇介绍的是纯自主开发的单片机智能小车,不同于网上那些,本篇介绍的是集成了红外循迹,超声波测距,机械臂抓取,蓝牙控制,视频图传在内的一套综合应用方案,代码方案可应用于实际项目。 视频演示:【梦飞智能-多功能机械臂小车-哔哩哔哩】 https://b23.tv/2EvpPYa 1.硬件组成 (1)小车主控采用stm32F030c8t6,主频48M,RAM20KB,flash64KB,ARMcortex-M0内核,引出了3路舵机接口用于控制机械臂,4路PWM用于电机控制,4路GPIO用于循迹传感器连接,以及一个超声波传感器接口和一个串口,主板大小只有5cm x 3.5cm左右,非常小巧美观,四个安装孔设计的可直接安装在舵机云台底部,采用USB供电或者5V电源接口供电。 (2)小车驱动板是梦飞自主开发的双LM2596+RZ7889电源和电机驱动一体化设计,电压输入6-15V,5V输出能力达到3A,电机驱动能力达到5A,(注意这个数据,可查查一般驱动板是什么能力) (3)极简三自由度机械臂,说高级一点这个模块是个机械臂,说简单点就是一个两轴云台+一个爪子,之所以这样做的目的就是方便定位和快速抓取,不用空间逆运算定位物体坐标,对于MCU来讲就是三个PWM控制上下左右和夹取,因此代码实现难度上非常简单,适合初学者。 (4)基于ESP32的视频图传和蓝牙控制方案,这里所讲的是两个模块,ESP32图传模块,以及蓝牙控制模块,ESP32支持HTTP协议获取图传,以及RTSP协议获取图像(这对于学习网络协议非常有意义),蓝牙模块采用串口蓝牙,上位机给蓝牙发送数据,只需串口接收和处理即可 (5)循迹和超声波测距,循迹采用最简单的两路循迹原理,超声波采用市面上最常见的超声波模块,具体不做赘述。 2.软件实现 重点讲解软件实现原理,整套软件代码基于ucosii架构,采用多任务并行的方式实现,可以将上述硬件分成不同的软件模块进行实现。 (1)基础驱动模块 包括PWM驱动,GPIO,串口这些引脚功能配置,将引脚定义全部采用宏定义方式进行统一管理。更改引脚功能只需要修改宏即可,这种方案是单片机架构中最常用的一种引脚处理方式。 (2)多任务划分 将需要实时处理的模块划分成多个任务,目前设计了串口数据处理任务,超声波测距任务,红外循迹处理任务,按键检测任务,LED显示任务等多个并行任务,其中优先级最高的是串口数据处理任务; (3)串口数据处理 处理蓝牙发送的实时串口数据,从而执行对应得动作,由于蓝牙数据可能是持续得,我们不能接收一条处理一条,容易造成数据丢失和混乱,因此这里引入了队列得数据结构,将蓝牙数据保存在队列缓存中,通过中断数据接收存入队列,然后在串口数据处理任务中轮询读取队列和处理,保证数据准确和高效处理。 (4)手动控制自动控制实现 如何让不同得功能顺利切换是一套关键策略,本方案中默认采用手动控制模式,通过手机app操作进行小车前后左右控制和机械臂上下左右控制,然后通过app操作给小车下发自动控制指令进入自动控制模式。MCU接收到串口指令时,先保存当前小车控制状态,这里设计了一套小车控制状态得结构体数据,包括小车运动控制参数和状态控制参数,当状态控制参数处于手动控制模式时,小车响应app控制操作,当状态参数处于自动控制模式时,小车响应自动循迹,自动测距和自动抓取得动作,另外控制模式切换也兼容主板上得按键进行手动切换。 (5)自动循迹和自动抓取实现逻辑 自动循迹和自动抓取在同一任务中进行,使用超声波测距进行目标障碍物检测,若前方没有障碍物则正常循迹,若前方出现障碍物,距离达到可夹取范围时,循迹停止,并控制机械臂向下运动到指定位置,夹取目标后再放置到预定位置,放置完之后再继续循迹。从而实现了自动搬运障碍物得操作。 (6)视频图传和手机app控制 视频图传是基于ESP32-CAM实现,采用arduino编程,通过获取摄像头图像然后使用HTTP协议上传,手机端app开启会自动链接摄像头的ip地址从而获取到视频图像,目前使用VGA分辨率实时传输图像和显示可达到25fps,基本能做到实时显示,app配合蓝牙连接和下发指令可实现不同的功能控制。比如需要控制机械臂可以切换到机械臂控制模式,然后使用控制按钮进行控制。 功能应用场景: 1.视频图传和运动控制,以及手动搬运目标物体 2.自动循迹和自动控制搬运物体到指定位置 3.自动循迹和自动清理垃圾等

python虚拟机安装教程,虚拟机运行python文件

虚拟机下载python需要联网吗 虚拟机下载python需要联网,因为python的安装包是存储在python的官网上,必须要通过网络访问官网才能下载下载方法:访问python官网,点击download下面的python版本在跳转后的页面翻到最下面,选择第一个就行了更多Python知识,请关注:Python自学网! ! 谷歌人工智能写作项目:小发猫 虚拟机里怎么安装python的第三方模块 方法1:下载源码,手动运行 install去安装下载对应的源码,往往都是,.zip的压缩包,解压后,打开windows的cmd,切换到对应目录,运行: install即可去安装typescript 在vue3的使用。 方法2:利用第三方安装工具(如pip,easy_install,distribute等)去自动化安装利用的目前常见的一些自动化安装工具,比如pip,easy_install,distribute等,自动帮你下载源码,并安装。 而且很多时候,由于要安装的包,还要依赖一些其他的别的包,而这类自动化安装工具,会自动帮你解决依赖关系,自动帮你下载并安装所缺少的那些包,所以相对来说,就省去了你的麻烦了。 ubuntu怎么安装python3.6.2 主要讲解的时ubuntu系统下,安装python工具/原料ubuntu系统(当然也可以是虚拟机)python安装包方法/步骤python安装包的下载:profile在文件末尾加上你自己的路径PATH="$PATH:/自己的路径/Python-3.3.3"exportPATH例如:PATH="$PATH:/home/cloud/Music/Python-3.3.3"步骤阅读下面就算完成了。 在终端输入python就可以写python了。 如何在在虚拟机上搭建python环境 Python已经被移植在许多平台上(经过改动使它能够工作在不同平台上)。您需要下载适用于您使用平台的二进制代码,然后安装Python。 如果您平台的二进制代码是不可用的,你需要使用C编译器手动编译源代码。编译的源代码,功能上有更多的选择性, 为python安装提供了更多的灵活性。 python windows系统 源代码 一、python如何运行程序首先说一下python解释器,它是一种让其他程序运行起来的程序。 当你编写了一段python程序,python解释器将读取程序,并按照其中的命令执行,得出结果,实际上,解释器是代码与机器的计算机硬件之间的软件逻辑层。 通俗来说,我们的计算机是基于二进制进行运算的,无论你用什么语言来写程序,无论你的程序写的多么简单或多么复杂,最终交给计算机运行的一定是 0或1,因为计算机只能识别0和1。 我们目前使用的大多数编程语言都是高级程序语言,也就是利于我们人类阅读的语言,要使我们编写的程序能够在计算机上跑起来,要经过一定的转换才可以,python程序大致的过程应该是这样:源代码-->字节码-->pvm(虚拟机)-->机器码可以到Python的官方网站下载python(),通常包括解释器、库文件及简单的编码环境(IDLE)。 把源代码编译成字节码其实是为了程序更节省时间,如果源代码没有变动,那么运行程序时会直接从字节码读取,加快速度,把字节码放到虚拟机去解释,可以更好的跨平台运行,最后转换成机器码。 二、Windows系统下搭建python编程环境。1、进入Python官网,在“Downloads”下拉菜单中选择相应的操作系统,我们选择windows。 2、这里有32位和64位版本,要和自己的电脑系统相对应。 3、安装刚才已经下载下来的安装包, 安装过程下图所示,使用默认配置,选择“Install Now”,勾选下面的Add Python3.5 to PATH,然后就是一直next,直到完成。 三、认识编程环境1、在开始运行处运行命令cmd,进行dos模式,输入python,即可进行python的交互式环境。 2、进行到IDLE界面3、交互式界面可以用于简单的学习,编写较大程序时应到具体的python文件中,python文件默认的后缀为.py,我们可以新建文本文件,然后把后缀扩展名改为.py,然后最后选择菜单中的Run下的run module即可运行,快捷键为F5。 《Python源码剖析深度探索动态语言核心技术》pdf下载在线阅读,求百度网盘云资源 《Python源码剖析》(陈儒)电子书网盘下载免费在线阅读资源链接:链接: 提取码:4zk4书名:Python源码剖析作者:陈儒豆瓣评分:8.8出版社:电子工业出版社出版年份:2008-6页数:480内容简介:作为主流的动态语言,Python不仅简单易学、移植性好,而且拥有强大丰富的库的支持。 此外,Python强大的可扩展性,让开发人员既可以非常容易地利用C/C++编写Python的扩展模块,还能将Python嵌入到C/C++程序中,为自己的系统添加动态扩展和动态编程的能力。 .为了更好地利用Python语言,无论是使用Python语言本身,还是将Python与C/C++交互使用,深刻理解Python的运行原理都是非常重要的。 本书以CPython为研究对象,在C代码一级,深入细致地剖析了Python的实现。书中不仅包括了对大量Python内置对象的剖析,更将大量的篇幅用于对Python虚拟机及Python高级特性的剖析。 通过此书,读者能够透彻地理解Python中的一般表达式、控制结构、异常机制、类机制、多线程机制、模块的动态加载机制、内存管理机制等核心技术的运行原理,同时,本书所揭示的动态语言的核心技术对于理解其他动态语言,如 Javascript、Ruby等也有较大的参考价值。 ..本书适合于Python程序员、动态语言爱好者、C程序员阅读。 不能解锁vmware 方法1首先下载unlocker2.**后,解压缩压缩包,再在对应的文件上右键“以管理员身份运行”,正常情况下是会自动执行完成并自动关闭命令提示符窗口的。 出现问题的时候,一般会提示已停止响应,再次打开VMware workstation虚拟机软件发现Mac osx虚拟机选项还是没有出现。 下载个python for windows版本(双击安装,基本上不需要任何设置,默认下一步,中间需要手动确认下权限提升即可打开目录,找到,右键编辑找到倒数第七行echo Patching...修改为 上面语句,根据实际情况决定是否添加对应路径! 比如C:\Python27\ 保存编辑后的文件。再以管理员身份运行即可!之后再执行就不再报错了,而且新建虚拟机中也出现了Mac osx的虚拟机选项。 方法2目前unlocker2.0.5和2.0.6后修改为了按上面方法操作时,记得同步修改的文件名为即可方法3有些人喜欢关闭UAC,也会导致unlocker无法正常执行验证方法是打开控制面板——操作中心,更改用户帐户控制设置是否为最下面的从不通知,是的话,说明关闭了UAC这个时候就需要同步删除文件中关于权限判断的语句net session >NUL 2>&1if %errorlevel% neq 0 (echo Administrator privileges required!

vue3.0——监听属性、Vue3生命周期函数、Teleport、属性传值、自定义事件、状态驱动的动态 CSS、注册组件、异步组件、占位组件 Suspense

一、监听属性-watch 与vue2.x中的watch配置功能一致 注意 监视reactive定义的响应式数据时,oldvalue无法正确获取,强制开始了深度监视(deep的配置失效) 监视reactive定义的响应式数据的某一个值时:deep配置有效 1.监听ref定义的响应式数据 示例: <script setup> import { ref, reactive, watch } from "vue"; //监听一个数据 let msg = ref("今天星期二"); function changemsg() { msg.value = "Today is Tuesday"; } watch(msg, (newv, oldv) => { console.log(newv, oldv, "msg发生了变化"); }); </script> <template> <div> <p>{{msg}}</p> <button @click="changemsg">change-msg</button> </div> </template> 结果显示: 2.监听reactive定义的一个响应式数据的全部属性 示例: <script setup> import { reactive, watch } from "vue"; let user = reactive({name: "haha",age: 21,shopping: { cloth: 2, shooes: 1 }}); watch(user, function(newv, oldv) { console.

Android Widget

参考链接 https://blog.csdn.net/Jason_Lee155/article/details/124476447 原文代码有多处问题 且有些信息似乎没有提供 本篇文章只是做了些整理 本文除了一些图片没有提供 其他资料应该是比较齐全的,图片可以随意下载一些 AppWidget 即桌面小部件,也叫桌面控件,就是能直接显示在Android系统桌面上的小程序。图中用黄色箭头指示的即为AppWidget,一些用户使用比较频繁的程序,可以做成AppWidget,这样能方便地使用。典型的程序有时钟、天气、音乐播放器等。AppWidget 是Android 系统应用开发层面的一部分,有着特殊用途,使用得当的话,的确会为app 增色不少,它的工作原理是把一个进程的控件嵌入到别外一个进程的窗口里。需要说明的是,AppWidgetProvider本质是一个广播,即BroadcastReceiver,在实际的使用中,把AppWidgetProvider当成一个BroadcastReceiver即可。 手动创建AppWidget的步骤: 1. 为AppWidget提供一个xml文件,定义小控件的基本配置信息 在资源文件夹res目录下新建xml文件夹,假设名字为my_widget.xml,文件内容为: <?xml version="1.0" encoding="utf-8"?><!--小控件宽高 android:minWidth="40dp" android:minHeight="40dp" 更新时间 android:updatePeriodMillis="86400000" 用于指定预览图片。即搜索到widget时,查看到的图片。若没有设置的话,系统为指定一张默认图片。(多半是ic_launcher) android:previewImage="@drawable/widget_flashlight" widget 添加到手机主屏幕中的layout android:initialLayout="@layout/flash_light_widget" android:resizeMode : widget可以被拉伸的方向。horizontal表示可以水平拉伸,vertical表示可以竖直拉伸 android:resizeMode="horizontal|vertical"--> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialLayout="@layout/widget_layout" android:minWidth="100dp" android:minHeight="100dp" android:previewImage="@drawable/img" android:resizeMode="horizontal|vertical" android:updatePeriodMillis="86400000" /> 2. 创建一个MyAppWidgetProvider继承自AppWidgetProvider package com.example.testapp import android.app.PendingIntent import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetProvider import android.content.Context import android.content.Intent import android.util.Log import android.widget.RemoteViews const val TAG = "MyAppWidgetProvider" class MyAppWidgetProvider : AppWidgetProvider() { //每接收一次广播消息就调用一次,使用频繁 override fun onReceive(context: Context?

IDEA Git 复制分支到新分支 提交到新分支

目录 前言:在原有代码基础改出来另一个版本 该出的版本不能提交到当前分支,需要提交到新的分支 所以要新建个分支原来分支上的数据也要在 之前对git的操作不够熟练忙活一上午 才搞明白 下面记录一下怎么操作的! 解决 在原有代码基础改出来另一个版本 改出的版本不能提交到当前分支,需要提交到新的分支 所以要新建个分支原来分支上的数据也要在 之前对git的操作不够熟练忙活一上午 才搞明白 下面记录一下怎么操作的! 步骤 1.拉取原有分支最新代码 2.将自己已经改好的东西提交到git缓存区 操作步骤如图 (vcs)-->git-->Uncommitted Changes-->Stash Changes...创建缓存区(会将所以变更的代码提交至git缓存区) 3.新建新分支(会自动把当前分支的之前所有的提交都合并过去) 点击idea右下角分支名 new branch 输入分支名 创建新分支 创建后会自动切换到新建分支 创建后会自动切换到新建分支 (这个时候是没办法拉取代码的,因为新建的分支还没推到git仓库) 4.提交新分支到仓库 这就是分支创建成功了 5.从缓存区中提交到新分支 选择刚才创建的缓存区 点击Apply stash 就会把刚才放到缓存区的代码给还到变更取 6.正常提交代码即可 提交之后push一下 再去git仓库看下就行了 然后就好了新分支就好了 最后建议或提醒最重要的地方 在用工具对代码操作的时候一定要先备份打个压缩包才是最保险的, 在对项目管理工具使用不熟练的情况下,辛辛苦苦写的代码很容易切换分支就消失(可以找回 但是需要费点时间 可能还要麻烦别人) 所以一定要做好备份 做好备份 做好备份!!!

UmiJS基础+UmiUI安装使用+Mock使用示例+DvaJS案例

title: UmiJS基础 date: 2022-09-12 19:20:27 tags: React框架UmiJS categories:框架 UmiJS 介绍 官方文档 可扩展 Umi 实现了完整的生命周期,并使其插件化,Umi 内部功能也全由插件完成。此外还支持插件和插件集,以满足功能和垂直域的分层需求。 开箱即用 Umi 内置了路由、构建、部署、测试等,仅需一个依赖即可上手开发。并且还提供针对 React 的集成插件集,内涵丰富的功能,可满足日常 80% 的开发需求。 企业级 经蚂蚁内部 3000+ 项目以及阿里、优酷、网易、飞猪、口碑等公司项目的验证,值得信赖。 大量自研 包含微前端、组件打包、文档工具、请求库、hooks 库、数据流等,满足日常项目的周边需求。 完备路由 同时支持配置式路由和约定式路由,同时保持功能的完备性,比如动态路由、嵌套路由、权限路由等等。 面向未来 在满足需求的同时,我们也不会停止对新技术的探索。比如 modern mode、webpack@5、自动化 external、bundler less 等等。 快速上手 安装 创建空目录 kdir myapp && cd myapp 使用官方提供脚手架 yarn create @umijs/umi-app 安装依赖 yarn start 部署发布-----打包好的文件生成在dist文件下 yarn build 项目目录 - .editorconfig // 对编辑器的默认配置 - .gitignore // git忽略文件配置 - .prettierignore // 代码格式化忽略的文件 - .

基于梦飞openmv的自主识别物联网图传小车

前言 接上一篇<梦飞openmv py-AI机器视觉_自主开发openmv底层固件和硬件>,在自主开发的oepnmv硬件之后,时隔一年,我们终于在openmv自主开发的路上又进一步,这一次不仅仅是硬件上的推进,更是软件交互和用户体验上的提升。这次要给大家介绍的就是我们纯自主开发的openmv机器视觉自主识别和图传控制小车。 B站功能演示视频:https://b23.tv/phCGmPr 硬件介绍 它是基于梦飞自主开发的openmv硬件及各种扩展模块的综合应用,集成了openmv各种图像识别算法,小车PID控制,视频图传,视觉追踪,机械臂自动控制等在内的综合应用方案。以下将逐一介绍各部分组成结构和原理。 第一,自主集成openmv硬件,梦飞openmv硬件集成了更多的外设引脚,支持电机控制,(LCD显示)SPI-wifi图传,舵机机械臂控制引脚,串口等在内的多个外设,并开发了对应的集成模块。 (1)自主开发了用于对接openmv的电机驱动和电源一体化控制板,集成双LM2596电源芯片和RZ7889电机驱动芯片,具备对外5V3A的输出能力,以及6-15V宽电压输入能力,电机驱动和对外供电单独运行,RZ7889具备最大5A电机PWM输出控制能力,基本满足市面上所有智能小车得控制和运行。 (2)自主开发了基于ESP8266得SPI-wifi图传模块,具备实时视频传输能力(HTTP传输实时速度可达200KB/s,VGA传输10fps,QVGA可达20fps以上),可在图像识别完成后将视频传输到手机端实时显示,以及单独增加了用于控制小车和实时通讯得蓝牙模块,WiFi和蓝牙单独运行互不干扰。 (3)自主开发了三自由度机械臂模块,在原有追踪云台基础上增加机械爪,可拆卸和可安装openmv模块,实现自动识别和抓取的目的,可应用与自动分拣,搬运等领域,机械臂分两款,分别是普通塑料材质骨架和MG90S金属舵机安装,以及铝合金骨架和,G996金属舵机安装的机械臂。 (4)增加了手机app集成,可将单独的算法功能全部集成在openmv硬件上,通过手机app实时显示视频和切换不同的识别模式,基本识别模式包括循迹,物体颜色识别,人脸识别追踪等。也可通过手机app实时控制小车实现视频控制。 所有模块接口均直插在openmv硬件上,实现一体化集成,这是以往任何一款openmv硬件都无法直接完成的,并且所有模块都采用电子积木的方式集成,方便拆卸,更换,调试等各种操作,并且有任何损坏只需更换对应模块即可,省钱省力。 软件功能介绍 openmv软件开发上采用micro-python开发,各个模块集成到对应的功能函数,目前功能函数包括,串口协议处理模块(手机app蓝牙通讯),车辆控制模块(电机PWM驱动),测距模块(图像简单测距),图像传输模块(wifi图传),图像识别模块(颜色识别,人脸识别,循迹等),PID追踪模块以及机械臂控制模块等在内的众多模块化集成代码,可方便用户快速集成自己想要的功能。 目前基于我们开发的两款openmv模块,分别为stm32F407主控和stm32H7主控,两款模块的特点分别为: (1)F407主控的openmv模块,支持直接采集JPEG图像,搭配ov2640摄像头和wifi图传模块可直接实现JPEG图传采集和传输,另外,算法集成上自主集成了颜色识别,二维码识别,人脸识别(基于haar特征训练的机器学习算法,支持人脸,手,口罩,行人,眼,车辆等任意特征训练的模型,提供众多转换好的模型供使用),模板匹配(NCC模板匹配,可支持数字,形状等模式识别)。 (2)H7主控的openmv模块,除支持F407所涉及所有功能外,另外支持openmv4plus的所有算法,但是由于没有外部SDRAM一些大点的神经网络无法运行,但是我们自主集成了stm32-CUBE-AI,可使用lenet和mnist神经网络识别数字,也可以使用卷积神经网络识别人体特征等。

C++之动态数组(Vector)中运用各类迭代器

迭代器按照定义分类: 正向迭代器: 容器类名::iterator 迭代器名; 依次向下遍历 反向迭代器: 容器类名::reverse_iterator 迭代器名; 依次向上遍历 常量正向迭代器: 容器类名::const_iterator 迭代器名; 常量反向迭代器: 容器类名::const_reverse_iterator 迭代器名; ------------------------------------------------------------------------------------------------------------------------- 迭代器按照功能分类: 正向迭代器,支持相互赋值、比较、自加、取内容等 双向迭代器,具有正向迭代器全部功能,支持自减 随机访问寄存器,具有双向迭代器的全部功能 不同容器的迭代器的功能: 随机访问寄存器 vector、deque 双向寄存器 list、set /multiset、map /multimap 不支持迭代器寄存器 stack、queue、priority_queue C++迭代器(STL迭代器)iterator详解 (biancheng.net) v.end(): 指向向量最后一个元素之后的元素,一般用于正向迭代器 v.rend(): 指向向量第一个元素之前的元素,一般用于反向迭代器 v.begin(): 返回一个指向向量第一个元素的迭代器,用于正向输出动态数组中的元素 v.rbegin(): 返回一个指向向量最后一个元素的反向迭代器,用于逆向输出动态数组中的元素 v.front(): 引用容器的第一个元素 v.assign(first,last): 新值替换旧值,定义了范围,first与last之间被替代 v.assign(n,val): 给指定容器v分配了n次val值,从容器头开始替代 v.erase(pos): 删除迭代器指向pos位置的指定元素 v.erase(first,last): 删除容器first与last之间的内容 v.emplace(pos,val): 在容器的pos位置处插入一个新元素val v.capacity(): 返回容器大小 v1.crbegin(): 同rbegin(),只是适用于常量迭代器,不能被修改 v1.crend()、v1.cend()、v1.cbegin()类似 v.clear(): 清空容器 v.hypot(): 返回两个数的平方和的平方根 v.push_back(val): 在容器末尾插入val v.pop_back(): 删除容器末尾的元素 v.insert(pos,val): 在pos处插入元素val v.insert(pos,n,val): 在pos处连续插入n次元素val v.insert(pos,first,last): 在pos处连续插入first-last之间的内容,可用于容器拼接 v.

Swarm、Cryosat(-2)、CSES卫星磁场测量及数据下载

LEO卫星磁场测量 近地球卫星(LEO)操作轨道离地球表面大约100km-1000km,比传统通信卫星低很多。这使得卫星与地面基站能频繁的无线电接触。LEO广泛地用作民用、科技和军用,如地面观测、雷达、光学、电信和演习的飞机等。 电离层研究小组(Q:628234115) 包含相关电离层数据(电子密度、TEC等)

CSS样式的引用方式

想只用CSS修饰网页,就需要在HTML文档中引入CSS。CSS提供了4种引用方式,分别是行内式、内嵌式、外链式和导入式。. 1.行内式: 行内式也被称为内联式,可以通过style属性设置标签的样式。行内式基本语法格式如下: <标签名 style="属性1:属性值1; 属性2:属性值2; 属性3:属性值3;">内容</ 标签名> 在上述语法中,style是标签的属性,实际上任何HTML标签都拥有style属性,用于设置行内式。属性和属性值的书写规范与CSS样式规则一样。行内式CSS只对其所在的标签及嵌套在其中的子标签起作用。 通常CSS位于<head>头部标签中,但是行内式CSS位于<html>根标签中。例如,下面的示例代码即为行内式CSS样式的写法。 <h1 style="font-size: 20px; color: blue; ">使用行内式CSS修饰一级标题的字体大小和颜色</h1> 在上述代码中,使用<h1>标签的style属性设置行内式CSS样式,用于修饰一级标题的字体和颜色。行内式CSS展示效果如上图。 要注意一点,行内式是通过标签的属性来控制样式的,这样并没有做到结构与样式分离,所以不推荐使用。 2.内嵌式 内嵌式是将CSS代码集中写在HTML文档的<head>头部标签中,并用<style>标签定义,其基本语法格式如下: <head> <style type="text/css"> 选择器 {属性1:属性值1; 属性2:属性值2; 属性3:属性值3;} </style> </head> 在上述语法中,<style>标签一般位于<head>标签中的<title>标签之后,因为浏览器是从上到下解析代码的,为了便于CSS代码提前备加载和解析应把它放在头部,以避免网页内容加载后没有样式修饰的问题。在<style>标签中,只有设置type的属性值为“text/css”,浏览器才知道<style>标签包含的是CSS代码。 例如: <head> <meta charset="UTF-8"> <title>刘某人CSS内嵌式的练习网站</title> <style type="text/css"> /*定义标题标签居中对其*/ h2{ text-align: center;} /*定义div标签样式*/ div{ border: 1px solid #CCC; width: 300px; height: 80px; color: purple; text-align: center;} </style> </head> <body> <h2>内嵌式CSS样式</h2> <div> 使用style标签可定义内嵌式CSS样式表,style标签一般位于head头部标签中, title标签之后。 </div> </body> 结果如下: 在文件中,HTML文档头部使用<style>标签定义内嵌式CSS样式,第7行代码使用了标题标签<h2>设置标题,9、10行代码定义了<div>标签的样式。 内嵌式CSS只对其所在的HTML页面有效,所以仅设计一个网站时,内嵌式CSS是个好东西。但是!在设计网站的时候,不建议用。因为内嵌式不能充分发挥CSS代码的重用优势。 3.外链式: 外链式也叫链入式,是将所有的样式放在一个或多个以.css为扩展名的外部样式表文件中,通过<link>标签将外部样式表文件连接到HTML文件中。外链式CSS的基本语法格式如下:

ArcGIS基础:分级色彩和换行标注(VbCrLf)操作(以制作社会经济分析图为例)

我们需要用到的实验数据如下: 村(点数据和面数据),主要属性就是【人口数】、【经济总量】,如下图所示。 点数据的要使用的两个字段【人口数】、【经济总量】如下: 面数据的要使用的两个字段【人口数】、【经济总量】: 1、【行政区面要素的符号化】: 先在面数据上右键,打开属性,弹出【图层属性】,找到2处的【符号系统】,再找到3处的【数量】,再找到4处的【分级色彩】,再找到5处的【字段】下的【人口数】,再找到6处的【分类】,根据需要分成不同数量的类别; 再找到7处的【色带】,选择适合的颜色色带即可。 查看结果: 2、【社会经济要素符号化】: 点击1处的【符号系统】,找到2处的【图表】,找到3处的【条形图/柱状图】,再找到【字段选择】下的【经济总量】,再5处进行配色方案的设计和选择。 先点击1处的【属性】,再找到2处的【以3D方式显示】,再找到3处的【厚度】进行调整,再找到4处的【牵引线】,将其取消选择即可。 结果显示如下: 3、【社会经济要素的标注】 先找到1处的【标注】,再勾选2处的【标注此图层中的要素】,再找到3处的【表达式】,再在4处输入表达式。 表达式是组合起来的,其中【VbCrLf】表示换行的意思。 在1处打开【放置属性】,在2处的【同名标注】下选择【每个要素放置一个标注】。 结果显示如下: 当然如果不喜欢上面配色方案,可根据个人爱好进行设置:

Vue2+Element UI后台管理系统的实现过程

利用脚手架创建项目 使用vue2写项目,脚手架用对应3版本的脚手架,如果安装的脚手架版本过高会导致出现警告,识别不到相应的内容。 安装脚手架之后,使用”vue create 项目名“,建立本次项目,选择需要使用到的选项,显示如下界面,选择Manually selected features,手动选择功能,选中如下选项(空格是选中,Enter是确定,进行下一步): 下一步选择hash模式或者history模式(hash模式兼容性比较好,history看起来简洁一些),本项目选择的是history模式,所以打出Y,之后选择书写css的方式,选择Less(可以嵌套写样式): 再选择严格模式,选择最后一个严格模式,比较完善: 之后选择语法的检查模式,选择第一个保存之后就进行检查: 然后选择配置文件的储存位置,这里可以选择第二个: 最后是否保存本次选项做为未来创建项目的预设,因为每次项目需要的功能不尽相同,所以这里咱们输入n,使用npm run serve运行,显示如下界面: 项目初始化完成。 实现对组件的管理 先来理理头绪,咱们看到上面的界面是App.vue这个根组件所呈现出来的,所以后面所有的组件最终都需要挂载到App.vue上进行呈现,一个项目会涉及到很多组件,为了方便进行组件管理,便于进行页面效果观察,咱们使用vue-router进行组件管理,同时为了避免适配问题,咱们通过npm install vue-router@3.1.3安装相适配的版本。之后在src中建立专门的文件夹router,在该文件夹下新建进行路由管理的JS文件,所有组件路径都将在该JS文件里书写,JS文件中引入vue-router,添加到Vue的使用中,定义一个数组,将组件路径等相关信息封装成一个对象,再把对象放到数组中,最后将该数组导出,那么该文件部分完成了,添加组件就可以直接按模板进行操作了,很多语言都以main为语言的入口,vue也是,在main.js文件处对router进行引入,添加成实例化Vue的变量,建立与根组件App.vue的联系,在App.vue中id为app的盒子中写上router-view,就可以组件中的内容显示到界面里了,并且可以通过在导航输入框中进行路径跳转,这样便于页面的观察和调试。 完成界面 知道了如何便利的查看界面,下一步咱们就要开始写界面了,本次书写界面用到了Element ui组件库,咱们先安装,项目终端输入npm i element-ui -S对其进行安装,引入这个组件库的方式有两种,全局引入和局部引入,本次案例我用到的是全局引入,需要在main.js引入,添加到Vue对象的使用,同时设置大小和权重,设置完毕,可以去Element UI的官网查看所需组件的用法。 下面在components中新建common和page两个文件夹,其中common用来储存公用部分的组件,page用来储存非公用部分的页面组件,ELement UI组件库中有专门的布局组件,可以用来进行主页布局,一般分为顶部,主体,底部和侧边栏,本次案例就是这样的布局,侧边栏可以用组件库中的组件来实现,用该组件同时也解决了路径跳转的问题,将相关组件“:index”的值写成需要跳转的组件界面路径,点击之后即可进行跳转,下面按照需要写每个界面即可。 我在写的时候,有部分布局比较难实现,就采用浮动,定位等css属性,可能与组件库中的一些组件产生冲突,还有就是在style处一定要加上scope="scoped",否则组件元素内部选择器的名称相同,就会产生冲突,导致页面呈现的效果差强人意,提前构思自己各个部分组件的布局需要,以及组合到一块之后的布局情况,大布局与小布局同步思考,统筹兼顾,才能完备呈现出自己想要的效果。 发送请求获取数据 等页面写完了,部分内容需要通过网络请求从接口拿到数据进行布局渲染,这次的案例是通过Apifox对接口进行模拟,并获取所需数据,先安装axios,在案例终端输入npm install axios,通过axios发送网络请求,在src下新建api文件夹,再新建request.js文件,引入axios,根据模拟的接口,设置默认路径(每次发送请求都会自动添加到前面的路径),设置请求时间,再写请求拦截器和响应拦截器,需要在这两个拦截器哪部分进行操作,可以自行书写。再在api文件夹下新建index.js文件,引入request.js同时,将自己所需要写的请求暴露(导出)给外部,需要使用该请求的组件进行引入,并通过异步挂载的方式根据接口传递数据的格式拿到相应的数据,将数据渲染到界面。 非父子组件数据传递 如果需要非父子组件之间的值传递,在src下新建utils文件夹,新建bus.js文件,在文件中引入Vue,写变量bus为实例化的Vue对象,暴露(导出)bus,记传递数据的组件为A,接收数据的组件为B,在A,B中都引入bus.js,在A组件的方法中写 message就是传递走的数据,在B组件中写 变量e就接收到了传递过来的数据,可以对拿到的数据进行操作,要记得对用到的变量进行定义,如message。 等界面和数据渲染都完成之后,就可以思考一些更加具备逻辑性的功能实现了。更完整的案例内容和内部逻辑,后面会在用vue3书写案例的时候呈现出来。 思考总结 一个案例有很多小知识汇聚在一起,部分知识需要学会了才能用,还有部分知识用着用着就会了,多思考思考整块逻辑实现的过程,分部实现,逐步攻克,最终实现大的功能,多多实践,找到适合自己的方式。

springboot中配置文件的读取顺序

配置文件一般在springboot项目中有四个位置,优先级是config文件下更高,根目录下更高。图中的1234即为四个不同配置文件读取的顺序,相同配置一般以第一次读取的参数为准,后边的不做覆盖。另外启动命令中的参数配置优先级更高。 注: 另外如果相同目录下有application.properties则prop文件优先级更高。 参考播客:https://www.cnblogs.com/nizuimeiabc1/p/16616227.html

循环单链表解决约瑟夫问题

[问题描述] 约瑟夫(Joeph)问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。 1、利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。 2、m的初值为20;密码:3,1,7,2,4,8,4(正确的结果应为6,1,4,7,2,3,5)。 3、程序运行后首先要求用户指定初始报数上限值,然后读取各人的密码。设n≤30。 我们采用不带头结点的尾插法建立单链表。 第一:如果我们用头插法,链表的中数据是逆序的,不利于操作。 第二:如果采用带头结点的单链表,每次遍历的时候,头结点不方便处理。 代码 #include<stdio.h> #include<malloc.h> typedef int ElemType; typedef struct LNode { ElemType data; struct LNode* next; }LinkNode; // 尾插法建立不带头结点循环单链表{1,2,3,4,5,6,7} LinkNode* Create(int n) { LinkNode* Q = NULL, * s; int i; Q = (LinkNode*)malloc(sizeof(LinkNode)); Q->data = 1;//给首节点赋初值 Q->next = Q;//将指针指向自己 for (i = 2; i <= n; i++) {// 从第二个节点开始创建节点并赋值 s = (LinkNode*)malloc(sizeof(LinkNode)); s->data = i; s->next = Q->next; Q->next = s; Q = s;// 指针指向最后一个节点 } return Q;// 将指针返回,以便后续调用 } void Joeph(LinkNode* Q, int m) { LinkNode* pre = Q; LinkNode* p = Q->next;//将指针指向首节点 int count = 1;// 计数器 int arr[] = { 0, 3, 1, 7, 2, 4, 8, 4 };//将密码全部存放在一个数组中 printf("

1、EC气象数据批量下载

EC气象数据批量下载 前言一、前期准备1. 配置Python环境2. 安装依赖库:3. 注册EC账户并获得Key3.1 注册账户3.2 获取API信息 4. 选择数据 二、编写脚本开始下载数据 前言 本文主要介绍如何使用Python批量下载EC(ECMWF)气象数据,所有代码均已Fork到ModelWhale平台上,修改相关参数后可一键跑通,欢迎阅读并订阅。 一、前期准备 1. 配置Python环境 建议使用Anaconda安装并配置Python环境,具体过程可参考:Anaconda安装并配置Python环境。如果已经安装好python环境,此步骤可以忽略。 2. 安装依赖库: pip install ecmwf-api-client 若安装失败,可尝试如下命令: conda install -c conda-forge ecmwf-api-client 3. 注册EC账户并获得Key 3.1 注册账户 打开官网https://www.ecmwf.int并点击右上角Log in进行账号注册后进行登陆操作。 结果如下图所示: 3.2 获取API信息 登陆成功后点击此链接获取账户API key等信息https://api.ecmwf.int/v1/key/ 效果如下图所示: 4. 选择数据 注意选择完需要的数据后,请点击Request API选项生成脚本。 二、编写脚本开始下载数据 from ecmwfapi import ECMWFDataServer server = ECMWFDataServer() server.retrieve({ "class": "ei", "dataset": "interim", "date": "19970101/19970201/19970301/19970401/19970501/19970601/19970701", #修改date数值实现多时次下载 "expver": "1", "grid": "1.0/1.0", "levelist": "200/500/700/850/1000", #修改levelist数值实现多层次下载 "levtype": "pl", "param": "

自动化之RPA工具之影刀

一、简介 名称:影刀类型:软件官网地址(工具使用地址/下载地址):https://www.winrobot360.com/tg/简要说明:「影刀RPA」可类比于工厂流水线上的物理机器人 二、解决的问题 通过自动在任何应用程式上进行鼠标点击、键盘输入、读取信息等操作,帮助解决白领的非主观决策工作,减少重复劳动。产品上线一年期间,30万+用户选择影刀RPA来搭建自动化流程,其中一半以上为业务人员。产品上线一年期间,1万+家企业使用,覆盖电商、金融、物流、医疗、 通迅等各领域,满意度近100%。影刀深度服务于那些坚信数字化是未来核心竞争力的企业。9倍生产力提升,工作100%准确,7*24全天侯待命。开启影刀RPA之旅,解放你的双手。 三、使用说明/实操使用案例 3.1 爬虫 3条命令实现批量数据抓取 命令含义 第一步:打开网址 提前用谷歌浏览器打开数据抓取的网址 第二步:数据提取 加分功能1:抓取多页,需获取元素 加分功能2:网页加载时间过长,可以调整“翻页间隔的时长”;网页有弹框类信息遮挡翻页按钮,可以取消模拟人工点击翻页按钮选项,通过底层代码去点击。 第三步:数据存到excel保留到本地 1、输出数据结果 2、保存的excel 3.2 巡检自动化 3.2.1 网页应用 五条命令实现:打开网页→截图→接口推送到企业微信 详情如下: 其中,机器人地址是企业微信自带的机器人webhook 3.2.2 获取自动更新文件 需求:程序定时生成excel和png,需要通过接口推送至手机进行定时巡检 两条命令实现: 详解如下: 四、缺点和不足 1、后期部分功能会收费,无法破译代码 2、环境库非开源 import xbot import xbot_visual from . import package from .package import variables as glv import time def main(args): try: web_page = xbot_visual.web.create(web_type="cef", value="https://uland.taobao.com/sem/tbsearch?refpid=mm_26632258_3504122_32538762&keyword=%E7%AC%94%E8%AE%B0%E6%9C%AC%E7%94%B5%E8%84%91&clk1=08d140917a02706d0af264930b2a9309&upsId=08d140917a02706d0af264930b2a9309&spm=a2e0b.20350158.search.1&pid=mm_26632258_3504122_32538762&union_lens=recoveryid%3A201_33.54.87.175_4881315_1660392167968%3Bprepvid%3A201_33.54.87.175_4881315_1660392167968", wait_load_completed=True, load_timeout="20", stop_load_if_load_timeout="handleExcept", chrome_file_name=None, edge_file_name=None, ie_file_name=None, bro360_file_name=None, firefox_file_name=None, arguments=None, _block=("main", 1, "打开网页")) for _xbot_retry_time in range(4): try: web_page2 = xbot_visual.

DRM驱动(六)之atomic_check

上节聊到应用传下来的参数均被存到对应的state。为了使驱动的容错能力比较强,在更新到硬件寄存器之前还需要进行一系列的参数检查,比如要显示图像的大小是否会超过支持分辨率,如果超过了显示的硬件可能会异常;再比如应用需要硬件进行缩放图像但是硬件不支持,强制配置到硬件上面即使不出错也肯定达不到预期的效果,等等场景,一起看下drm驱动中是如何进行处理的。 驱动错误检查的入口为drm_atomic_check_only int drm_atomic_check_only(struct drm_atomic_state *state) { struct drm_device *dev = state->dev; struct drm_mode_config *config = &dev->mode_config; struct drm_plane *plane; struct drm_plane_state *plane_state; struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; for_each_plane_in_state(state, plane, plane_state, i) { ret = drm_atomic_plane_check(plane, plane_state); if (ret) { return ret; } } for_each_crtc_in_state(state, crtc, crtc_state, i) { ret = drm_atomic_crtc_check(crtc, crtc_state); if (ret) { return ret; } } if (config->funcs->atomic_check) ret = config->funcs->atomic_check(state->dev, state); if (!state->allow_modeset) { for_each_crtc_in_state(state, crtc, crtc_state, i) { if (crtc_state->mode_changed || crtc_state->active_changed) { return -EINVAL; } } } return ret; } 这里主要调用了三个函数

Shell 脚本常用语法总结

计算机中 Shell 术语最早是在 1964 年 Multics 操作系统中定义的,作用是提供人机交互的操作界面,它会解释执行用户输入命令并输出结果。对 Shell 通常的理解是 类Unix系统 上的命令行和批处理程序,可以看作是早期操作系统的桌面,像如今的图形化界面(文件资源管理器、任务管理器、控制面板)一样,可以操作文件、查看进程、配置系统、管理硬件等功能。图形化界面虽然能更直观的使用计算机,但无法使用没有界面的程序,且没有Shell脚本灵活的编程复用能力。Shell 通常基于内核API实现,演变出了很多版本,下列介绍目前最常用的版本: 首版名称开发者历史1971年Thompson shell(sh)Ken Thompson为 Unix V1 开发,简化了早期的 Multics shell,新增了如 输入(<),输出(>) 等特性1977年Bourne shell(sh)Stephen Bourne为 Unix V7 开发,给脚本添加了变量、循环等特性,是当今 shell 的基础,衍生了 csh/ksh/zsh/bash 等1989年Bourne-Again Shell(Bash)Brian Fox为 GNU计划 开发的免费软件,功能上是 Bourne shell 的超集,名字源自 born again 双关语,被 Linux、macOS 系统很多版本广泛使用1990年Z shell(Zsh)Paul Falstad是 csh 的子集,包含了 bash/ksh 部分特性,有热度很高的 Oh My Zsh 插件和社区,并从 2019年 起作为 macOS 默认 shell Shell 本身是指一种应用程序,现在通常也指 Shell 脚本(shell script)。这篇文章主要介绍 Shell 脚本的语法,由于不同版本会有差异,本文采用的案例以覆盖最广泛的 Bash 为准,测试环境为 macOS 中的 Terminal。