STM32 LwIP netconn_write问题传输结构

时间:2019-12-09 18:31:28

标签: c tcp stm32 ethernet lwip

我将STM32F407Discovery板上的FreeRTOS的LwIP堆栈与TCP Client一起使用,并且有一台Linux计算机作为TCP Server。在通过struct EncoderData Encoder[2] API传输结构数组(例如netconn)时,我遇到了一个问题。

问题是,当我将struct数组的元素打印到串行终端(使用UART)时,正确显示了struct数组中存储的数据。但是,当我通过netconn套接字发送结构时,第一个结构的元素,即Encoder[0]被正确接收,而Encoder[1]被接收为全零。

服务器端的预期输出,

Encoder[0] ---> 0xAA 0x07 0x00 0x52 0x12 0xDC 0xAB 0xFA
Encoder[1] ---> 0xAA 0x07 0x01 0x52 0x42 0xBF 0xAA 0xFA

服务器端输出出现问题

Encoder[0] ---> 0xAA 0x07 0x00 0x52 0x12 0xDC 0xAB 0xFA
Encoder[1] ---> 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

下面,我同时共享服务器和客户端代码,如果您能帮助我确定问题的所在,我将不胜感激。

Server.c-Linux计算机

#define MAX  9 
#define PORT 8080 
#define SA struct sockaddr 

#define NUM_OF_ENCODERS  2
#define PREAMBLE         0xAA
#define LENGTH           0x07
#define CRC              0xFA

struct EncoderData {
    volatile uint8_t encoderID;
    volatile uint8_t byte0;
    volatile uint8_t byte1;
    volatile uint8_t byte2;
    volatile uint8_t byte3;
    volatile uint8_t byte4;
    volatile uint32_t singleTurnValue;
    volatile uint16_t multiTurnValue;
    volatile uint16_t prevMultiTurnValue;
    volatile uint8_t direction;
    volatile float angle;
};

struct EncoderData Encoder[NUM_OF_ENCODERS];

// This function is called inside int main() 
void func(int sockfd) 
{ 
    uint8_t buff[MAX]; 
    uint32_t singleTurnValue = 0;
    float angle = 0.0;
    uint8_t channel;
    uint8_t encoderID;

    // infinite loop to read data continuously
    for (;;) { 

        bzero(buff, MAX); 

        // read the message from client and copy it in buffer 
        read(sockfd, buff, sizeof(buff));

        if(buff[0] == PREAMBLE && buff[1] == LENGTH && buff[8] == CRC)
        {
            encoderID = buff[2];

            Encoder[encoderID].encoderID        = encoderID;
            Encoder[encoderID].byte0            = (uint8_t)buff[3];
            Encoder[encoderID].byte1            = (uint8_t)buff[4];
            Encoder[encoderID].byte2            = (uint8_t)buff[5];
            Encoder[encoderID].byte3            = (uint8_t)buff[6];
            Encoder[encoderID].byte4            = (uint8_t)buff[7];
            Encoder[encoderID].singleTurnValue  = (uint32_t)((buff[5] << 16)|(buff[6] << 8)|(buff[7]));
            Encoder[encoderID].multiTurnValue   = (uint16_t)((buff[3] << 8)|(buff[4]));
            //printf("%d\n", encoderID);
            bzero(buff, MAX);
        }

        // Here I print the struct elements, below printf shows data correctly
        printf("0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\t\t", 
                Encoder[0].encoderID, Encoder[0].byte0, Encoder[0].byte1,
                Encoder[0].byte2, Encoder[0].byte3, Encoder[0].byte4);

        // However below printf results in only zeroes
        printf("0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n", 
                Encoder[1].encoderID, Encoder[1].byte0, Encoder[1].byte1,
                Encoder[1].byte2, Encoder[1].byte3, Encoder[1].byte4);

    } 
} 

Client.c-STM32F407发现

#define NUM_OF_ENCODERS  2

struct EncoderData Encoder[NUM_OF_ENCODERS];

void Encoder_Process(void)
{   
    //float angle = 0.0;
    uint64_t encoderRawValue = 0;
    uint32_t singleTurnValue = 0;
    uint8_t channel = 0;

    for(channel = 0; channel < NUM_OF_ENCODERS; channel++)
    {
        selectChannel(channel);

        encoderRawValue = readEncoder();
        singleTurnValue = getSingleTurn(encoderRawValue);
        angle = calculateMotorAngle(singleTurnValue);

        Encoder[channel].preamble  = 0xAA;
        Encoder[channel].length    = 0x07;
        Encoder[channel].encoderID = channel;
        Encoder[channel].byte0     = (uint8_t)((encoderRawValue >> 32) & 0xFF);
        Encoder[channel].byte1     = (uint8_t)((encoderRawValue >> 24) & 0xFF);
        Encoder[channel].byte2     = (uint8_t)((encoderRawValue >> 16) & 0xFF);
        Encoder[channel].byte3     = (uint8_t)((encoderRawValue >> 8)  & 0xFF);
        Encoder[channel].byte4     = (uint8_t)((encoderRawValue     )  & 0xFF);
        Encoder[channel].crc       = 0xFA;
    }
}

// Convert Encoder struct into buffer
uint8_t* prepareEncoderData(struct EncoderData enc)
{
    static uint8_t buffer[9];

    memset(buffer, '\0', 9);

    buffer[0] = enc.preamble;
    buffer[1] = enc.length;
    buffer[2] = enc.encoderID;
    buffer[3] = enc.byte0;
    buffer[4] = enc.byte1;
    buffer[5] = enc.byte2;
    buffer[6] = enc.byte3;
    buffer[7] = enc.byte4;
    buffer[8] = enc.crc;

    return buffer;
}

static void tcp_client_netconn_thread(void *arg)
{ 
  struct netconn *conn; //, *newconn;
    struct ip_addr remoteipaddr, localipaddr;
  err_t err1, err2;
//  portCHAR pagehits[100] = {0};
    uint8_t channels;
    uint8_t *transmitBuffer;

    IP4_ADDR(&remoteipaddr, DEST_IP_ADDR0, DEST_IP_ADDR1, DEST_IP_ADDR2, DEST_IP_ADDR3);
    IP4_ADDR(&localipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);

  /* Create a new TCP connection handle */
  conn = netconn_new(NETCONN_TCP);

  if (conn!= NULL)
  {
    err1 = netconn_bind(conn, &localipaddr, PORT_NUMBER);
        err2 = netconn_connect(conn, &remoteipaddr, PORT_NUMBER);

    if (err1 == ERR_OK && err2 == ERR_OK)
    {
            printf("STM32F4 connected to the server!\n");

      while(1) 
      {

         for(channels = 0; channels < NUM_OF_ENCODERS; channels++)
         {
            Encoder_Process();
            transmitBuffer = prepareEncoderData(Encoder[channels]);
            netconn_write(conn, transmitBuffer, strlen((char*)transmitBuffer), NETCONN_COPY);

         }

        vTaskDelay(10);
        //netconn_delete(newconn);
      }
    }
    else
    {
      printf("can not bind netconn");
      printf("\terr code: %d", err1);
      printf("\terr code: %d\n", err2);
    }
  }
  else
  {
    printf("can not create netconn");
  }
}

0 个答案:

没有答案