使用GPIO库函数时,其端口参数怎么表达?

  • 功能:用于注册网卡到系统中,如果之前网卡设备链表为空,则直接复制给全局指针变量eth_devices和eth_current ,如果不为空,则把当前网卡插入到链表eth_devices中。

DM9000A 拥有一系列的控制和状态寄存器,这些寄存器可以被处理器所访问,这些寄存器是按字节对齐的。

所有的 CSRs 在软件或者硬件复位后都将被置为默认值,除非他们被另外标识。

通用目的控制寄存器(8bit 模式)
即将发送控制/状态寄存器
接收校验和控制状态寄存器
内存数据预取读命令寄存器(地址不加 1)
内存数据读命令寄存器(地址不加 1)
内存数据读命令寄存器(地址加 1)
内存数据读地址寄存器低字节
内存数据读地址寄存器高字节
内存数据写命令寄存器(地址不加 1)
内存数据写命令寄存器(地址加 1)
内存数据写地址寄存器低字节
内存数据写地址寄存器高字节
TX 数据包长度低字节寄存器
TX 数据包长度高字节寄存器

在下面寄存器描述中,默认栏采用如下形式:

P 电源复位恢复默认值 H 硬件复位恢复默认值 S 软件复位恢复默认值 T 从捆绑引脚(strap pin)得到默认值 RW/C1=可读可写/通过写1擦除

保留位被隐藏且应写 0,在读访问时保留位没有定义。

    条件: nGCS1 信号拉低、 Xm0OEn 信号拉低、 Xm0ADDR2 拉高, 或者说从下面的地址读数据

DM9000A的寄存器很多,但是我们并需要都掌握,我们只需要掌握其中几个最重要的寄存器的使用即可。

  1. 网络控制寄存器(NCR)
  2. 网络状态寄存器(NSR)

429行即调用我们注册的dm9000A初始化函数,从这也可以看出,整个架构是把网卡的驱动独立分隔开,与硬件操作相关的代码由用户自己填充并注册到系统中即可,便于扩展。

通过读 bit[15:12]来看经过自动协商后选择的是哪一种模式。
网卡自动协商完成后,结果将被写到该位。若该位为 1,意味着操作 1 模式是 100M 全双工模式。

  1. 发送写操作,操作MWCMD
  2. 等待数据发送完毕,轮训检查NSR
void *packet :发送数据包存放的内存的首地址

414行 打开debug开关,该行会打印发送的数据包
416行 使能数据包发送,将寄存器ISR的bit[1]设置为1
419行 通过寄存器MWCMD写入一个地址,并向该地址对应的 SRAM 中写数据。执行写该指令之后,写指针会根据操作模式(8 位或 16 位)自动增加 1 或 2。
425~426行 将发送数据包长度写入到寄存器TXPLL/TXPLH中,这两个寄存器分别对应低字节和高字节
429行 向寄存器TCR的bit[0]写入1,来请求发送数据,发送完毕该位自动清0
432~440行 通过向寄存器ISR的bit[1]写入1,来清楚发送标记位

此处我们看到每次都是从相同的地址读取数据,为什么不需要做地址偏移呢?
答:寄存器MWCMD已经和我们说的很清楚了,写该指令之后,指写指针根据操作模式(8 位或 16 位)增

479行 读取寄存器MRCMDX, 以从接收 SRAM 中读数据;执行读取该指令之后,指向内部 SRAM的读指针不变。DM9000A 开始预取 SRAM 中数据到内部数据缓冲中
500行 通过函数指针db->rx_status读取网卡的状态和接收到的数据包的长度

由此可见,要分析DM9000A的数据收发的原理和流程,就要分析我们注册网卡的以下几个函数:

五、uboot中网络协议栈

网卡的驱动,对于上层协议来说,已经封装好了发送和接收数据的接口,那么上层协议栈只需要按照顺序调用对应的网卡驱动函数就可以进行网络数据的收发。

uboot中的协议栈相对来说比较简单,有以下几个特点:

  1. 传输层只支持UDP协议;
  2. 网卡采用poll接收数据包,而不是中断方式;
  3. 数据包的发送和接收操作是串行操作,不支持并发。

下面是uboot网络协议栈的函数调用流程:

2. 通过DNS命令来解析一个数据包的收发流程

dns命令的定义如下:

当我们在uboot的命令终端输入命令dns后,命令解析函数就会调用dns执行函数do_dns()

406行 判断参数字符串长度,大于255非法
413~416行 保存dns命令的环境参数,该参数可以没有
418行 进入网络协议处理函数入口NetLoop(),并将对应的协议DNS传递给该函数

NetLoop()代码比较长,我们只分析其中比较重要的几段代码

367行 对传入的参数做switch操作,不同的协议进入到不同的处理流程

51~57行 根据dns协议填充dns协议头,数据帧首地址为NetTxPacket,此处通过指针pkt和p来填充dns数据帧
60~85行 根据协议格式要求填充要解析的host名字到数据包
87行 计算数据包长度
90行 产生一个随机的端口号
92~93行 调用udp协议的发送函数NetSendUDPPacket(),参数依次是:以太头信息,DNS服务器 ip地址,DNS服务器端口号,我们的dns服务端口号,数据包长度

