Send UDP sockets with rtems with a M5234BCC

Joel Sherrill joel.sherrill at OARcorp.com
Thu Oct 22 15:16:51 UTC 2009


I think you missed the main point in my previous answer.  Your Init task
closes the socket and then returns.  When a Classic API task returns,
it is a fatal error.  The NIC driver tasks this never run.

At the bottom of Init do not fall out, add

while (1)
  rtems_task_wake_after(100)

While not something I would recommend for a real application,
that should let the driver tasks run and get your packets out.

And since Init() doesn't return, there won't be a fatal error.

--joel

Diego Sanz wrote:
> Like this is my first response in the mailing list of rtems, I hope 
> that I had done well.
>
> I have changed the init.c (the only code for my program) and the 
> result is the same(the program doesn't send anything). Then I have 
> introduce several "printfs" inside the driver code (of the network, 
> the file is network.c) then I can see, that when I call the function 
> rtems_bsdnet_initialize_network(), then the funcion makes calls to the 
> ioctl funcion, and the command that invoques doesn't exist. It is 
> obvious to think that if the creators of the RTEMS make a funcion that 
> invokes the initialization of the network driver, and the code of the 
> driver, at least they could have written, inside the switch of the 
> ioctl function, the minimal code that initialize the driver network.
>
> Obout the TTCP/IP STACK, I trust in the people that have design RTEMS.
>
> This is now the code in one unique task.  And after it is the part of 
> the network driver where I have introduce the printf's
>
>
>
> /*
>  *  $Id: init.c,v 1.6 2007/04/05 15:22:58 joel Exp $
>  */
>
> #include <bsp.h>
>
> #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
> #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
> #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
>
> #define CONFIGURE_EXECUTIVE_RAM_SIZE        (512*1024)
> #define CONFIGURE_MAXIMUM_SEMAPHORES        20
> #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES    20
> #define CONFIGURE_MAXIMUM_TASKS            20
>
> #define CONFIGURE_MICROSECONDS_PER_TICK    10000
> #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 50
> #define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
>
> #define CONFIGURE_INIT_TASK_STACK_SIZE    (10*1024)
> #define CONFIGURE_INIT_TASK_PRIORITY    50
> #define CONFIGURE_INIT_TASK_INITIAL_MODES (RTEMS_PREEMPT | \
>                                            RTEMS_NO_TIMESLICE | \
>                                            RTEMS_NO_ASR | \
>                                            RTEMS_INTERRUPT_LEVEL(0))
>
> #define CONFIGURE_INIT
> rtems_task Init(rtems_task_argument argument);
>
> #include <rtems/confdefs.h>
>
> #include <rtems/rtems_bsdnet.h>
> #include <rtems/error.h>
> #include <stdio.h>
> #include <stdarg.h>
> #include <stdlib.h>
> #include <string.h>
> #include <errno.h>
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include <net/if.h>
> #include <sys/ioctl.h>
> #include <sys/sockio.h>
>
> /*
>  * Network configuration
>  */
> //extern void rtems_bsdnet_loopattach();
> static struct rtems_bsdnet_ifconfig netdriver_config = {
>     //"lo0",                          /* name */
>    // (int (*)(struct rtems_bsdnet_ifconfig *, 
> int))rtems_bsdnet_loopattach, /* attach function */
>      RTEMS_BSP_NETWORK_DRIVER_NAME,
>      RTEMS_BSP_NETWORK_DRIVER_ATTACH,     
>      NULL,                           /* link to next interface */
>     "138.100.48.254",                    /* IP address */
>     "255.225.225.128",                    /* IP net mask */
>      NULL,
>      0,
> };
>
> struct rtems_bsdnet_config rtems_bsdnet_config = {
>     &netdriver_config,       /* Network interface */
>     NULL,                   /* Use fixed network configuration */
>     0,                      /* Default network task priority */
>     0,                      /* Default mbuf capacity */
>     0,                      /* Default mbuf cluster capacity */
>     "testSystem",           /* Host name */
>     "nowhere.com <http://nowhere.com>",          /* Domain name */
>     "138.100.48.129",            /* Gateway */
>     "138.100.48.253",            /* Log host */
>     {"127.0.0.1" },         /* Name server(s) */
>     {"127.0.0.1" },         /* NTP server(s) */
> };
>
> /*
>  * Thread-safe output routines
>  */
> static rtems_id printMutex;
> static void printSafe(const char *fmt, ...)
> {
>     va_list args;
>     va_start(args, fmt);
>     rtems_semaphore_obtain(printMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
>     vprintf(fmt, args);
>     rtems_semaphore_release(printMutex);
>     va_end(args);
> }
> #define printf printSafe
>
> rtems_task
> Init (rtems_task_argument ignored)
> {
>     int net_state=0;
>         int s;
>         struct sockaddr_in myAddr, farAddr,buffer;
>         struct sockaddr hola;
> //        char cbuf[]={"HOLA DIEGO TE HABLA 5235"};
>     char cbuf[1600];
>         int i;
>         int f, flags;
>         struct ifreq *device;   
>      struct ifconf data;
>          unsigned long int broadaddr=0;
>    
>     for (i=0;i<1600;i++)
>     {
>         cbuf[i]='r';
>     }
>     i=0;
>
>
>      printf("\n \"Network\" initializing! HI DIEGO\n");
>      net_state=rtems_bsdnet_initialize_network();
>     
>      printf("\n \"Network\" initialized! devuelve:%d\n",net_state);
>
>   
>  
>
>      data.ifc_len=sizeof(device);   
>      memset(data.ifc_buf,0,data.ifc_len);
>      flags = IFF_UP|IFF_RUNNING;
>      s=socket(AF_INET,SOCK_DGRAM,0);
>      if (s < 0)
>      {
>     printf("Can't create client socket: %s\n", strerror(errno));
>             return;
>      }
>   
> //rtems_bsdnet_ifconfig(RTEMS_BSP_NETWORK_DRIVER_NAME,SIO_RTEMS_SHOW_STATS, 
> &device);   
> //buffer=(struct sockaddr_in)device->ifr_ifru.ifru_broadaddr;
> /*     
>     broadaddr=(device->ifr_ifru.ifru_addr.sa_data[0])<<24;
>      broadaddr|=(device->ifr_ifru.ifru_addr.sa_data[1])<<16;
>      broadaddr|=(device->ifr_ifru.ifru_addr.sa_data[2])<<8;
>      broadaddr|=(device->ifr_ifru.ifru_addr.sa_data[3]);
> */   
> /*
>     printf("\name:%s",device->ifr_name);
>         printf("\n direccion de broadcast=%u  \n",broadaddr);
> */
>
>     memset(&myAddr, 0, sizeof myAddr);
>     myAddr.sin_family = AF_INET;
> //    myAddr.sin_port = htons(10100);
>     myAddr.sin_port = 10100;
>
>     myAddr.sin_addr.s_addr = inet_addr("138.100.48.254");
>     if (bind(s, (struct sockaddr *)&myAddr, sizeof myAddr) < 0)
>     {
>         printf("Can't bind socket: %s\n", strerror(errno));
>             goto close;
>        }
>         memset(&farAddr, 0, sizeof farAddr);
>     farAddr.sin_family = AF_INET;
> //    farAddr.sin_port=htons(10001);
>     farAddr.sin_port=10001;
>     farAddr.sin_addr.s_addr = inet_addr("138.100.48.253");
>    
>    
>     printf("\n sending to host\n ");
>     i=sendto(s,&cbuf,1600,0,(struct sockaddr*)&farAddr,sizeof(struct 
> sockaddr));
>
>     if (i>0)
>     {
>         printf("Enviado correctamente\nNumero de Bytes:%d\n",i);
>        
>     }
>     else
>     {
>         printf("Enviado Incorrectamente\n");
>     }
>
> //    rtems_bsdnet_show_inet_routes ();
> //     rtems_bsdnet_show_mbuf_stats ();
>     rtems_bsdnet_show_if_stats ();
>     rtems_bsdnet_show_ip_stats ();
> //    rtems_bsdnet_show_udp_stats ();
>   close:
>     printf("Client closing connection.\n");
>     if (close(s) < 0)
>     {
>                 printf("Can't close client task socket: %s\n", 
> strerror(errno));
>     }
> }
>
> /************************************************************/
>
> The part of the driver
>
>
> static int
> fec_ioctl(struct ifnet *ifp, ioctl_command_t command, caddr_t data)
> {
>     struct mcf5235_enet_struct *sc = ifp->if_softc;
>     int error = 0;
>   
>
>     switch (command) {
>         case SIOCGIFADDR:
>         case SIOCSIFADDR:
>         ether_ioctl(ifp, command, data);
>             printf("\nIOCTL SIOCSIFADDR & SIOCGIFADDR");
>             break;
>
>         case SIOCSIFFLAGS:
>             switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
>                 case IFF_RUNNING:
>                     fec_stop(sc);
>              printf("\nIOCTL SIOCSIFFLAGS1");
>                     break;
>
>                 case IFF_UP:
>                     fec_init(sc);
>             printf("\nIOCTL SIOCSIFFLAGS 2 f");
>                     break;
>
>                 case IFF_UP | IFF_RUNNING:
>                     fec_stop(sc);
>                     fec_init(sc);
>             printf("\nIOCTL SIOCSIFFLAGS3 ");
>                     break;
>
>                 default:
>             printf("\nIOCTL SIOCSIFFLAGS default");   
>                     break;
>             }
>         printf("\nIOCTL BREAK ");
>             break;
>
>         case SIO_RTEMS_SHOW_STATS:
>       //  printf("\nHA ENTRADO EN SHOW STATS\n");
>             enet_stats(sc);
>             break;
>
>             /*
>              * FIXME: All sorts of multicast commands need to be added 
> here!
>              */
>         default:
>         printf("\nIOCTL NO RESPONDE A PETICION");   
>             error = EINVAL;
>             break;
>     }
>     return error;
> }
>
> Then when I execute the program, I can see by console: WHen I call to 
> the rtems_bsdnet_initialize_function(); the next text .
> .
> .
>
>
> IOCTL SIOCSIFFLAGS 2 f
> IOCTL BREAK
> IOCTL SIOCSIFADDR & SIOCGIFADDR
> nIOCTL NO RESPONDE A PETICION
> .
> .
> .
>
> I hope that someone could tell me at least in wich *.c of the source 
> of rtems, it's the call to the driver to initialize hardware 
> configuration, if it s posible...
>
> Lot of thanks
>
> Diego
>
>   
>
>
>
>
>
>
>
>
>
> 2009/10/19 Joel Sherrill <joel.sherrill at oarcorp.com 
> <mailto:joel.sherrill at oarcorp.com>>
>
>     There may be other problems but the TCP/IP stack runs
>     as a set of tasks.  I do not see how the TCP/IP stack gets
>     to run at all in this example.  The Init task is highest
>     priority and not preemptible.  When the clientWorker()
>     does the open/write/close, it returns to Init() which falls
>     off the bottom of its task body.  This by definition is a fatal
>     error in the Classic API.
>
>     The driver itself may or may not work, but I am pretty sure
>     in the best of cases, in this example the driver task never
>     runs to try push the data out.
>
>     --joel
>
>     Diego Sanz wrote:
>
>         Hello
>          I am trying to send packets throw UDP sockets, on the board
>         M5234BCC whose microcontroller is mcf 5234 (coldfire), with RTEMS
>         The Examples that comes with RTEMS works perfectly, including
>         the loopback exaqmple.
>
>         Well The next code is the application that I am trying to make
>         but doesn't send anything throw the cable ( I see with the
>         commview program).
>
>         Could someone help me and tell me if is there some error?  Thanks!
>
>         The code:
>
>         /*
>          *  $Id: init.c,v 1.6 2007/04/05 15:22:58 joel Exp $
>          */
>
>         #include <bsp.h>
>
>         #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
>         #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
>         #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
>
>         #define CONFIGURE_EXECUTIVE_RAM_SIZE        (512*1024)
>         #define CONFIGURE_MAXIMUM_SEMAPHORES        20
>         #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES    20
>         #define CONFIGURE_MAXIMUM_TASKS            20
>
>         #define CONFIGURE_MICROSECONDS_PER_TICK    10000
>         #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 50
>         #define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
>
>         #define CONFIGURE_INIT_TASK_STACK_SIZE    (10*1024)
>         #define CONFIGURE_INIT_TASK_PRIORITY    50
>         #define CONFIGURE_INIT_TASK_INITIAL_MODES (RTEMS_PREEMPT | \
>                                                   RTEMS_NO_TIMESLICE | \
>                                                   RTEMS_NO_ASR | \
>                                                  
>         RTEMS_INTERRUPT_LEVEL(0))
>
>         #define CONFIGURE_INIT
>         rtems_task Init(rtems_task_argument argument);
>
>         #include <rtems/confdefs.h>
>
>         #include <rtems/rtems_bsdnet.h>
>         #include <rtems/error.h>
>         #include <stdio.h>
>         #include <stdarg.h>
>         #include <stdlib.h>
>         #include <string.h>
>         #include <errno.h>
>         #include <sys/socket.h>
>         #include <netinet/in.h>
>         #include <net/if.h>
>         #include <sys/ioctl.h>
>         #include <sys/sockio.h>
>
>         /*
>          * Network configuration
>          */
>         //extern void rtems_bsdnet_loopattach();
>         static struct rtems_bsdnet_ifconfig netdriver_config = {
>            //"lo0",                          /* name */
>           // (int (*)(struct rtems_bsdnet_ifconfig *,
>         int))rtems_bsdnet_loopattach, /* attach function */
>             RTEMS_BSP_NETWORK_DRIVER_NAME,
>             RTEMS_BSP_NETWORK_DRIVER_ATTACH,         NULL,            
>                       /* link to next interface */
>            "138.100.48.254",                    /* IP address */
>            "255.225.225.128",                    /* IP net mask */
>             NULL,
>             0,
>         };
>
>         struct rtems_bsdnet_config rtems_bsdnet_config = {
>            &netdriver_config,       /* Network interface */
>            NULL,                   /* Use fixed network configuration */
>            0,                      /* Default network task priority */
>            0,                      /* Default mbuf capacity */
>            0,                      /* Default mbuf cluster capacity */
>            "testSystem",           /* Host name */
>            "nowhere.com <http://nowhere.com> <http://nowhere.com>",  
>                /* Domain name */
>
>            "138.100.48.129",            /* Gateway */
>            "138.100.48.253",            /* Log host */
>            {"127.0.0.1" },         /* Name server(s) */
>            {"127.0.0.1" },         /* NTP server(s) */
>         };
>
>         /*
>          * Thread-safe output routines
>          */
>         static rtems_id printMutex;
>         static void printSafe(const char *fmt, ...)
>         {
>            va_list args;
>            va_start(args, fmt);
>            rtems_semaphore_obtain(printMutex, RTEMS_WAIT,
>         RTEMS_NO_TIMEOUT);
>            vprintf(fmt, args);
>            rtems_semaphore_release(printMutex);
>            va_end(args);
>         }
>         #define printf printSafe
>
>
>
>
>         /*
>          * The real part of the client
>          */
>         static rtems_task clientWorker(int arg)
>         {
>               int s;
>                struct sockaddr_in myAddr, farAddr,buffer;
>                struct sockaddr hola;
>                char cbuf[]={"HOLA DIEGO TE HABLA 5235"};
>                int i;
>                int f, flags;
>                struct ifreq *device;       struct ifconf data;
>                 unsigned long int broadaddr=0;
>                 data.ifc_len=sizeof(device);      
>         memset(data.ifc_buf,0,data.ifc_len);
>                     flags = IFF_UP|IFF_RUNNING;
>                    s=socket(AF_INET,SOCK_DGRAM,0);
>            if (s < 0)
>            {
>                printf("Can't create client socket: %s\n",
>         strerror(errno));
>                    return;
>            }
>         //SIOCSIFBRDADDR
>                printf("\nENTRA EN LA TAREA CLIENT WORKER\n");
>            //rtems_bsdnet_ifconfig(RTEMS_BSP_NETWORK_DRIVER_NAME,
>         SIOCGIFDSTADDR, &device);               //buffer=(struct
>         sockaddr_in)device->ifr_ifru.ifru_broadaddr;
>            
>                broadaddr=(device->ifr_ifru.ifru_addr.sa_data[0])<<24;
>             broadaddr|=(device->ifr_ifru.ifru_addr.sa_data[1])<<16;
>             broadaddr|=(device->ifr_ifru.ifru_addr.sa_data[2])<<8;
>             broadaddr|=(device->ifr_ifru.ifru_addr.sa_data[3]);
>                  /*
>            printf("\name:%s",device->ifr_name);
>                printf("\n direccion de broadcast=%u  \n",broadaddr);
>                */
>
>            memset(&myAddr, 0, sizeof myAddr);
>            myAddr.sin_family = AF_INET;
>         //    myAddr.sin_port = htons(10100);
>            myAddr.sin_port = 10100;
>            myAddr.sin_addr.s_addr = inet_addr("138.100.48.254");
>              if (bind(s, (struct sockaddr *)&myAddr, sizeof myAddr) < 0)
>            {
>                printf("Can't bind socket: %s\n", strerror(errno));
>                    goto close;
>               }
>                memset(&farAddr, 0, sizeof farAddr);
>            farAddr.sin_family = AF_INET;
>         //    farAddr.sin_port=htons(10001);
>            farAddr.sin_port=10001;
>            farAddr.sin_addr.s_addr = inet_addr("138.100.48.253");
>         /***************************************************************/
>            rtems_bsdnet_show_inet_routes ();
>         //     rtems_bsdnet_show_mbuf_stats ();
>         //    rtems_bsdnet_show_if_stats ();
>         //    rtems_bsdnet_show_ip_stats ();
>         //    rtems_bsdnet_show_udp_stats ();
>                printf("\n sending to host\n ");
>            i=sendto(s,&cbuf,25,0,(struct
>         sockaddr*)&farAddr,sizeof(struct sockaddr));
>              if (i>0)
>            {
>                printf("Enviado correctamente\n %d",i);
>                  }
>            else
>            {
>                printf("Enviado Incorrectamente\n");
>            }
>          close:
>            printf("Client closing connection.\n");
>            if (close(s) < 0)
>            {
>                        printf("Can't close client task socket: %s\n",
>         strerror(errno));
>            }
>         }
>
>
>
>
>         rtems_task
>         Init (rtems_task_argument ignored)
>         {
>            int net_state=0;
>            
>             printf("\"Network\" initializing! HI DIEGO\n");
>            net_state=rtems_bsdnet_initialize_network();
>            printf("\"Network\" initialized! %d\n",net_state);
>
>            printf("Try running client with no server present.\n");
>            printf("Should fail with `connection refused'.\n");
>            clientWorker(0);
>
>         }
>
>
>




More information about the users mailing list