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 + ARM7


From: Werner Motz
Subject: [lwip-users] lwip 2.0.2 + freertos + ARM7
Date: Wed, 10 May 2017 16:06:01 +0200

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.

 

 

 

 


reply via email to

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