• 全国客户服务热线:4006-054-001 疑难解答:173-0411-9111(7X24受理投诉、建议、合作、售前咨询),155-4267-2990(售前),传真:0411-83767788,微信:543646
当前位置:主页 > 技术方案 > 工控技术

ARM嵌入式系统开发之发送过程的实现

时间:2023-09-29 10:35来源: 作者: 点击:
>ARM嵌入式系统开发之发送过程的实现

要通过网卡数据时,上层协议实体调用函数hard_start_xmit(),在我们的驱动程序中这个函数被映射成DM9000_wait_to_send_packet()函数,正如它名字中wait所表示的那样,这个函数只完成了等待的工作,实际的是调用DM9000_hardware_send_packet()函数完成的,这也是前面提到的buffer分配机制的一种体现。
在具体介绍这两个函数之前,有必要简单说一说DM9000芯片发送数据的工作原理。前面已经讲过,为了增加网络吞吐量DM9000芯片内部集成了8K的buffer,芯片对这些buffer采用了内存页面管理方式,每页256B,内部寄存器支持简单的内存分配指令。对于内核来说,发送数据只是把数据从内核送到芯片的buffer中去,实际向物理媒介上的发送和相关的控制(CSMA/CD)是由芯片自主完成的。完成情况通过中断的方式通知内核。

在数据发送中用到两个函数。函数DM9000_wait_to_send_packet()一方面和上层协议接口,另一方面检查buffer分配是否成功,如果成功就调用,DM9000_hardware_send_packet()将数据传送到buffer中去,如果不成功,则打开相关中断,在分配成功时由中断控制程序调用DM9000_hardware_send_packet()完成数据传送。这两个函数都用到Linux网络协议栈中很重要的一个数据结构sk_buff,关于它在讲接收程序时再详细介绍。下面结合代码片段分析这两个函数的功能。

static int DM9000_wait_to_send_packet( struct sk_buff* skb, struct net_device * dev )

{

struct DM9000_local *lp = (struct DM9000_local *)dev->priv;

word length;

unsigned short numPages;

word time_out;

word status;

lp->saved_skb = skb;

length = ETH_ZLEN skb->len ? skb->len : ETH_ZLEN;

numPages = ((length 0xfffe) + 6);

numPages >>= 8;

DM9000_SELECT_BANK( 2 );

outw( MC_ALLOC | numPages, MMU_CMD_REG );

}

以上代码从skb中读出数据长度做一些处理后,换算出所需的页面数。然后向芯片发出分配buffer的请求,MC_ALLOC和MMU_CMD_REG都是在头文件中定义的宏,MC_ALLOC是分配buffer空间的寄存器指令,而MMU_CMD_REG是MMU命令寄存器的地址。

time_out = MEMORY_WAIT_TIME;

do {

status = inb( INT_REG );

if ( status IM_ALLOC_INT ) {

break;

}

} while ( -- time_out );



>ARM嵌入式系统开发之发送过程的实现
热门服务和内容