基于DM9161的RL-TCPnet实现
来源:互联网 发布:24周胎儿发育标准数据 编辑:程序博客网 时间:2024/04/30 18:01
RL-ARM版本:4.22
以太网PHY:DM9161
处理器:STR912FAW4x
软件平台:裸奔
编译环境:MDK-ARM Professional Version: 4.23
目标:固定IP,ping通
如果Keil提供了处理器的MAC驱动,并且驱动与PHY匹配的话,那么RL-TCPnet的实现超简单。Keil提供了STR9的驱动,不过那是为STE100P写的,而我用的是DM9161,驱动不能直接用,因此费了一些脑筋。
RL-TCPnet可独立于RTX内核运行,为了降低调试难度,我采用了裸奔的方式。
1. 添加并修改Net_Config.c
从Keil\ARM\RL\TCPnet\Config复制Net_Config.c,并修改如下:
去掉不用的模块。UDP要选上,因为ping的ICMP包要用到。
2. 添加函数库
从\Keil\ARM\RV31\LIB复制TCP_ARM_L.lib,并添加到MDK。
3. 添加并修改驱动
从\Keil\ARM\RL\TCPnet\Drivers复制STR9_ENET.c和STR9_ENET.h。
对比STE100P和DM9161的手册,发现两个芯片的寄存器0~6内容基本相同(业内标准??),于是我将STE100P特有的寄存器定义去掉,只保留相同的内容(STR9_ENET.h文件):
/* PHY Registers */#define PHY_REG_XCR 0 /* XCVR Control Register */#define PHY_REG_XSR 1 /* XCVR Status Register */#define PHY_REG_PID1 2 /* PHY Identifier 1 */#define PHY_REG_PID2 3 /* PHY Identifier 2 */#define PHY_REG_ANA 4 /* Auto-Negotiation Advertisement */#define PHY_REG_ANLPA 5 /* Auto-Neg. Link Partner Abitily */#define PHY_REG_ANE 6 /* Auto-Neg. Expansion Register *///#define PHY_REG_XCIIS 17 /* XCVR Config. and Interrupt Status *///#define PHY_REG_XIE 18 /* XCVR Interrupt Enable Register *///#define PHY_REG_100CTR 19 /* 100Base-TX PHY Control/Status *///#define PHY_REG_XMC 20 /* XCVE Mode Control Register */
编译,提示PHY_REG_XCIIS未定义,代码在STR9_ENET.c的此处:
regv = read_PHY (PHY_REG_XCIIS); if (regv & 0x0100) {
这两行的作用是判断是否全双工,可以通过读取寄存器0来实现:
regv = read_PHY (PHY_REG_XSR); if (regv & 0x5000) {
根据DM9161的PHY ID和PHYAD[0~4]管脚的复位电平,将STR9_ENET.h这两行
#define STE100P_DEF_ADR 0x0000 /* Default PHY device address */#define STE100P_ID 0x1C040010 /* PHY Identifier */
改为:
#define PHY_DEV_ADDR 1 /* PHY device address */#define PHY_ID 0x0181B8A0 /* PHY Identifier */
同时修改STR9_ENET.c相关内容。
init_ethernet函数:
if (((id1 << 16) | (id2 & 0xFFF0)) == PHY_ID) {
write_PHY函数:
ENET_MAC->MIIA = (PHY_DEV_ADDR << 11) | (PhyReg << 6) | MIIA_WR | MIIA_BUSY;
read_PHY函数:
ENET_MAC->MIIA = (PHY_DEV_ADDR << 11) | (PhyReg << 6) | MIIA_BUSY;
最后,由于带__irq关键字的中断函数在裸奔时无法正常运行,将STR9_ENET.c文件中的所有__irq关键字去掉。
顺便说一下,这个驱动采用的是中断方式。根据Keil的手册,RL-TCPnet的以太网驱动有两种方式:轮询方式和中断方式。这里我没有看到poll_ethernet函数,而init_ethernet函数配置了中断入口,因此是中断方式。
4. 编写main.c
代码如下:
#include <rtl.h>bool g_100mstimeout = FALSE; //这个标志在100ms定时中断置为TRUEvoid timer_poll () { if (g_100mstimeout) { timer_tick (); // RL-TCPnet function g_100mstimeout = FALSE; }}int main (void) { //此处初始化100ms定时器和外围时钟等 init_TcpNet (); while (1) { timer_poll (); main_TcpNet (); }}
5. 注意事项
(1)如果PHY的时钟信号使用独立晶振,不使用STR9的P5.2,那么需要修改STR9_ENET.c中init_ethernet函数的IO初始化代码,禁止P5.2输出。不这样做的话,P5.2高频率悬空,对板子的EMC性能有影响。
(2)采用2008版STR91x.s在裸奔的时候无法正常运行,我采用的是2006版的文件。
(3)裸奔的时候STR91x.s中的Setup Library Exception Handlers选项必须打开,否则中断函数不正常。
有意思的是,以上(2)(3)两点以及__irq关键字都是与使用RTX的情况相反。原因不清楚,暂时没有去研究。
6. 参考资料
http://download.csdn.net/detail/zoogar/4003823 -- DM9161手册
http://download.csdn.net/detail/zoogar/4003811 -- STE100P手册
http://download.csdn.net/detail/zoogar/3983092 -- RL-ARM User's Guide
http://download.csdn.net/detail/zoogar/3983085 -- Building Applications with RL-ARM - Getting Started
http://bbs.eeworld.com.cn/thread-192539-1-3.html -- 云*飞扬写的网络开发笔记
http://bbs.eeworld.com.cn/thread-285929-1-1.html -- shilaike写的Realtime库学习心得
- 基于DM9161的RL-TCPnet实现
- 基于RL-TCPnet的Web Server应用
- 在RL-TCPnet下的UDP通信
- RL-TCPNet的移植与使用简介
- RL-TCPNet库提供的函数整理
- STM32移植RL-TCPnet
- STM32F107 以太网 + RL-TCPnet
- 【RL笔记】基于tensorflow实现RL的policy based算法
- MDK 5.0的RL Tcp/ip库和MDK 4.0的RL-TCPNet的区别
- 基于NAND Flash的RL-FlashFS实现
- RL-TCPnet移植到enc28j60
- RL-TCPnet之TCP服务器(enc28j60)
- DM9161
- DM9000的DM9161的比较
- dm9161和at91rm9200的收、发过程
- rl-flashFS的移植
- RL强化学习 C++实现
- RRC连接、RL、RB、RAB的本质
- Javascript数组删除索引元素的方法
- 开始学习Python
- EhCache之初试
- 关于“实模式”和“保护模式”
- 防止程序无响应
- 基于DM9161的RL-TCPnet实现
- 软考成绩查询网址
- Windows7下硬盘安装Ubuntu 11.04
- 备忘录:Nutch+eclipse配置
- 值得捐赠的10个开源项目
- 文字与图片图像
- 用户层与驱动层阻塞读写
- 复制一批文件 include **/*.java */*.java
- 一个平凡菜鸟的C#琐碎总结 ---- C#打印功能的实现