应用基础笔记

1 、uart

        通信模式:串行异步全双工

        波特率:每秒钟传输的bit数

        传输距离

        TTL电平:0.5m以内采用(短距离,因为一般是5v左右表示高电平,所以不适合长距离)

        RS232:0.5m~15m(最大30m左右,有的也说50m,根据具体情况吧),3v-12v表示高电平1,速率一般为20kbps

        RS485:速率可达10Mbps,标准情况最大距离1200m,最大也可达3km。

        数据格式:最开始电平拉低,维持一段时间,表示起始位,要开始发送数据。然后发送一个字节数据,发送完之后发校验位,再发送停止位,停止位可以是1位或者1.5位等,要继续发送数据就循环这个过程。 

                                                发送的数据

起始位00000000校验位停止位

        内部实现:数据线发送到fifo队列里,发送的时候从队列取数据,通过移位寄存器发出去。接收数据时,数据放到fifo队列,再通过移位寄存器取数据。

        如何知道有数据? : 可以通过轮询或者中断实现。

2、串口编程实验

        tty:终端,分为虚拟终端和真实终端,真实终端比如硬件设备,串口也是一个终端,控制台就是一个虚拟终端。如果不想区分是不是虚拟终端,可以用tty代表当前终端。        

        在此引入了  行规程  ,他会对数据进行处理。

        在终端,键盘输入一个字符时,会发送到串口驱动程序,驱动程序发给行规程,行规程发现只是一个普通的字符,就回环,把数据发送给驱动程序,驱动程序再发给pc终端显示。

        当输入回车或者删除键时,行规程判断是特殊的字符,比如回车就会把数据发送给app程序,程序就开始运行。它里面有一个buffer,存放输入的数据,如果是删除,他就会把输入的字符删掉,然后把buff的数据发给驱动程序。

3、iic中的重要结构体

        APP 通过 I2C Controller 与 I2C Device 传输数据。一个芯片里可能有多个 I2C Controller,
对于使用者,只要确定是第几个 I2C Controller 即可。

        i2c_client:里面存储设备地址,还有adapter结构体指针。

       i2c_adapter:表示是第几个I2C Controller,其中有i2c_algorithm结构体

        i2c_algorithm,其中有i2c的msg结构体,这个msg结构体表示传输的i2c数据的信息,包含设备地址,数据,读或写,长度等信息。

4、编写驱动程序

        当我们open,write文件时,内核会去进行系统调用,调用内核的open,write。

        当我们open,write设备时,内核会去调用对应驱动程序的open,write。

        所以我们去写驱动程序时,要提供open,write等函数。

     流程:

        写驱动程序时,提供设备号,file_operation结构体,里面包含驱动程序的open等函数,要把它告诉内核,所以要注册驱动程序。

        如何注册呢?需要提供入口函数,安装时会去调用它

        想卸载驱动怎么办呢?所以需要提供出口函数。

        open,write时,系统会根据设备号打开对应的驱动程序。然后再进行相应的调用。

        驱动程序如何访问硬件呢?需要将寄存器地址映射为虚拟地址,通过这个虚拟地址来进行访问。

5、GPIO

        高速模式和低速怎么选择呢?

        当我们使用高速模式时,速率快,但波形也会更抖,对其他外设的干扰就比较大,当我们想去做电磁兼容测试时,可能就通不过,所以高速和低速要去根据我们的外界设备来进行选择

6、为什么要将物理地址映射为虚拟地址,比如ioremap

        程序运行时,它的物理地址是通过pid来进行分配的,cpu看到的地址是MMU映射后的虚拟地址。

        而且写代码的人水平有高有低,不能让一窍不通的人直接去访问硬件

        地址的映射是由MMU完成的,

        mmu有两个作用:地址映射和权限保护(cpu发出的地址要结果mmu的审核才能访问硬件,cpu能不能访问硬件由mmu决定)

7、app读取按键操作

        1、查询

        2、休眠-唤醒

        3、poll方式(定时)

        4、异步通知方式

8、中断、异常

        中断不能嵌套,中断处理要越快越好

        中断控制器可以告诉cpu有需要处理的事情

        中断属于一种异常,异常(比如指令错误,数据访问有问题)是不可屏蔽的

        中断设置:设置中断源,使能中断

        cpu每执行完一条指令,都会检测有无中断产生,这是由硬件决定的

处理流程:

        对于不同的异常,cpu跳转到不同的地址(这些只是跳转指令,这些地址一般排在一块,称为异常向量),然后执行不同的处理程序,

        比如发生中断异常,就会跳到中断处理的代码,这些代码会执行:保存现场、处理中断(分辨中断源,调用对应的处理函数)、恢复现场这几个过程。

如何保存现场呢?

        例子:在执行a=a+b时,cpu会分别从寄存器里读取a和b的值,放入cpu里的寄存器,进行加法操作后数据保存到a寄存器中。

        如果此时发生中断,其他程序也要用到这些寄存器,那不就是乱套了?

        所以会把寄存器相应的值保存到栈中,恢复现场时,根据这个栈去恢复相应寄存器的值即可。

        函数A里面运行函数B的话,A的值就会保存到B的栈中,B才再去执行自己的程序。

        (注:虽然进程里的资源线程是共享的,但是线程也有自己的栈)     

中断处理的改进 

        如果某个中断很耗时怎么办呢?我们可以把中断分为上半部和下半部,上半部执行重要的处理,把耗时的放到下半部去执行。 也就是硬件中断(不可被打断)和软件中断

           在中断处理时,preempt_count会++,上半部会关中断,这时候不可被打断,当上半部执行完,  count--,然后开中断,此时才会被打断。如果此时被打断,当另外一个中断的上半部执行完时,会判断count是否为零,如果大于0,中断会马上处理完成,这时候去恢复所有中断的下半部,这些下半部都会得到执行。 

        但是这些执行很慢,系统会变得卡顿怎么办?此时程序员们想到了,把中断放入线程中去执行,这样系统的程序和中断都会得到调度,就不会那么卡了。       

        内核会给你创建一个worker线程(内核线程),线程里会有worker queue队列,想让worker执行时,往队列放数据即可。

        但是这些线程只会在一个核上运行,效率较低。所以用到了thread_irq,当你传入函数时,会单独创建一个线程,这些单独的线程可以在不同的核上执行。

9、stm32中断系统

        由 中断向量表、中断优先级、EXIT、NVIC、中断函数组成

中断优先级:

        分为抢占式优先级和响应优先级

配置:

GPIO-AFIO

        /打开AFIO时钟(供中断使用)

EXIT:        line(中断线) ->trigger(上升沿还是下降沿触发)

        /创建结构体

        /选择中断线

        /开启中断

        /指定中断线模式(中断模式/事件模式)

        /指定触发有效边沿(上升/下降沿触发)

        /EXTl_Init函数将结构体放入寄存器位置

 NVIC:        channle-> 抢占优先级->响应优先级

        //配置NVIC优先级分组(每个程序只有一个)

        //定义结构体

        /指定中断通道开启或关闭

        /指定通道是使能或失能

        /指定通道的抢占优先级

        /指定通道的响应优先级

        /NVIC_Init

中断函数       

        //配置对应的中断处理函数

        //如果有多个中断线,就判断标志位是哪一根线的中断

        //中断结束后清除标志位

        

        

        

        

        


        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值