716~730行 如果没有目的MAC地址,就要先发送ARP请求
734行 调用函数NetSendPacket(),参数分别是:要发送数据帧的首地址,数据包长度

该函数已经分析过,根据流程图,回到函数NetLoop()

461~562行 循环接收网络数据包

参数inpkt:指向接收到的以太数据包头 len:接收到的数据包的长度
960行 变量NetRxPacket指向接收的数据头,以太数据包包头比定位以太协议头
985行 从以太协议头提取出协议字段,该字段表示后面是否是ip协议
999行 解析出ip协议头
1045行 根据以太头协议进行switch操作
行 对协议头进行合法性检查
1085行 读取出目的ip地址
1093行 读取出源ip地址,

该函数用于解析DNS协议,在此不再详解
475行 判断是否按下ctrl+c快捷键,并作出操作
522~562行 对执行结果进行处理,计入统计信息
如果net_state为NETLOOP_CONTINUE,表明仍然有后续数据包要接收,则回到461行,继续下一个数据包的接收

至此DNS协议的处理流程分析完毕,大家可以根据这个流程自行分析其他几个协议的处理流程。

上一节看完手册以后,你或许已经明白怎么配置一个GPIO接口让它实现输入输出的各种功能了。但是如果我问起你:如果要让GPIOA端口的P0和P1配置成推挽输出10MHz模式,你该怎么做,你会做些什么?
绝大多数人做的事情应该还是翻开手册里GPIO_CRL的寄存器定义,然后照着手册编程。GPIO外设的功能比较简单,需要配置的功能不算太多,这么做没什么难度。但有些外设的配置寄存器有许许多多控制位,比如下面这位:
这是串口通信外设的控制寄存器1(对没错,还有个控制寄存器2),里面的14个有效位都与通信的各种规则和状态密切相关,通过查手册一位一位地改显然有点不太经济且不甚直观。
标准固件库函数就是为这个而生的。ST官方将常用的对外设的操作和外设的各种状态封装成可读性更高的函数和结构供用户使用。我们就着GPIIO的库函数来看看,这玩意到底有什么魔力。
并且在你的main里包含两个.h。打开这gpio的两个文件,里面虽然看着纷繁,但核心思路我们一讲便通。

与之配套地,这些字段的有意义值被定义成了相关的枚举或宏,你可以在.h中找到这些东西:

这个结构体用来装载开发者对外设的配置参数并作为参数输入给Init函数。因此你在执行Init函数前需要像这样定义一个结构体并设置它的值:

在它上边右键单击后选择“Go to Defnition”可以查看这个函数的内容。我将它复制过来,并添加了中文注释进行讲解。请仔细阅读。

函数的运行原理请多加阅读和理解,里边的一些代码习惯也是你学习的榜样。
于是乎,我们只需要在刚才定义好初始化结构体之后运行一句Init函数就好:

虽然初始化结构体没必要一定和初始化函数在一个作用域,但我还是希望你能把他们两个放在同一个代码块(最好是为它们单独开辟一个大括号),这样逻辑更清晰,也更加节省空间。
最后,别忘了我们最开始就讲过的配置外设常用步骤,我们还差“挂时钟”一步,这你只需要在运行初始化之前先来一下:

这个函数在_rcc.h里声明,可以去看看,我们之后会讲。

运行Init函数之后,你想打开的端口就都启动了。你还可以用修改寄存器的办法去操作它们的电平,不过,你在刚才的函数中还有十几个没有用,它们都可以用来修改我们上节讲的那些寄存器,进而实现对IO
口的各种操作。你也可以“Go to
Definition”一下,去看看它们的内容并理解它们的功能。以下是一个例子,开启GPIOA的所有端口做输出,并开启GPIOB的所有端口做输入。


这里边不仅有对一个引脚的位操作,还有对字节和半字的操作,它们在电机控制、并口通讯等领域应用广泛。

使用DPI接口时,根据LCM IC支持的情况,可以选择16bus、18bus传输RGB格式文件,在GPIO 部分分为R、G、B分别对应8个GPIO(GPIO20~46期间),客户采用DPI接口需要根据选择的bus

方式进行配置,推荐RGB端口全部配置为对应的复选模式,并设置为OUT输出。

采用DBI接口,有两种模式选择,一种是选择共用DPI的bus脚+DPI控制线,另一种是共用nand data pin+CPU 控制线。

不同ESD方式需要注意的方面

目前我司HDMI/MHL的相关code和driver都是有集成在codebase中的,要使用的话,只需要只需要在对应的ProjectConfig.mk文件中开启,并且在dct中配置好对应的引脚定义即可。

大部分TE问题是由于没有正常开启TE所导致,首先检查TE是否开启。

89平台使用内部TE,lcm driver中只需要在init过程中打开LCM TE即可,一般是写0x35寄存器,部

我要回帖

更多关于 二端口网络四个参数 的文章

 

随机推荐