Hi,
i'm trying to send a udp packet via the lwIP using following code.
#include "lwip/udp.h" #includestruct 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 0x80Ustruct 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;
};
- 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
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
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
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
thats the way it works
i tried to call it from the startupparameter of the entertask in the rcxconfig
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
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.
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
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.
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
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.
Initialization is done by the LwipTaskEnter but in the moment of wrong usage it dies.
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;
}
hey bilsen,
thanks a lot for your help, it now works with the timer and either with a second task for connecting.
greetz
hilscherlovers
hey bilsen,
thanks a lot for your help, it now works with the timer and either with a second task for connecting.
greetz
hilscherlovers
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