industrialNETworXnetx

| 26.05.2008 | 17:28 | 15 replies

UDP packets via lwIP-protocollstack

Hi,

i'm trying to send a udp packet via the lwIP using following code.

#include "lwip/udp.h"
#include 

struct pbuf *p;

/*****************************************************************************
send p via udp connection
*****************************************************************************/
int udp_conn(void)
{


struct udp_pcb* pcb;
pcb = udp_new();
udp_bind(pcb, IP_ADDR_LOCAL, 8002);
udp_connect(pcb, IP_ADDR_REMOTE, 8002);

udp_send(pcb, p);

udp_disconnect(pcb);
return 0;
}

I assume that the missfunction is caused by the pbuf configuration. The description of udpsend in the rawapi an the pbuf struct:

#define PBUF_FLAG_RAM   0x00U    /* Flags that pbuf data is stored in RAM */
#define PBUF_FLAG_ROM   0x01U    /* Flags that pbuf data is stored in ROM */
#define PBUF_FLAG_POOL  0x02U    /* Flags that the pbuf comes from the pbuf pool */
#define PBUF_FLAG_REF   0x04U    /* Flags thet the pbuf payload refers to RAM */

/** indicates this packet was broadcast on the link */
#define PBUF_FLAG_LINK_BROADCAST 0x80U

struct pbuf {
/** next pbuf in singly linked pbuf chain */
struct pbuf *next;

/** pointer to the actual data in the buffer */
void *payload;

/**
* total length of this buffer and all next buffers in chain
* belonging to the same packet.
*
* For non-queue packet chains this is the invariant:
* p->tot_len == p->len + (p->next? p->next->tot_len: 0)
*/
u16_t tot_len;

/** length of this buffer */
u16_t len;

/** flags telling the type of pbuf, see PBUF_FLAG_ */
u16_t flags;

/**
* the reference count always equals the number of pointers
* that refer to this pbuf. This can be pointers from an application,
* the stack itself, or pbuf->next pointers from a chain.
*/
u16_t ref;

};

Quote:
- err_t udp_send(struct udp_pcb *pcb, struct pbuf *p)

Sends the pbuf p. The pbuf is not deallocated.

Its possible to compile, build and run the programm. the problem is that it stops at the udp_send call. Would be thankfull for any help.

greetz

hilscherlovers

| 26.05.2008 | 17:50

Hello hilscherlovers,

it is not to help you, but ask you help.

please check the topic about " how to start my own Programm" before yours and tell me if you have a idea...

thanks

Fchaleun

Burkhard Ilsen

Burkhard Ilsen

Hilscher GmbH

| 27.05.2008 | 17:02

Hi

At first, which version of lwIP do you use?
Is it the Hilscher distribution with netX/rcX support?

Your code looks ok so far.
Please post more code of your pbuf configuration.
How do you allocate it (pbuf_alloc(...)), how do you fill it with data?

Greetings,
Burkhard

| 30.05.2008 | 12:36

lwip version: 1.0
netx500, ARM cpu
os: rcx

pbuf memory allocation didnt work, so i tried to send a empty buffer.

buffer =
pbuf_alloc(TRANSPORT, 1024, RAM);
// transport flag for tcp , RAM for dynamic manipulation ability 

do you know how to fill it properly or with zeros?

greetz

| 30.05.2008 | 14:11

thats the way it works:

    struct ip_addr ipaddr;
    struct udp_pcb *pcb;
    struct pbuf *pb;
    char str[512]="Testdaten Matze Dave Simon";
    IP4_ADDR(&ipaddr, 141,28,33,20);
  
    pcb = udp_new();
    udp_bind(pcb, IP_ADDR_ANY, 5555);
    
    udp_connect(pcb, &ipaddr, 5555);
  
    pb = pbuf_alloc(PBUF_TRANSPORT, 512, PBUF_REF);
    pb->payload = str;
    pb->len = pb->tot_len = 512;


udp_send(pcb, pb);

pbuf_free(pb);
udp_remove(pcb);

next problem: it only works if you call it in the callbackmethod. i tried to call it from the startupparameter of the entertask in the rcxconfig but the udp connection remains dead.

any ideas?

greetz

Burkhard Ilsen

Burkhard Ilsen

