我将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");
}
}