SylixOS 下网络驱动编程(一)

        目的:最近在搞DW 网卡驱动,索性自己重新编写驱动,这样加深下在SylixOS 系统下网络驱动的过程;

       1, 开始先了解下SylixOS 下的网络驱动编程流程,建议看下《SylixOS 驱动程序开发》手册,SylixOS 下网络整体框图如下:

         2,通过手册可以得知,如果想在SylixOS 下添加新的网络设备,需要使用到 netdev_add() 这个函数;

/* netdev driver call the following functions add / delete a network interface,
 * if this device not in '/etc/if_param.ini' ip, netmask, gw is default configuration.
 * 'if_flags' defined in net/if.h such as IFF_UP, IFF_BROADCAST, IFF_RUNNING, IFF_NOARP, IFF_MULTICAST, IFF_PROMISC ... */
int  netdev_add(netdev_t *netdev, const char *ip, const char *netmask, const char *gw, int if_flags);

在该函数下有个重要的结构体netdev_t 网络设备结构体:

/*
 * network device struct.
 */
typedef struct netdev {
#define NETDEV_VERSION  (0x00020003)
#define NETDEV_MAGIC    (0xf7e34a81 + NETDEV_VERSION)
  UINT32 magic_no;  /* MUST be NETDEV_MAGIC */

  char  dev_name[IF_NAMESIZE];  /* user network device name (such as igb* rtl* also call initialize with '\0') */
  char  if_name[IF_NAMESIZE];   /* add to system netif name (such as 'en'), after netdev_add() if_name saved full ifname by system */
  char *if_hostname;
  
#define NETDEV_INIT_LOAD_PARAM     0x01     /* load netif parameter when add to system */
#define NETDEV_INIT_LOAD_DNS       0x02     /* load dns parameter when add to system */
#define NETDEV_INIT_IPV6_AUTOCFG   0x04     /* use IPv6 auto config */
#define NETDEV_INIT_AS_DEFAULT     0x08
#define NETDEV_INIT_USE_DHCP       0x10     /* force use DHCP get address */
#define NETDEV_INIT_USE_DHCP6      0x40     /* force use IPv6 DHCP get address */
#define NETDEV_INIT_USE_AODV       0x80     /* use AODV(Ad-hoc) Only for LOWPAN (ipv4 only) */
#define NETDEV_INIT_DO_NOT         0x20     /* do not call init() function (Only used for net bridge) */
#define NETDEV_INIT_NO_TXQ         0x100    /* do not support txqueue */
#define NETDEV_INIT_TIGHT          0x200    /* add to bridge or bonding do not delete from system */
  UINT32 init_flags;
  
#define NETDEV_CHKSUM_GEN_IP       0x0001   /* tcp/ip stack will generate checksum IP, UDP, TCP, ICMP, ICMP6 */
#define NETDEV_CHKSUM_GEN_UDP      0x0002
#define NETDEV_CHKSUM_GEN_TCP      0x0004
#define NETDEV_CHKSUM_GEN_ICMP     0x0008
#define NETDEV_CHKSUM_GEN_ICMP6    0x0010
#define NETDEV_CHKSUM_CHECK_IP     0x0100   /* tcp/ip stack will check checksum IP, UDP, TCP, ICMP, ICMP6 */
#define NETDEV_CHKSUM_CHECK_UDP    0x0200
#define NETDEV_CHKSUM_CHECK_TCP    0x0400
#define NETDEV_CHKSUM_CHECK_ICMP   0x0800
#define NETDEV_CHKSUM_CHECK_ICMP6  0x1000
#define NETDEV_CHKSUM_ENABLE_ALL   0xffff   /* tcp/ip stack will gen/check all chksum */
#define NETDEV_CHKSUM_DISABLE_ALL  0x0000   /* tcp/ip stack will not gen/check all chksum */
  UINT32 chksum_flags;

#define NETDEV_TYPE_RAW             0
#define NETDEV_TYPE_ETHERNET        1
#define NETDEV_TYPE_LOWPAN          2
#define NETDEV_TYPE_LOWPAN_BLE      3
  UINT32 net_type;
  
  UINT64 speed; /* link layer speed bps */
  UINT32 mtu;   /* link layer max packet length (6LowPAN must be 1280) */
  
  UINT8 hwaddr_len;                     /* link layer address length MUST 6 or 8 */
  UINT8 hwaddr[NETIF_MAX_HWADDR_LEN];   /* link layer address */
  
  struct netdev_funcs *drv; /* netdev driver */
  
  void *priv;   /* user network device private data */
  
  /* the following member is used by system, driver MUST set zero and do not used! */
  int if_flags;
  
  /* wireless externed */
  void *wireless_handlers; /* iw_handler_def ptr */
  void *wireless_data; /* iw_public_data ptr */
  
  /* hwaddr filter list */
  struct netdev_mac *mac_filter;
  
  /* SylixOS Real-Time externd(poll mode) */
  struct netdev_poll poll;
  
  /* SylixOS Tx-Queue */
  void *kern_txq;
  
  /* SylixOS Reserve */
  void *kern_priv; /* kernel priv */
  void *kern_res[15];
  
  ULONG sys[254];  /* reserve for netif */
} netdev_t;