Hilscher GmbH

| 30.05.2008 | 15:12

Quote:
thats the way it works

Yes, you made it!

Quote:
i tried to call it from the startupparameter of the entertask in the rcxconfig

How do you call the method from the startup parameter? The code of your rcX task configuration may help...

| 02.06.2008 | 11:50

enter task configuration, all parts of rcX_Config:

STATIC CONST FAR LWIP_TASK_CONFIG_T tLwipConfig = {
  &atLwipLinkIf[0],    /* pointer to link port config struct array */
  1,                   /* number of ports in the array */
  &atLwipNetIf[0],     /* network interface config */
  1,                   /* not supported / must be 1 (future use of network interface aliases) */
#ifdef CB_RCX
  initApplication,     /* initialize application layer */
#else
  NULL,
#endif
  NULL,                /* argument for application init */
  lwipFatalCallback    /* error callback routine */
};

/* Static Task Parameter List */
STATIC CONST FAR RX_STATIC_TASK_T FAR atrXStaticTasks[] = {
{
"LWIP_INIT", /* Set Identification */
TSK_PRIO_12, TSK_TOK_12, /* Set Priority,and Token ID*/
0, /* Set Instance to 0 */
&auTskStack_Lwip[0], /* Pointer to Stack */
TSK_STACK_SIZE_LWIP, /* Size of Task Stack */
0, /* Threshold to maximum possible value */
RX_TASK_AUTO_START, /* Start task automatically */
TaskEnter_Lwip, /* Task function to schedule*/
NULL, /* Function called when Task will be deleted */
(UINT32)&tLwipConfig, /* Startup Parameter */
{0,0,0,0,0,0,0,0} /* Reserved Region */
}
};

initApplication calls the user application:

int myApplication(void);
INT initApplication(VOID FAR* pvArg) {
  return myApplication();
}

myApplication should simply send a udp packet doing something like that:

int myApplication(void ){
    struct ip_addr ipaddr;
    struct udp_pcb *pcb;
    struct pbuf *pb;
    char str[512]="Testdaten Matze Dave Simon";
    IP4_ADDR(&ipaddr, 141,28,33,20);
 
    pcb = udp_new();
    udp_bind(pcb, IP_ADDR_ANY, 5555);
   
    udp_connect(pcb, &ipaddr, 5555);
 
    pb = pbuf_alloc(PBUF_TRANSPORT, 512, PBUF_REF);
    pb->payload = str;
    pb->len = pb->tot_len = 512;


udp_send(pcb, pb);

pbuf_free(pb);
udp_remove(pcb);
return 0;
}

the main calls rX_SysEnterKernelExt(&trXEnterKernelParam); with atrXStaticTasks embedded in EnterKernelParam to run the kernel.

it worked when i put the code from myApplication into the callbackmethod of tcp_rcv(pcb, httpd_cb_tcpRecv) of the http webserver example but its irreproducable for me why.

greetz

Burkhard Ilsen

Burkhard Ilsen

Hilscher GmbH

| 02.06.2008 | 13:07

The application initialization method "myApplication()" cannot "use" the stack in terms of sending or receiving data from the network. The reason is that the initialization of the stack is not finished when this method is called.
The initialization method is for the registration of your application callback functions. If you want to send any "I am here"- data you can use a timer controlled callback function or another application task.
I hope this helps.

| 02.06.2008 | 17:11

now I call talk_init() from initApplication using following code:

#include "rX_Includes.h"
#include "lwip/talk.h"
#include "lwip/udp.h"

int talk_init(void){
RX_HANDLE hMyTimer; /* timer handle */

rX_MemAllocateMemory(&hMyTimer,1024);
rX_TimCreateTimer(hMyTimer,TxTimer,sendUDP,RX_TIM_AUTO_RELOAD, 0,100);
return 0;
}

void CALLBACK TxTimer(void)
{
sendUDP();
}

void sendUDP(void){

struct ip_addr ipaddr;
struct udp_pcb *pcb;
struct pbuf *pb;
char str[512]="da bin ich!";
IP4_ADDR(&ipaddr, 141,28,33,21);

pcb = udp_new();
udp_bind(pcb, IP_ADDR_ANY, 5555);

udp_connect(pcb, &ipaddr, 5555);

pb = pbuf_alloc(PBUF_TRANSPORT, 512, PBUF_REF);
pb->payload = str;
pb->len = pb->tot_len = 512;


udp_send(pcb, pb);

pbuf_free(pb);
udp_remove(pcb);

}

