龙芯1c的网卡驱动已提交到RT-Thread官方git(https://github.com/RT-Thread/rt-thread)了,RT-Thread默认会初始化网口,初始化函数为rt_hw_eth_init(),已在函数rt_init_thread_entry()中默认调用了。socket编程时,只需要创建一个线程,然后调用lwip的NETCONN接口编程即可。假设已经对lwip有一定了解了,如果不了解,请移步到《NETCONN编程接口简介 LWIP(一) 》http://blog.csdn.net/feather_wch/article/details/50473933
在RT-Thread的msh下使用命令ifconfig查看当前IP地址,如下
Ip地址在头文件“rtconfig.h”中修改,比如将板子的IP设为192.168.1.254,修改后的源码如下
本文通过在龙芯1c的板子上,新建两个RT-Thread线程,分别用tcp和udp实现echo(回显)的功能,即收到什么返回什么。另外,在虚拟机的linux上用socket编程来测试,即linux下用c实现的小程序先发送一个字符串,然后看看龙芯1c板子是否返回通用的字符串。
不废话了,直接上源码
在RT-Thread下,只需要在源文件“bsp\ls1cdev\applications\application.c”中,新建线程“tcpecho”和“udpecho”即可。具体源码如下
/*
* File : application.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006-2012, RT-Thread Develop Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-06-25 Bernard first version
* 2011-08-08 lgnq modified for Loongson LS1B
* 2015-07-06 chinesebear modified for Loongson LS1C
*/
#include
#include
#include "net/synopGMAC.h"
#include
#define TCP_ECHO_PORT 8000
#define UDP_ECHO_PORT 8000
#define printf rt_kprintf
static void DumpData(const rt_uint8_t *pcStr,rt_uint8_t *pucBuf,rt_uint32_t usLen)
{
rt_uint32_t i;
rt_uint8_t acTmp[17];
rt_uint8_t *p;
rt_uint8_t *pucAddr = pucBuf;
if(pcStr)
{
printf("%s: length = %d [0x%X]\r\n", pcStr, usLen, usLen);
}
if(usLen == 0)
{
return;
}
p = acTmp;
printf("%p ", pucAddr);
for(i=0;i=0x20) && (pucBuf[i]<0x7F))
{
*p++ = pucBuf[i];
}
else
{
*p++ = '.';
}
if((i+1)%16==0)
{
*p++ = 0;//string end
printf(" | %s", acTmp);
p = acTmp;
printf("\r\n");
if((i+1) < usLen)
{
pucAddr += 16;
printf("%p ", pucAddr);
}
}
else if((i+1)%8==0)
{
printf("- ");
}
}
if(usLen%16!=0)
{
for(i=usLen%16;i<16;i++)
{
printf(" ");
if(((i+1)%8==0) && ((i+1)%16!=0))
{
printf("- ");
}
}
*p++ = 0;//string end
printf(" | %s", acTmp);
printf("\r\n");
}
}
static int rt_netconn_recv(struct netconn *conn, struct netbuf **new_buf)
{
err_t err;
err = netconn_recv(conn,new_buf);
if(*new_buf)
return 1;
else
return 0;
}
void rt_tcpecho_entry(void *parameter)
{
struct netconn *conn, *newconn;
err_t err;
struct netbuf *buf;
void *data;
u16_t len;
rt_kprintf("tcpecho server start...\r\n");
/* Create a new connection identifier. */
conn = netconn_new(NETCONN_TCP);
/* Bind connection to well known port number 7. */
netconn_bind(conn, IP_ADDR_ANY, TCP_ECHO_PORT);
/* Tell connection to go into listening mode. */
netconn_listen(conn);
for(;;)
{
/* Grab new connection. */
err = netconn_accept(conn,&newconn);
/* Process the new connection. */
if(newconn != NULL)
{
while(rt_netconn_recv(newconn,&buf))
{
do
{
netbuf_data(buf, &data, &len);
DumpData("tcpecho packet",data,len);
err = netconn_write(newconn, data, len, NETCONN_COPY);
if(err != ERR_OK)
{
rt_kprintf("netconn_write(),ret=%d\r\n",err);
}
}while(netbuf_next(buf) >= 0);
netbuf_delete(buf);
buf = NULL;
}
/* Close connection and discard connection identifier. */
netconn_delete(newconn);
newconn = NULL;
}
}
}
void rt_udpecho_entry(void *parameter)
{
struct netconn *conn;
struct netbuf *buf;
struct ip_addr *addr;
unsigned short port;
void *data;
u16_t len = 0;
rt_kprintf("udpecho server start...\r\n");
conn = netconn_new(NETCONN_UDP);
netconn_bind(conn, IP_ADDR_ANY, UDP_ECHO_PORT);
for(;;)
{
/* received data to buffer */
netconn_recv(conn,&buf);
netbuf_data(buf, &data, &len);
DumpData("udpecho packet", data, len);
// 延时2秒
rt_thread_delay(2 * RT_TICK_PER_SECOND);
addr = netbuf_fromaddr(buf);
port = netbuf_fromport(buf);
/* send the data to buffer */
netconn_connect(conn, addr, port);
/* reset address, and send to client */
buf->addr.addr = 0;
netconn_send(conn, buf);
/* release buffer */
netbuf_delete(buf);
rt_kprintf("[%s] port = %u\n", __FUNCTION__, port);
rt_kprintf("[%s] send response\n", __FUNCTION__);
}
}
void rt_init_thread_entry(void *parameter)
{
/* initialization RT-Thread Components */
rt_components_init();
rt_hw_eth_init();
}
int rt_application_init(void)
{
rt_thread_t tid,echo_tid,udpecho_tid;
/* create initialization thread */
tid = rt_thread_create("init",
rt_init_thread_entry, RT_NULL,
4096, RT_THREAD_PRIORITY_MAX/3, 20);
if (tid != RT_NULL)
rt_thread_startup(tid);
echo_tid = rt_thread_create("tcpecho",
rt_tcpecho_entry, RT_NULL,
4096, 30, 5);
if (echo_tid != RT_NULL)
rt_thread_startup(echo_tid);
udpecho_tid = rt_thread_create("udpecho",
rt_udpecho_entry, RT_NULL,
4096, 30, 5);
if (udpecho_tid != RT_NULL)
rt_thread_startup(udpecho_tid);
return 0;
}
// client.c
#include
#include
#include
#include
#include
#include
#define MAXLINE 80
#define SERV_PORT 8000
int main(void)
{
struct sockaddr_in servaddr;
char buf[MAXLINE] = {0};
int sockfd;
char str[] = "ls1c rtt lwip!";
int len = 0;
if (0 > (sockfd = socket(AF_INET, SOCK_STREAM, 0)))
{
perror("socket");
return 1;
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("192.168.1.254");
servaddr.sin_port = htons(SERV_PORT);
if (0 > connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)))
{
perror("connect");
return 1;
}
printf("connect to server\n");
len = send(sockfd, str, strlen(str), 0);
printf("send ok, len=%d\n", len);
sleep(1);
len = recv(sockfd, buf, MAXLINE, 0);
buf[len] = '\0';
if (0 == len)
{
printf("no byte recv!\n");
}
else
{
printf("[%s] response from server:%s\n", __FUNCTION__, buf);
}
close(sockfd);
return 0;
}
#include
#include
#include
#include
#include
#include
#include
#define BUF_SIZE (1024)
#define SERVER_PORT (8000)
int main(void)
{
int client_sockfd;
int len;
struct sockaddr_in remote_addr;
int sin_size;
char str[] = "ls1c rtt lwip udp test!";
char recv_buf[BUF_SIZE] = {0};
memset(&remote_addr, 0, sizeof(remote_addr));
remote_addr.sin_family = AF_INET;
remote_addr.sin_addr.s_addr = inet_addr("192.168.1.254");
remote_addr.sin_port = htons(SERVER_PORT);
if (0 > (client_sockfd = socket(PF_INET, SOCK_DGRAM, 0)))
{
perror("socket");
return 1;
}
// 发送字符串
if (0 > (len = sendto(client_sockfd, str, strlen(str), 0, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr))))
{
perror("sendto");
return 1;
}
printf("[%s] sending: %s\n", __FUNCTION__, str);
if (0 > (len = recvfrom(client_sockfd, recv_buf, BUF_SIZE, 0, NULL, 0)))
{
perror("recvfrom");
return 1;
}
printf("[%s] received: %s\n", __FUNCTION__, recv_buf);
close(client_sockfd);
return 0;
}
all:
gcc test_rtt_lwip_tcp_client.c -o test_rtt_lwip_tcp_client
gcc test_rtt_lwip_udp.c -o test_rtt_lwip_udp