OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4378|回复: 16

Note nOte noTe notE 笔记 笔记 笔记 笔记

[复制链接]

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
发表于 2019-10-19 17:47:02 | 显示全部楼层 |阅读模式
Linux的设备文件大体上分为三种基本类型:字符设备、块设备和网络设备。
字符设备:能够按照字节流(类似文件)一样顺序访问的设备,由字符驱动程序实现此种特性。最典型的就是字符终端(/dev/console)和串口设备(/dev/tty*)了。与嵌入式有关的许多外设(I2C/SPI/UART等)都可以归入此类别。
块设备:一次传送512或者2的倍数字节。虽然从系统调用角度看它和字符设备是类似的,但在内核实现中的内部数据管理和实现则完全不同。这里最典型的就是磁盘设备。
网络设备:任何网络通信都通过网络接口,形成一个能够与其他外界交换数据的设备。由于网络底层往往围绕数据分组展开,而TCP/IP协议却是面向流/数据报的方式,因此与字符设备不同。在UNIX/Linux中往往使用单独的名称进行访问(eth0)。但这个名字在文件中不存在对应节点,内核调用的是网络通信函数而非read/write函数。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

1127

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1656
金钱
1656
注册时间
2019-8-15
在线时间
102 小时
发表于 2019-10-19 22:26:31 | 显示全部楼层
回复 支持 反对

使用道具 举报

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
 楼主| 发表于 2019-10-21 11:24:12 | 显示全部楼层
计算机系统中常见的各类并行接口,包括ECP/EPP、硬盘IDE/PATA、扩展卡用的ISA、PCI、AGP、CF等。这些并行接口的目的如下:
提供较高的数据吞吐速率
提供海量存储
提供网络通信
提供数据采集等专用目的扩展
实现与其他接口的桥接
回复 支持 反对

使用道具 举报

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
 楼主| 发表于 2019-10-21 15:12:00 | 显示全部楼层
在老式PC中,并行接口(简称并口)速率比RS232要快,当时用于与打印机和其他“高速”数据采集设备通信。并行接口有三个标准。
标准并行接口:SPP(Standard Parallel Port),支持4/8半8位传输,4位速率可达40KB/s~48KB/s,8位速率位80KB/s~150KB/s,即320kbps~1.2Mbps。
增强并行接口:EPP(Enhanced Parallel Port),速率为300KB/s,即2.4Mbps。
扩展兼容并行接口:ECP(Extended Capabilities Port),支持DMA传输,速率同EPP。
PC并行接口曾经是大量仪器仪表,如数据采集卡、通用编程器的标准通信接口,现在均被USB总线替代了。
回复 支持 反对

使用道具 举报

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
 楼主| 发表于 2019-10-21 15:22:18 | 显示全部楼层
在计算机主板上,各类并行接口如ISA、PCI、PCIe、AGP、ATA等总线演进得非常快,出现了高速串行化的发展趋势:减少引脚数量,采用高速差分对传输。这样做的目的是减少并行总线的EMI/EMC问题,同时提高速率。典型案例如下:从IDE/PATA到SATA/mSATA,从ISA/AGP/PCIe到Mini PCI-E,采用LPC、SMBus、PMBus控制外设等。
嵌入式系统的演变虽然没有那么快,但是紧随着PC行业进行着技术平移,不仅普及了USB,还增加了Mini PCI-E/SDIO等总线的支持。但处于直接外设控制的考量,GPIO口依然大量使用。GPIO以及对应的PWM/ADC功能都是以8/16/32位宽度端口存在的,我们可以将其归类在并行接口。
回复 支持 反对

使用道具 举报

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
 楼主| 发表于 2019-10-22 14:17:59 | 显示全部楼层
I2C是一种可以多芯片并联的中等速率串行总线。I2C总线利用SDA/SCL两根线,可以让嵌入式控制器同时对多个元器件进行控制。I2C总线采用了开漏电路,所以在SDA/SCL中可以并联多个IC,节省了电路板空间,更加重要的是节省了MCU的引脚。其速率在100kbps/400kbps/3.4Mbps左右。其推出后,很快成为半导体行业的行业标准,尤其在传感器、存储器方面非常流行。
回复 支持 反对

使用道具 举报

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
 楼主| 发表于 2019-10-22 15:21:10 | 显示全部楼层
