先说说我使用的平台:MDK3.5, 安装实时库文件:RL-ARM4.12
移植步骤:
1:用MDK创建一个新工程,建立如下图的一个工程(并根据不同的源文件建立不同的文件夹,以方便管理)
其中,WebFile文件下的文件为与网页相关的文件,Start文件下为系统的启动文件,FWLib为STM32的链接库,Config为配置文件,Web文件夹下的Web.c是经过FCARM转换后产生的。NetDriver是网卡驱动的文件夹,其他文件可以根据你自己的工程需要添加。下图展示的是我实际应用中的一个工程结构。
图1
2:以太网卡驱动的移植
编写网卡驱动DM9000A.C文件(以我的为例),并加入到工程NetDriver的文件夹中,在非中断模式下,编写网卡驱动主要做的工作是提供如下三个接口函数给 RL-TCPnet
init_ethernet(void) 初始化以太网控制器。
poll_ethernet(void) 从以太网控制缓冲器读取包。
send_frame(OS_FRAME* frame) ;发包到以太网控制器。
网卡驱动代码网上资源较多,,函数部分示意性的代码
void init_ethernet(void)
{
DM9_CtrlLinesConfig();//配置STM32开发板与网卡芯片相关的管脚及使能等
DM9_FSMCConfig();//配置STM32 FSMC,网卡芯片是DM9000A
DM9_Init();//初始化网卡芯片
}
void poll_ethernet(void)
{
OS_FRAME *frame;//添加一个OS_FRAME结构体类型,
判断是否有一帧数据
…
…
frame = alloc_mem (rx_length+1);//申请rx_length长度的内存
将网卡接受到的一帧数据存入frame->data中,
put_in_queue (frame);//调用RL-TCPnet提供的API函数,将网卡数据放入队列中。
}
void send_frame (OS_FRAME *frame)
{
DM9_Send_packet(frame->data,frame->length); //frame->length 保存需要传递的帧的总长度,frame->data数据帧,//OS_FRAME。
其原型定义在 net_config.h中
}
3:添加Net_Config.c配置文件
在MDK的安装目录下找到Net_Config.c配置文件并添加到工程Config文件夹下。根据需要对各个选项进行配置,下图是我的应用中的一个配置
图2
4:HTTP Server的应用(如果不需要,可以跳过这一步)
(1)找到Web.inp的文件(可以到RL-TCPNet的提供的HTTP_demo例程目录下找到),添加到WebFile文件夹中
Web.inp文件是根据FCARM的语法命令编写的,主要是用来描述静态网页所用到的所有信息,并通过FCARM工具转换为可编译的文件。如下所示:
index.htm, guet.gif, mov1.gif, llblue.jpg, pabb.gif, home.png,
network.cgi, leds.cgi, tcp.cgi, system.cgi, lcd.cgi, language.cgi,
pg_header.inc, pg_footer.inc, xml_http.js, fault.cgi to Web.c nopr root(Web)
它表达的意思就是将index.htm.guet.gif,mov1.gif ……等网页用到的CGI文件以及图片等信息转换为Web.c文件
(2)将Web.inp文件中用到的网页cgi文件,图片文件,以及后缀为htm的文件等等添加到工程的WebFile文件夹中,添加之后如上边图1的WebFile文件夹下的所示
(3)上边之所以将这些文本文件类型的文件加入工程,主要是便于修改网页文件的时候能够及时更新转换后的Web.c文件,为此,需要在如下位置添加(如图3),也即在编译前预处理我们的网页信息。
在Run User Programs Before Build/Rebuild这一栏下添加FCARM路径,及Web.inp文件的路径。
(4): 找到通过FCARM网页转换工具生成的Web.c文件(可再后边经过编译之后在添加),找到HTTP_CGI.c的文件(可以到RL-TCPNet的提供的HTTP_demo例程目录下找到),添加到工程Web文件夹中,
5:关键函数的调用
在使用中,主要涉及到三个关键函数
init_TcpNet ();//网卡初始化及RL-TCPnet初始化工作,系统提供
main_TcpNet();//轮询网卡,检查是否有数据到来,有则自动调用相应的处理函数
timer_tick ();//timer_tick函数设置了系统测量时间标志,TCPnet系统用它来衡量时间 ,如,ARP的更新时间,连接超时等
对于不使用RL-RTX实时系统的情况,示意性代码如下
#include <rtl.h>
static void timer_poll () {
if (T1IR & 1) {
T1IR = 1;
/* Timer tick every 100 ms */
timer_tick ();//每100ms调用一次
}
}
timer_tick函数设置了系统测量时间标志,TCPnet系统用它来衡量时间
void main (void) {
init ();
/* Initialize the TcpNet */
init_TcpNet ();
while (1);
/* Poll the system tick timer */
timer_poll ();
/* Run main TcpNet ‘thread’ */
main_TcpNet ();
}
}
使用RL-RTX实时系统的情况:
#include <rtl.h>
U64 tcp_stack[800/8]; /* A bigger stack for tcp_task */
BOOL tick;
__task void timer_task (void) {
/* System tick timer task */
os_itv_set (10);
while (1) {
timer_tick ();
tick = __TRUE;
os_itv_wait ();
}
}
__task void tcp_task (void) {
/* Main Thread of the TcpNet. This task should have */
/* the lowest priority because it is always READY. */
while (1) {
main_TcpNet();
//dhcp_check ();
os_tsk_pass();
}
}
__task void init (void) {
init_TcpNet ();
/* Initialize Tasks */
os_tsk_prio_self (100);
os_tsk_create (timer_task, 30);
os_tsk_create_user (tcp_task, 0, &tcp_stack, sizeof(tcp_stack));
os_dly_wait(50);
// os_tsk_create_user (Usb_Hid_Task, 2, &usbhid_stack, sizeof(usbhid_stack));
os_tsk_delete_self();
}
int main()
{
Init_Board();
os_sys_init(init);
}
Write By totozoo 2012.06
转载请注明:徐自远的乱七八糟小站 » 【转贴】RL-TCPnet在STM32开发板上的移植