I also tried:

#include "rX_Includes.h"
#include "lwip/talk.h"
#include "lwip/udp.h"

int talk_init(void){

static const abIdx [] = {1,5,6,9,10};

RX_HANDLE hMyTimer; /* timer handle */

rX_MemAllocateMemory(&hMyTimer,1024);
rX_TimCreateTimer(hMyTimer,TxTimer,&abIdx [3],RX_TIM_AUTO_RELOAD, 0,100);
return 0;
}

void CALLBACK TxTimer(void)
{
struct ip_addr ipaddr;
struct udp_pcb *pcb;
struct pbuf *pb;
char str[512]="da bin ich!";
IP4_ADDR(&ipaddr, 141,28,33,21);

pcb = udp_new();
udp_bind(pcb, IP_ADDR_ANY, 5555);

udp_connect(pcb, &ipaddr, 5555);

pb = pbuf_alloc(PBUF_TRANSPORT, 512, PBUF_REF);
pb->payload = str;
pb->len = pb->tot_len = 512;


udp_send(pcb, pb);

pbuf_free(pb);
udp_remove(pcb);
}

but neither worked ... :?
do you know when the initialization of the stack is finished? we would be happy to be able to run a ping without having the http-server startet.

greetz

| 02.06.2008 | 17:59

i just uploaded the originate http webserver example without any content in the http_init(); of the httpd.c

void http_init(void){
  return 0;
}

surprisingly, the board was still pingable. why is that? i'm confused a bit.

Burkhard Ilsen

Burkhard Ilsen

Hilscher GmbH

| 03.06.2008 | 09:41

After the initialization, the stack is running all its protocols. ICMP (Ping) is one of these protocols. HTTP is a layer 5 protocol and neither a part of the stack nor necessary for running ICMP. So you are ping-ing the stack, not the server.
http://en.wikipedia.org/wiki/TCP/IP_model

| 06.06.2008 | 13:21

Quote:
So you are ping-ing the stack, not the server.

yeah, i know but if the server doesnt run im not able to ping the stack because its not initialized completely. i'd like to know how i can do that. defining a callback method by the timer seems not to help.

| 06.06.2008 | 14:22

Initialization is done by the LwipTaskEnter but in the moment of wrong usage it dies.

Burkhard Ilsen

Burkhard Ilsen

Hilscher GmbH

| 09.06.2008 | 09:47

Hi,
the creation of the timer in talk_init() is incorrect.
Try the following code:

void sendUDP(void* pvIndex){

struct ip_addr ipaddr;
struct udp_pcb *pcb;
struct pbuf *pb;
char str[512]="da bin ich!";
IP4_ADDR(&ipaddr, 141,28,33,21);

pcb = udp_new();
udp_bind(pcb, IP_ADDR_ANY, 5555);

udp_connect(pcb, &ipaddr, 5555);

pb = pbuf_alloc(PBUF_TRANSPORT, 512, PBUF_REF);
pb->payload = str;
pb->len = pb->tot_len = 512;

udp_send(pcb, pb);

pbuf_free(pb);
udp_remove(pcb);
}

INT talk_init(void){
RX_HANDLE hMyTimer; /* timer handle */
RX_RESULT eRslt;

eRslt = rX_MemAllocateMemory(&hMyTimer,1024);
if( eRslt != RX_OK )
{
return -1;
}

eRslt = rX_TimCreateTimer(hMyTimer,sendUDP,NULL,RX_TIM_AUTO_RELOAD,100,2000);
if( eRslt != RX_OK )
{
rX_MemFreeMemory(hMyTimer);
return -2;
}

return 0;
}

| 11.06.2008 | 14:12

hey bilsen,

thanks a lot for your help, it now works with the timer and either with a second task for connecting.

greetz

hilscherlovers

| 11.06.2008 | 14:13

hey bilsen,

thanks a lot for your help, it now works with the timer and either with a second task for connecting.

greetz

hilscherlovers

Login