Inter在I2C基础上,定义了SMBus(System Management Bus)用于系统管理的总线。不能够简单地说SMBus就是I2C,但两者间的确存在继承关系。SMBus上增加了超时管理和数据传输格式标准,但没有定义传输数据内容。具体如下:
数据包错误检测(PEC,Packet Error Checking)
传输超时
标准化传输类型
ALERT报警线
SUSPEND挂起线
电源开关
最大速率位100kHz/s
由于SMBus和I2C的关系,因此Python的I2C包的名称是python-smbus
在SMBus基础上,产生了PMBus(Power Management Bus)。该标准定义了电源控制管理所需的命令和数据结构,以满足控制智能电池组的需求。SMBus和PMBus都是SMIF的注册商标。
回复 支持 反对

使用道具 举报

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
 楼主| 发表于 2019-10-24 09:48:37 | 显示全部楼层
本帖最后由 sagiri 于 2019-10-24 15:11 编辑

__________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

app.config支持多种更新配置的方式。假设现在有个叫作settings.py的配置文件,其中的内容如下:
A = 1
可以选择如下三种方式加载。
1.通过配置文件加载。
app.config.from_object('settings')  #通过字符串的模块名字
#或者引用之后直接传入模块对象
import settings
app.config.from_object(settings)
2.通过文件名字加载。直接传入文件名字,但是不限于只使用.py后缀的文件名。
app.config.from_pyfile('settings.py',silent=True)#默认当配置文件不存在时会抛出异常,使用silent=Ture的时候只是返回False,但不会抛出异常
3.通过环境变量加载。这种方式依然支持silent参数,获得路径后其实还是使用from_pyfile的方式加载。
> export YOURAPPLICATION_SETTINGS='settings.py'
app.config.from_envvar('YOURAPPLICATION_SETTINGS')
回复 支持 反对

使用道具 举报

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
 楼主| 发表于 2019-10-24 10:36:05 | 显示全部楼层
虽然app.run这样的方式适用于启动本地的开发服务器,但是每次修改代码后都要手动重启的话,既不方便也不够优雅。如果启用了调试模式,服务器会在代码修改后自动重新载入,并在发生错误时提供一个能获得错误上下文及可执行代码的调试页面。
有两种途径来启用调试模式。
1.直接在应用对象上设置
app.debug=True
app.run()
2.作为run的参数传入
app.run(debug=True)
需要注意,开启调试模式会成为一个巨大的安全隐患,因此它绝对不能用于生产环境中。
回复 支持 反对

使用道具 举报

6

主题

1127

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1656
金钱
1656
注册时间
2019-8-15
在线时间
102 小时
发表于 2019-10-24 10:45:30 | 显示全部楼层
顶一下
回复 支持 反对

使用道具 举报

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
 楼主| 发表于 2019-10-24 11:45:14 | 显示全部楼层
@app.route('/item/<id>/')
def item(id):
        return 'Item: {}'.format(id)
尖括号中的内容是动态的,凡是匹配到/item/前缀的URL都会被映射到这个路由上,在内部把id作为参数而获得。
它使用了特殊的字段标记<variable_name>,默认类型是字符串。如果需要指定参数类型需要标记成<converter:variable_name>这样的格式,converter有下面几种。
string:接受任何没有斜杠"/"的文本(默认)。
int:接受整数。
float:同int,但是接受浮点数。
path:和默认的相似,但也接受斜杠。
uuid:只接受uuid字符串。
any:可以指定多种路径,但是需要传入参数。
回复 支持 反对

使用道具 举报

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
 楼主| 发表于 2019-10-24 16:24:35 | 显示全部楼层
要想明白"@app.route()"的工作原理,我们首先需要看一看Python中的装饰器(就是以"@"开头的那玩意,下面接着函数定义)。究竟什么是装饰器?没啥特别的。装饰器只是一种接受函数(就是那个你用"@"符号装饰的函数)的函数,并返回一个新的函数。当你装饰一个函数,意味着你告诉Python调用的是那个有你的装饰器返回的新函数,而不仅仅是直接返回原函数体的执行结果。还不是很明白?这里是一个简单的例子:
def simple_decorator(f):
        def wrapper():
                print "Entering Function"
                f()
                print "Exited Function"
        return wrapper
@simple_decorator
def hello():
        print "Hello World"
