Hello,
I'm trying to send UDP-packets from an LM3S9B96 to the PC. But every time when I call the Library-function "udp_get_buf(len);" I get an Hardfault-IRQ. Receiving the UDP-Packets from the PC is no problem, so my initialization from the UDP should be ok. Any ideas what could be wrong?
Thank you.
Regards, Mike
Where are you calling the UdpSend from?
Is it from within the callback?
Even if I comment out my udpsend I get an hardfault. But then all the ARP-stuff is done again.
Where are you calling udp_get_buf(len); from ?
In the same function as the udpsend(). I tried both: to call that function from the callback-function and also to call it from my udp_task but the effect was the same.
Here are the important parts of my code:
int main (void) { InitDevice(); init_TcpNet(); /* Initialize UDP Socket and start listening */ ucMainUDP_socket = udp_get_socket (0, UDP_OPT_SEND_CS | UDP_OPT_CHK_CS, UDP_callback); if (ucMainUDP_socket != 0) { udp_open (ucMainUDP_socket, UDP_PORT_NUM); } //---RTOS-Setup os_sys_init_prio(InitTask,250); // init RTOS with 'InitTask' as start-Task and prio of 250 } __task void InitTask(void) { // start 'UDPTask' with an priority of 100 tID_UDPTask = os_tsk_create(UDPTask, 100); // start 'Timer' tID_TimerTask = os_tsk_create(tick_timer, 100); // we do not need 'InitTask' anymore os_tsk_delete_self(); } __task void UDPTask(void) { while(1) { main_TcpNet(); os_tsk_pass (); } } __task void tick_timer (void) { os_itv_set (10); while (1) { os_itv_wait (); /* Timer tick every 100 ms */ timer_tick (); } } unsigned short UDP_callback (unsigned char soc, unsigned char *rip, unsigned short rport, unsigned char *buf, unsigned short len) { if (len < 10) return (0); if (soc != ucMainUDP_socket) { /* Check if this is the socket we are connected to */ return (0); } procrec(buf,len); return (0); } void procrec (U8 *buf, unsigned short len) { char udp_msg[]={"Hello World!"}; static U8 remip[] = {192,168,240,77}; U8 *sendbuf; U16 len1; len1 = strlen(udp_msg); if (ucMainUDP_socket != 0) { // sendbuf = udp_get_buf(13); // strcpy ((char*)sendbuf, udp_msg); // udp_send (ucMainUDP_socket, remip, 23456, sendbuf, len1); } return; }
Is there an evident mistake?
A response I once got from Keil Technical Support was this:
In general the rule is "Do not call any TCP net functions from the TCP callback function." This is self explaining.
I would suggest that (as a test) you change your callback function to set a flag on receipt of the UDP message and test the flag for the generation of a response (including the call to udp_get_buf) within your UDPTask loop.
This is (fundamentally) what I do in my code.
Ok. I set a flag. But it crashes when I leave the callback-function. I tried to do single-stepping and realized that after the callback I jump to the function: void int_disable_eth (void) and in the following I get the fault. I think that there is basically an other problem as the call to udp_get_buf.
Thank you all for your help! Finally I found the problem: my task didn't run in privileged mode! Now I can send UDP-data.
Hi Mike,
the remedy could be to run RTX in privilege mode or to modify int_enable_eth() and int_disable_eth() so that when they manipulate the NVIC they temporarily run in privileged mode.
I also had problems running TCPnet together with RTX on a Cortex M3. That was strange because I had always used that on ARM7s. Finally, I saw the very same crash as yours on int_disable_eth(), looked at the code inside and it flashed a light: the NVIC and the privileged mode!
I cannot say if your program has other problems, but on a project of mine which successfully uses TCPnet and RTX in protected mode on a CM3, if I turn protected mode off the program crashes.
Regards, Marco.
OK... I was late.
The important thing however, is that you solved your problem.
Cheers, Marco.
Thanks for mentioning the solution.
I haven't (yet) had the chance to use the Cortex-M3. Our projects have been on ARM7 and ARM9 and I've never needed to do anything special with regards to the privilege mode.
I'll write myself a reminder for the future.