lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-users] lwip-2.0.2 + freertos 8.2.3 + ARM7


From: Angelus
Subject: [lwip-users] lwip-2.0.2 + freertos 8.2.3 + ARM7
Date: Wed, 10 May 2017 06:57:23 -0700 (MST)

Hello, I am using lwip 2.0.2 RAW API + freertos 8.2.3. I have to send a lot of data received by CAN to Ethernet. I receive CAN data in a CAN Interrupt and enque them here. In a 3ms task I periodically check the queue for new data and send them via tcp_write() and tcp_output(). It seems to work fine but after a few seconds I stuck into "tcp_write: pbufs on queue => at least one queue non-empty". if (pcb->snd_queuelen != 0) { LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty", pcb->unacked != NULL || pcb->unsent != NULL); } else { LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty", pcb->unacked == NULL && pcb->unsent == NULL); } I googled a lot and I read that this could be a thread problem. I don't know what I am doing wrong. I have been researching for month now, but cannot find the solution. In main() I am calling: void vStartEthernetTaskLauncher( unsigned portBASE_TYPE uxPriority ) { /* Spawn the Sentinel task. */ if(xTaskCreate(vStartEthernetTask, "ETHLAUNCH", configMINIMAL_STACK_SIZE, NULL, uxPriority, (xTaskHandle *)NULL) != pdPASS){ printf("Failed to create Monitor task\r\n"); } } which starts a init task: portTASK_FUNCTION(vStartEthernetTask, pvParameters) { /* Setup lwIP. */ prvlwIPInit(); #if (HTTP_USED == 1) /* Create the WEB server task. This uses the lwIP RTOS abstraction layer. */ /*sys_thread_new("WEB", vBasicWEBServer, (void *)NULL, lwipBASIC_WEB_SERVER_STACK_SIZE, lwipBASIC_WEB_SERVER_PRIORITY);*/ /* Initialize HTTP Server*/ //httpd_init(); //RAW-API #endif init_SET_TCP_server(); #if (TFTP_USED == 1) /* Create the TFTP server task. This uses the lwIP RTOS abstraction layer. */ sys_thread_new("TFTP", vBasicTFTPServer, (void *)NULL, lwipBASIC_TFTP_SERVER_STACK_SIZE, lwipBASIC_TFTP_SERVER_PRIORITY); #endif #if (SMTP_USED == 1) /* Create the SMTP Client task. This uses the lwIP RTOS abstraction layer. */ sys_thread_new("SMTP", vBasicSMTPClient, (void *)NULL, lwipBASIC_SMTP_CLIENT_STACK_SIZE, lwipBASIC_SMTP_CLIENT_PRIORITY); #endif /* Kill this task. */ vTaskDelete(NULL); } My task which checks for new queue entries and sends them is seen here: void CAN_TO_ETH_TASK(void *pvParameters) { ( void ) pvParameters; CANMSGOBJ can_tx_msgobj; uint32_t supersize = 0; uint32_t pdu_bytes = 0; char ucrecBuff[1460] = {0}; uint8_t number_of_pdus = 0; uint8_t returnvalue; uint8_t can_msg_size = 32; uint8_t headersize = 12; uint8_t queuecounter = 0; uint8_t fillup = 0; SET_PDU_t *pdu; portTickType xLastWakeTime; const portTickType xFrequency = CAN_TO_ETH_CYCLE_TIME_MS; xLastWakeTime = xTaskGetTickCount(); // struct pbuf* p_buf; err_t err, write_error, output_error; //------------------TASK----------------------- for(;;) { for(queuecounter = 0; queuecounter < NUM_ACTIVE_CAN_CHANNELS; queuecounter++) { output_error = ERR_OK; write_error = ERR_OK; number_of_pdus = 0; if(xQueueReceive(can_to_ether_q[queuecounter], &can_tx_msgobj, 0) == pdTRUE)// && tcp_active_pcbs != NULL) { if(tcp_active_pcbs != NULL) { returnvalue = pdTRUE; //As long there is sth. in the queue... while(returnvalue == pdTRUE && number_of_pdus < 46) { //create sending pdu pdu = &ucrecBuff[headersize+number_of_pdus*can_msg_size]; pdu->direction = can_tx_msgobj.Channel; pdu->errorCode = 0x00; pdu->sequenceCounter = 0x00; pdu->flags.all = 0x00; pdu->paramID = 0x26; pdu->data.can_payload.timestamp = xTaskGetTickCount(); pdu->data.can_payload.identifier = can_tx_msgobj.CANMSG.id; if(can_tx_msgobj.CANMSG.extended) pdu->data.can_payload.identifier |= 0x20000000; pdu->data.can_payload.typ1 = 0x00; pdu->data.can_payload.infoA = 0x00; pdu->data.can_payload.infoB = 0x00; pdu->data.can_payload.dlc = can_tx_msgobj.CANMSG.dlc; memcpy(pdu->data.can_payload.char_data, can_tx_msgobj.CANMSG.data, can_tx_msgobj.CANMSG.dlc); //fill up with 0. if(can_tx_msgobj.CANMSG.dlc < 8) { for(fillup = can_tx_msgobj.CANMSG.dlc; fillup < 8; fillup++) { pdu->data.can_payload.char_data[fillup] = 0x00; } } if(number_of_pdus <46-1) returnvalue = xQueueReceive(can_to_ether_q[queuecounter], &can_tx_msgobj, 0); number_of_pdus++; } //---------------------Writing part----------------------------------- pdu_bytes = number_of_pdus*can_msg_size; memcpy(&ucrecBuff[8], &pdu_bytes, sizeof(pdu_bytes)); supersize = headersize+number_of_pdus*can_msg_size; struct tcp_pcb *pcb = tcp_active_pcbs; bool foundflag = false; while(pcb != NULL) { //Only certain combinations of ports and CAN channels are valid if((pcb->local_port == PortCAN1 && can_tx_msgobj.Channel == CAN0)|| //5459 and CAN0 (pcb->local_port == PortCAN2 && can_tx_msgobj.Channel == CAN1)|| //5460 and CAN1 (pcb->local_port == PortCAN3 && can_tx_msgobj.Channel == CAN2)) //5461 and CAN2 { foundflag = true; //Check for sufficant sending buffer if(tcp_sndbuf(pcb) >= (supersize)) { pcb->flags |= (TF_NODELAY); write_error = tcp_write(pcb, ucrecBuff, supersize, TCP_WRITE_FLAG_COPY); System.led.cBlinkData += 1; output_error = tcp_output(pcb); } else if(tcp_sndbuf(pcb) < (supersize)) { set_SystemStatus(SYSTEM_WARNING, 17); System.led.cBlinkError += 2; } } //Pointer to next protocol control block pcb = pcb->next; } if(foundflag == false || write_error != ERR_OK || output_error != ERR_OK) { set_SystemStatus(SYSTEM_ERROR, 7); System.led.cBlinkError += 2; } //---------------------------------------------------------------------- } //end if //No tcp connection found else if (tcp_active_pcbs == NULL) { set_SystemStatus(SYSTEM_WARNING, 24); System.led.cBlinkError += 2; //Element im Queue jedoch keine aktive Verbindung } } //end if } //end user for vTaskDelayUntil(&xLastWakeTime, xFrequency); //Pause //---------------------------------------------------------------------------------------------------------------------- } //end for } My lwipopts are the following: /* * lwipopts.h * * Created: 30.03.2017 11:11:16 * Author: motz.werner */ #ifndef LWIPOPTS_H_ #define LWIPOPTS_H_ //#include "conf_lwip_threads.h" #include "lwip/debug.h" #include "conf_tasks.h" /** * NO_SYS==1: Provides VERY minimal functionality. Otherwise, * use lwIP facilities. * Uses Raw API only. */ #define NO_SYS 0 #define LWIP_RAW 0 /* These are not available when using "NO_SYS" */ #define LWIP_NETCONN 0 #define LWIP_SOCKET 0 /* Define default values for unconfigured parameters. */ #define LWIP_NOASSERT 0 /* To suppress some errors for now (no debug output) */ #define LWIP_DEBUG 0 /* These two control is reclaimer functions should be compiled * in. Should always be turned on (1). */ #define MEM_RECLAIM 1 #define MEMP_RECLAIM 1 /* Platform specific locking */ /* * enable SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection * for certain critical regions during buffer allocation, deallocation and memory * allocation and deallocation. */ #define SYS_LIGHTWEIGHT_PROT 1 /* ---------- Memory options ---------- */ /* MEM_ALIGNMENT: should be set to the alignment of the CPU for which * lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2 * byte alignment -> define MEM_ALIGNMENT to 2. */ #define MEM_ALIGNMENT 4 /* MEM_SIZE: the size of the heap memory. If the application will send * a lot of data that needs to be copied, this should be set high. */ #define MEM_SIZE 8 * 1024 /* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application * sends a lot of data out of ROM (or other static memory), this * should be set high. */ #define MEMP_NUM_PBUF 6 /* Number of raw connection PCBs */ #define MEMP_NUM_RAW_PCB 5//1 <----- Hier geändert /* ---------- UDP options ---------- */ #define LWIP_UDP 1 #define UDP_TTL 255 /* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One * per active UDP "connection". */ /* required by DHCP (because DNS is used) */ #define MEMP_NUM_UDP_PCB 1 #if (TFTP_USED == 1) /* one PCB for DHCP (DNS used), one for TFTP */ #undef MEMP_NUM_UDP_PCB #define MEMP_NUM_UDP_PCB 2 #endif /* MEMP_NUM_TCP_PCB: the number of simultaneously active TCP connections. */ #define MEMP_NUM_TCP_PCB 8//2 /* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. */ #define MEMP_NUM_TCP_PCB_LISTEN 8//1 /* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. */ #define MEMP_NUM_TCP_SEG 48 //8 //-------------------- /* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. */ #define MEMP_NUM_SYS_TIMEOUT 6 /* The following four are used only with the sequential API and can be * set to 0 if the application only will use the raw API. */ /* MEMP_NUM_NETBUF: the number of struct netbufs. */ #define MEMP_NUM_NETBUF 8//3 /* MEMP_NUM_NETCONN: the number of struct netconns. */ #define MEMP_NUM_NETCONN 8//4 /* ---------- Pbuf options ---------- */ /* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ #define PBUF_POOL_SIZE 8 /* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ #define PBUF_POOL_BUFSIZE 2048//3000//500 //!!!!!!!!!!!!!!!!!!!!!!!! /** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure * alignment of payload after that header. Since the header is 14 bytes long, * without this padding e.g. addresses in the IP header will not be aligned * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms. */ #define ETH_PAD_SIZE 0 /* PBUF_LINK_HLEN: the number of bytes that should be allocated for a * link level header. */ #define PBUF_LINK_HLEN (16 + ETH_PAD_SIZE) /* ---------- TCP options ---------- */ #define LWIP_TCP 1 #define TCP_TTL 255 /* TCP receive window. */ #define TCP_WND 4 * TCP_MSS//3000 <------ Hier geändert /* Controls if TCP should queue segments that arrive out of * order. Define to 0 if your device is low on memory. */ #define TCP_QUEUE_OOSEQ 1 /* TCP Maximum segment size. */ #define TCP_MSS 1460 /* TCP sender buffer space (bytes). */ #define TCP_SND_BUF 16*TCP_MSS /* TCP sender buffer space (pbufs). This must be at least = 2 * TCP_SND_BUF/TCP_MSS for things to work. */ #define TCP_SND_QUEUELEN 48//(TCP_SND_BUF/TCP_MSS)*2// ((6 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) <-----Hier geändert war 16 /* Maximum number of retransmissions of data segments. */ #define TCP_MAXRTX 12 /* Maximum number of retransmissions of SYN segments. */ #define TCP_SYNMAXRTX 4 /** * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed * to sys_mbox_new() when the recvmbox is created. */ #define DEFAULT_RAW_RECVMBOX_SIZE 6 /** * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed * to sys_mbox_new() when the recvmbox is created. */ #define DEFAULT_UDP_RECVMBOX_SIZE 6 /** * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed * to sys_mbox_new() when the recvmbox is created. */ #define DEFAULT_TCP_RECVMBOX_SIZE 6 /** * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. * The queue size value itself is platform-dependent, but is passed to * sys_mbox_new() when the acceptmbox is created. */ #define DEFAULT_ACCEPTMBOX_SIZE 6 /* ---------- ARP options ---------- */ #define ARP_TABLE_SIZE 10 #define ARP_QUEUEING 0 /* ---------- IP options ---------- */ /* Define IP_FORWARD to 1 if you wish to have the ability to forward * IP packets across network interfaces. If you are going to run lwIP * on a device with only one network interface, define this to 0. */ #define IP_FORWARD 0 /* If defined to 1, IP options are allowed (but not parsed). If * defined to 0, all packets with IP options are dropped. */ #define IP_OPTIONS 1 /* ---------- ICMP options ---------- */ #define ICMP_TTL 255 /* ---------- DHCP options ---------- */ /* Define LWIP_DHCP to 1 if you want DHCP configuration of * interfaces. DHCP is not implemented in lwIP 0.5.1, however, so * turning this on does currently not work. */ #define LWIP_DHCP 1 #ifdef LWIP_DHCP //#define DHCP_USED #endif /* 1 if you want to do an ARP check on the offered address * (recommended). */ /* #define DHCP_DOES_ARP_CHECK 1 */ /* * ------------------------------------ * ---------- Thread options ---------- * ------------------------------------ */ /** * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. */ #define TCPIP_THREAD_NAME "TCP/IP" /** * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. * The stack size value itself is platform-dependent, but is passed to * sys_thread_new() when the thread is created. */ #define TCPIP_THREAD_STACKSIZE lwipINTERFACE_STACK_SIZE /** * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. * The priority value itself is platform-dependent, but is passed to * sys_thread_new() when the thread is created. */ #define TCPIP_THREAD_PRIO lwipINTERFACE_TASK_PRIORITY /** * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages * The queue size value itself is platform-dependent, but is passed to * sys_mbox_new() when tcpip_init is called. */ #define TCPIP_MBOX_SIZE 6 /** * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread. */ #define SLIPIF_THREAD_NAME "slipif" /** * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread. * The stack size value itself is platform-dependent, but is passed to * sys_thread_new() when the thread is created. */ #define SLIPIF_THREAD_STACKSIZE configMINIMAL_STACK_SIZE /** * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread. * The priority value itself is platform-dependent, but is passed to * sys_thread_new() when the thread is created. */ #define SLIPIF_THREAD_PRIO 1 /** * PPP_THREAD_NAME: The name assigned to the pppMain thread. */ #define PPP_THREAD_NAME "pppInputThread" /** * PPP_THREAD_STACKSIZE: The stack size used by the pppMain thread. * The stack size value itself is platform-dependent, but is passed to * sys_thread_new() when the thread is created. */ #define PPP_THREAD_STACKSIZE configMINIMAL_STACK_SIZE /** * PPP_THREAD_PRIO: The priority assigned to the pppMain thread. * The priority value itself is platform-dependent, but is passed to * sys_thread_new() when the thread is created. */ #define PPP_THREAD_PRIO 1 /** * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread. */ #define DEFAULT_THREAD_NAME "lwIP" /** * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. * The stack size value itself is platform-dependent, but is passed to * sys_thread_new() when the thread is created. */ #define DEFAULT_THREAD_STACKSIZE configMINIMAL_STACK_SIZE /** * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. * The priority value itself is platform-dependent, but is passed to * sys_thread_new() when the thread is created. */ #define DEFAULT_THREAD_PRIO 1 #define LWIP_NETIF_STATUS_CALLBACK 1 /* ---------- Statistics options ---------- */ #define LWIP_STATS 1 #define LWIP_STATS_DISPLAY 1 #if LWIP_STATS #define LINK_STATS 1 #define IP_STATS 1 #define ICMP_STATS 1 #define UDP_STATS 1 #define TCP_STATS 1 #define MEM_STATS 1 #define MEMP_STATS 1 #define PBUF_STATS 1 #define SYS_STATS 1 #endif /* STATS */ /* ---------- Lwip Debug options ---------- */ //LWIP_DBG_ON #define DBG_TYPES_ON 0xff #define ETHARP_DEBUG LWIP_DBG_OFF #define NETIF_DEBUG LWIP_DBG_OFF//LWIP_DBG_ON #define PBUF_DEBUG LWIP_DBG_OFF//LWIP_DBG_ON #define API_LIB_DEBUG LWIP_DBG_OFF #define API_MSG_DEBUG LWIP_DBG_OFF//LWIP_DBG_ON #define SOCKETS_DEBUG LWIP_DBG_OFF #define ICMP_DEBUG LWIP_DBG_OFF #define INET_DEBUG LWIP_DBG_OFF #define IP_DEBUG LWIP_DBG_OFF #define IP_REASS_DEBUG LWIP_DBG_OFF #define RAW_DEBUG LWIP_DBG_OFF #define MEM_DEBUG LWIP_DBG_OFF #define MEMP_DEBUG LWIP_DBG_OFF #define SYS_DEBUG LWIP_DBG_OFF #define TCP_DEBUG LWIP_DBG_OFF//LWIP_DBG_ON #define TCP_INPUT_DEBUG LWIP_DBG_OFF #define TCP_FR_DEBUG LWIP_DBG_OFF #define TCP_RTO_DEBUG LWIP_DBG_OFF #define TCP_CWND_DEBUG LWIP_DBG_OFF #define TCP_WND_DEBUG LWIP_DBG_OFF #define TCP_OUTPUT_DEBUG LWIP_DBG_OFF #define TCP_RST_DEBUG LWIP_DBG_OFF #define TCP_QLEN_DEBUG LWIP_DBG_OFF #define UDP_DEBUG LWIP_DBG_OFF #define TCPIP_DEBUG LWIP_DBG_OFF #define DBG_MIN_LEVEL LWIP_DBG_LEVEL_SEVERE /* \note For a list of all possible lwIP configurations, check * http://lwip.wikia.com/wiki/Lwipopts.h */ //***************************************************************************** // // ---------- httpd options ---------- // //***************************************************************************** #define INCLUDE_HTTPD_SSI #define INCLUDE_HTTPD_CGI #define LWIP_HTTPD_DYNAMIC_HEADERS #endif /* LWIPOPTS_H_ */ I hope somebody can help me.

View this message in context: lwip-2.0.2 + freertos 8.2.3 + ARM7
Sent from the lwip-users mailing list archive at Nabble.com.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]