hello()
运行上述代码会输出以下结果:
Entering Function
Hello World
Exited Function
很好!现在我们有点明白怎样创建我们自己的"@app.route()"装饰器了,但你可能会注意到有一个不同点,就是我们的simple_decorator不可以接受任何参数,但"@app.route()"却可以。
那么我们怎样才能给我们的装饰器传参数?要实现这个我们只需创建一个"decorator_factory"函数,我们调用这个函数,返回适用于我们函数的装饰器。现在看看如何实现它。
def decorator_factory(enter_message,exit_message):
        def simple_decorator(f):
                def wrapper():
                        print enter_message
                        f()
                        print exit_message
                return wrapper
        return simple_decorator
@decorator_factory("Start","End")
def hello():
        print "Hello World"
hello()
给我们的输出是:
Start
Hello World
End
请注意在我们写@decorator_factory("Start","End")时,我们实际调用的是decorator_factory函数,实际返回的装饰器已经被用上了,代码很简洁,对吧?

现在我们掌握了装饰器怎样工作的全部前置知识,可以重新实现Flask API的这个部分了,那么把我们的目光转移到"app"在我们Flask应用中的重要地位上面来。
在开始解释Flask对象里面发生了什么之前,我们先创建我们自己的Python类NotFlask。
class NotFlask():
        pass
app=NotFlask()
这不是一个很有趣的类,不过有一样值得注意,就是这个类的方法也可以被用作装饰器,所以让我们把这个类写得更有趣一点,加一个称作route的方法,它是一个简单的装饰器工厂。
class NotFlask():
        def route(self,route_str):
                def decorator(f):
                        return f
                return decorator
app=NotFlask()
@app.route("/")
def hello():
        return "Hello World!"
这个装饰器和我们之前创建的那些最大的不同,在于我们不想修改被我们装饰的函数的行为,我们只是想获得它的引用。
所以,最后一步是我们打算去利用一个特性,就是用装饰器函数的副产品去保存一个提供给我们的路径之间的链接,装饰器函数应该与它关联起来。
为了实现这个,我们给我们的NotFlask对象加一个"routes"字典,当我们的"decorator"函数被调用,路径将被插入新字典中函数对应的位置。
class NotFlask():
        def __init__(self):
                self.routes={}
        def route(self,route_str):
                def decorator(f):
                        self.routes[route_str]=f
                        return f
                return decorator
app=NotFlask()
@app.route("/")
def hello():
        return "Hello World!"
现在我们就要完成了!可如果没法访问内部的视图函数,保存路径的字典又有什么用?让我们加入一个方法serve(path),当给定的路径存在时运行一个函数并给我们结果,当路径尚未注册时则抛出一个异常。
class NotFlask():
        def __init__(self):
                self.routes={}
        def route(self,route_str):
                def decorator(f):
                        self.routes[route_str]=f
                        return f
                return decorator
        def serve(self,path):
                view_function=self.routes.get(path)
                if view_function:
                        return view_function()
                else:
                        raise ValueError('Route"{}"has not been registered'.format(path))
app=NotFlask()
@app.route("/")
def hello():
        return "Hello World!"
回复 支持 反对

使用道具 举报

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
 楼主| 发表于 2019-10-24 16:34:16 | 显示全部楼层
HTTP有多个访问URL方法,默认情况下,路由只回应GET请求,但是通过app.route装饰器传递methods参数可以改变这个行为:
@qpp.route('/login',methods=['GET','POSE'])
@app.route('/j/item/<id>',methods=['DELETE','POST'])
如果存在GET,那么也会自动地添加HEAD方法,无须干预。它会确保遵照HTTP RFC(描述HTTP协议的文档)处理HEAD请求,所以你完全可以忽略这部分的HTTP规范。从Flask0.6起,它也实现了OPTIONS的自动处理。
下面简要介绍HTTP方法和使用场景。
GET:获取资源,GET操作应该是幂等的。
HEAD:想要获取信息,但是只关心消息头。应用应该像处理GET请求一样来处理它,但是不返回实际内容。
POST:创建一个新的资源。
PUT:完整地替换资源或者创建资源。PUT操作虽然有副作用,但应该是幂等的。
OPTIONS:获取资源支持的所有HTTP方法。
PATCH:局部更新,修改某个已有的资源。

幂等表示在相同的数据和参数下,执行一次或者多次产生的效果是一样的。
回复 支持 反对

使用道具 举报

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
 楼主| 发表于 2019-10-24 16:50:49 | 显示全部楼层
跳转(状态码301)多用于旧网址在废弃前转向新网址以保证用户的访问,有页面被永久性移走的概念。重定向(状态码302)表示页面是暂时性地转移。但是也不建议经常性使用重定向。在Flask中它们都是通过flask.redirect实现的:
redirect(location)  #默认是302
redirect(location,code=301)  #通过code参数可以指定状态码
Flask还支持303、305、307重定向,但是较少被用到。
回复 支持 反对

