http://www.altera.com/devices/processor/nios2/tools/embed-partners/ni2-network-stack.html
以前,NIOS使用Lightweight IP (LWIP) network stack方案,目前使用NicheStack TCP/IP Network Stack。
NicheStack® TCP/IP Stack - Nios® II Edition 目标是 减少资源使用提供全部功能的TCP/IP协议栈。设计用于小内存的嵌入式系统。NIOS可以在BSP中添加,有以下特性:
包括以下两种MAC的驱动:SMSC lan91c111设备、Altera Triple-Speed Ethernet
它的驱动是基于中断的,因此需要确保连接了以太网元件的中断。硬件基础是HAL。
主要接口是标准sockets接口。调用以下两个函数来初始化协议栈和驱动:alt_iniche_init() 和 netmain()。可以使用初始化线程中的全局变量 iniche_net_ready。必须提供HAL系统代码调用的两个简单函数来获取MAC地址和IP地址:get_mac_addr() 和 get_ip_addr()。
NicheStack 主任务(main task),tk_netmain() —— 初始化后,该任务 sleep 直到一个新的数据包到达要处理。数据包通过中断服务程序(ISR)来接收,当ISR收到数据包,放入接收序列,唤醒该主任务。
NicheStack 定时任务(tick task),tk_nettick() —— 周期性的唤醒。
在初始化之前,先通过从 main() 函数中调用 OSStart() 来启动 MicroC/OS-II 流程。为确保在 RTOS 运行和 I/O 驱动可用之前,不要企图更多的初始化操作,需要在高优先级的任务中进行协议栈的初始化。
在 iniche_net_ready 为真之前,需要确保不要使用协议栈接口。如:
void SInitialTask(void *task_data)
{
INT8U error_code;
/*
* Initialize Altera NicheStack TCP/IP Stack - Nios II Edition specific code.
* NicheStack is initialized from a task, so that RTOS will have started, and
* I/O drivers are available. Two tasks are created:
* "Inet main" task with priority 2
* "clock tick" task with priority 3
*/
alt_iniche_init();
/* Start the Iniche-specific network tasks and initialize the network
* devices.
*/
netmain();
/* Wait for the network stack to be ready before proceeding. */
while (!iniche_net_ready)
TK_SLEEP(1);
/* Now that the stack is running, perform the application initialization steps */
}
这里 TK_SLEEP 在 NicheStack 中定义
#define TK_SLEEP(count) OSTimeDly(count + 1)
NicheStack TCP/IP Stack 系统代码在设备初始化过程中需要调用 get_mac_addr() and get_ip_addr(),这两个函数用来设置 在BSP中的 altera_iniche.iniche_default_if 选择的网络接口的 MAC 和 IP 地址。MAC最好不要指定固定地址,可以保存在一个灵活的地方,如flash中。
prototypes:
int get_mac_addr(NET net, unsigned char mac_addr[6]);
int get_ip_addr(alt_iniche_dev* p_dev,
ip_addr* ipaddr,
ip_addr* netmask,
ip_addr* gw,
int* use_dhcp);在
mac地址需要保证在产品线上的唯一性。
在 get_ip_addr 函数中,通过以下代码来设定:
IP4_ADDR(*ipaddr, IPADDR0, IPADDR1, IPADDR2, IPADDR3);
IP4_ADDR(*gw, GWADDR0, GWADDR1, GWADDR2, GWADDR3);
IP4_ADDR(*netmask, MSKADDR0, MSKADDR1, MSKADDR2, MSKADDR3);
开启DCHP:
*use_dhcp = 1;
在30秒内自动获取失败会使用默认IP。
iniche_default_if和dhcp_client都可以在BSP Editor中指定。
初始化完成后,就可以使用sockets API来访问IP栈。
必须使用 TK_NEWTASK() 函数来使用 sockets API 访问IP栈。
在 ipport.h 文件中,可以使用 #define 来配置很多的选项。