3,好了,废话不多说直接上搭建好的网络驱动代码模板:

#define  __SYLIXOS_KERNEL
#include <SylixOS.h>
#include <netdev.h>

char  *ip          = "10.9.0.99";
char  *netmask     = "255.255.0.0";
char  *gw          = "10.9.0.1";

char *netDevName     = "dw";
netdev_t             dwDev;

int   dwTransmit(struct netdev *netdev, struct pbuf *p);
void  dwReceive(struct netdev *netdev, int (*input)(struct netdev *, struct pbuf *));

struct netdev_funcs  netFuns = {
        .init       = NULL,
        .up         = NULL,
        .down       = NULL,
        .remove     = NULL,
        .transmit   = dwTransmit,
        .receive    = dwReceive,
        .pollrecv   = NULL,
        .intctl     = NULL,
        .rxmode     = NULL,
        .ioctl      = NULL,

};

int  dwTransmit(struct netdev *netdev, struct pbuf *p)
{
    return  (0);
}

void  dwReceive(struct netdev *netdev, int (*input)(struct netdev *, struct pbuf *))
{
    return;
}

void dwCreate(void)
{
    int ret = 0;
    lib_memcpy(dwDev.dev_name,netDevName,sizeof(netDevName));
    lib_strcpy(dwDev.if_name,  "en");

    dwDev.hwaddr_len = 6;
    dwDev.hwaddr[0]  = 0x00;
    dwDev.hwaddr[1]  = 0x11;
    dwDev.hwaddr[2]  = 0x44;
    dwDev.hwaddr[3]  = 0x55;
    dwDev.hwaddr[4]  = 0x77;
    dwDev.hwaddr[5]  = 0x88;

    dwDev.magic_no     = NETDEV_MAGIC;
    dwDev.if_hostname  = "SylixOS_Dw";
    dwDev.init_flags   = NETDEV_INIT_LOAD_PARAM |         /*  net_dev 初始化时选项    */
                         NETDEV_INIT_LOAD_DNS   |
                         NETDEV_INIT_IPV6_AUTOCFG;

    dwDev.chksum_flags = NETDEV_CHKSUM_ENABLE_ALL;
    dwDev.net_type     = NETDEV_TYPE_ETHERNET;
    dwDev.speed        = 0;
    dwDev.mtu          = 1500;
    dwDev.drv          = &netFuns;

    ret = netdev_add(&dwDev,ip,netmask,gw,IFF_UP | IFF_BROADCAST | IFF_RUNNING);
    if(ret < 0)
    {
        printk("dev add error \n\r");
    }
}

/*
 *  SylixOS call module_init() and module_exit() automatically.
 */
int module_init (void)
{
    dwCreate();
    printk("hello_module init!\n");

    return 0;
}

void module_exit (void)
{
    printk("hello_module exit!\n");
}

/*
 *  module export symbols
 */
LW_SYMBOL_EXPORT void hello_module_func (void)
{
    printk("hello_module_func() run!\n");
}

编译,上传并加载ko文件,使用ifconfig 命令可以发现多出一个网络设备:

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
很抱歉,我无法直接提供SylixOS下的完整驱动代码,因为SylixOS是一个商业操作系统,它的代码并不是开源的。SylixOS提供了丰富的驱动支持和API,但具体的驱动代码需要根据硬件平台和设备类型进行开发。 如果你需要编写SylixOS下的驱动代码,可以参考SylixOS提供的开发文档和示例代码。以下是一个简单的驱动代码示例,用于演示如何在SylixOS下编写一个LED驱动程序: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sylixos.h> #define LED_DEVICE "/dev/led" int main(void) { int fd; int led_state = 0; // 打开LED设备文件 fd = open(LED_DEVICE, O_RDWR); if (fd < 0) { printf("Failed to open LED device\n"); return -1; } while (1) { // 切换LED状态 led_state = !led_state; // 控制LED灯亮或灭 if (ioctl(fd, led_state ? 1 : 0, NULL) < 0) { printf("Failed to control LED\n"); break; } // 延时一段时间 sleep(1); } // 关闭LED设备文件 close(fd); return 0; } ``` 上述示例代码中,假设存在一个名为"/dev/led"的LED设备文件,可以通过打开设备文件并使用ioctl函数来控制LED的亮灭状态。在while循环中,通过切换led_state的值来控制LED的状态,并使用sleep函数进行延时。 请注意,以上代码仅作为示例,实际的驱动开发需要根据硬件平台和设备类型进行适配和实现。确保你按照SylixOS开发文档和API进行驱动开发

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值