使用道具 举报

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
 楼主| 发表于 2019-10-25 15:15:48 | 显示全部楼层
Python程序可以调用一组基本的函数(即内建函数),比如print()、input()和len()等函数。Python本身也内置一组模块(即标准库)。每个模块都是一个Python程序,且包含了一组相关的函数,可以嵌入到你的程序之中,比如,math模块包含了数学运算相关的函数,random模块包含随机数相关的函数,等等。
一、import语句
在开始使用一个模块中的函数之前,必须用import语句导入该模块。
语法:import module1[,module2[,...moduleN]]
实例:
1、使用random模块ranint()函数:
# printRandom.py
import random
for i in range(5)
    print(random.randint(1,10))
# result:
说明:因randint()函数属于random模块,必须在函数名称之前先加上random,告诉Python在random模块中寻找这个函数。
2、导入多个模块:
import math, sys, random, os
二、from import语句
这是导入模块的另一种形式,使用这种形式的import语句,调用模块中的函数时不需要moduleName.前缀。但是,使用完整的名称会让代码更可读,所以最好是使用普通形式的import语句。
语法:from moduleName import name1[,name2[,...nameN]]|*
实例:
导入random模块下的所有函数:
from random import *
for i in range(5):
    print(randint(1,10))  #这里就不需要random.前缀了
导入random模块下的randint,random函数:
from random import randint, random
回复 支持 反对

使用道具 举报

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
 楼主| 发表于 2019-10-25 15:16:32 | 显示全部楼层
abs(x)
Return the absolute(绝对值) value of a number.The argument may be an integer or a floating point number.If the argument is a complex number,its magnitude is returned.If x defines __abs__(),abs(x) return x.__abs__().

all(iterable)
如果iterable的所有元素为真(或迭代器为空),返回True。等价于:
def all(iterable):
    for element in iterable:
        if not element:
            return False
    return True

any(iterable)
如果iterable的任一元素为真则返回True。如果迭代器为空,返回False。等价于:
def any(iterable)
    for element in iterable:
        if element:
            return True
    return False

ascii(object)
就像函数repr(),返回一个对象可打印的字符串,但是repr()返回的字符串中非ASCII编码的字符,会使用\x , \u 和 \U来转义。生成的字符串和Python2的repr()返回的结果相似。

bin(x)
将一个整数转变为一个前缀为"0b"的二进制字符串。结果是一个合法的Python表达式。如果x不是Python的int对象,那它需要定义__index__()方法返回一个整数。一些例子:
>>> bin(3)
'0b11'
>>> bin(-10)
'-0b1010'
如果不一定需要前缀"0b",还可以使用如下的方法。
>>> format(14,'#b'),format(14,'b')
('0b1110','1110')
>>> f'{14:#b}',f'{14:b}'
('0b1110','1110')
另加format()获取更多信息。

class bool([x])
返回一个布尔值,True或者False。x使用标准的真值测试过程来转换。如果x是假的或者被省略,返回False;其他情况返回True。bool类是int的子类(参见数字类型--int,float,complex)。其他类不能继承自它。它只有False和True两个实例(参见布尔值)。
在3.7版更改:x现在只能作为位置参数。
回复 支持 反对

使用道具 举报

8

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-6-18
在线时间
25 小时
 楼主| 发表于 2019-10-25 15:50:19 | 显示全部楼层
操作系统接口
os模块提供了许多与操作系统交互的函数:
>>> import os
>>> os.getcwd()    # Return the current working directory
'C:\\Python38'
>>> os.chdir('/server/accesslogs')    # Change current working directory
>>> os.system('mkdir today')    #Run the command mkdir in the system shell
0
一定要使用import os而不是from os import *。这将避免内建的open()函数被os.open()隐式替换掉,它们的使用方式大不相同。
内置的dir()和help()函数可用作交互式辅助工具,用于处理大型模块,如os:
>>> import os
>>> dir(os)
<returns a list of all module functions>
>>> help(os)
<returns an extensive manual page created from the module's docstrings>
对于日常文件和目录管理任务,shutil模块提供了更易于使用的更高级别的接口:
>>> import shutil
>>> shutil.copyfile('data.db','archive.db')
'archive.db'
>>> shutil.move('/build/executables','installdir')
'installdir'
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 17:28

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表