Moin Moin, ich möchte gerne mein XMC4500 relax kit per Ethernet mit einem Messinstrument verbinden. klappt soweit auch ganz gut.. Das Problem ist nur, wenn ich die Verbindung aufbaue und der laser bestätigt mit dem ersten ack, macht das Board danach nichts mehr. Quellcode befindet sich unten und die wireshark datei im Anhang.. Vielen dank für mögliche Lösungsansätze #include <DAVE3.h> //Declarations from DAVE3 Code Generation (includes SFR declaration) #include <string.h> /*Test LED */ #define LED1 IO004_Handle0 void delay(long unsigned int i) { while(i--) { __NOP(); } } enum { LASER_STATUS_UNKNOWN = 0, LASER_STATUS_CONNECTING, LASER_STATUS_CONNECTED, LASER_STATUS_VV_SENT, LASER_STATUS_VV_RECEIVED, LASER_STATUS_DISTANCE_QUERY_SENT, LASER_STATUS_DISTANCE_QUERY_RECEIVED, LASER_STATUS_CONNECTION_CLOSED }; int laser_status = LASER_STATUS_UNKNOWN; // zentrale stelle un state-changes im programm-fluss zu kontrollieren u. evtl. zu dokumentieren void setLaserStatus(int new_state) { int old_state = new_state; if (old_state != new_state) { // toggle LED ? // printf ("Laser state change %d -> %d\n", old_state, new_state); laser_status = new_state; } } // send query-string to TCP connection err_t sendLaserQuery(struct tcp_pcb * tpcb, char * laserQuery) { err_t error; struct pbuf *pb; int queryLen; int bufspace = tcp_sndbuf(tpcb); if (bufspace < strlen(laserQuery)) { // printf ("TCP sndbuf insufficient space (%d)\n", bufspace); tcp_close(tpcb); return ERR_MEM; } queryLen = strlen(laserQuery); pb = pbuf_alloc(PBUF_TRANSPORT, queryLen, PBUF_REF); memcpy(pb->payload, laserQuery, queryLen); pb->len = pb->tot_len = queryLen; // write data to TCP socket error = tcp_write(tpcb, pb->payload, pb->len, queryLen); if (error != ERR_OK) { return error; } // force data to be sent out error = tcp_output(tpcb); if (error != ERR_OK) { return error; } return ERR_OK; } // called by lwip to inidicate TCP connection is established (3way handshake is SYN, SYN-ACK, ACK, ...) err_t laserConnect(void * arg, struct tcp_pcb * tpcb, err_t err) { err_t error; setLaserStatus(LASER_STATUS_CONNECTED); error = sendLaserQuery(tpcb, "VV\r\n"); if (error == ERR_OK) { setLaserStatus(LASER_STATUS_VV_SENT); } return error; } // called by lwip to inidicate incoming laser data err_t laserReceive(void * arg, struct tcp_pcb * tpcb, struct pbuf * p, err_t err) { err_t error = ERR_OK; switch (laser_status) { case LASER_STATUS_VV_SENT: // @TODO parse/analyse/display VV info (p->payload / p->len) // send distance query error = sendLaserQuery(tpcb, "WTF-DD-ETC-PP\r\n"); if (error == ERR_OK) { setLaserStatus(LASER_STATUS_DISTANCE_QUERY_SENT); } break; case LASER_STATUS_DISTANCE_QUERY_SENT: // @TODO parse/analyse/display/store Distance info (p->payload / p->len) // @TODO set timer to send text query, or close connection /* error = sendLaserQuery(tpcb, "WTF-DD-ETC-PP\r\n"); if (error == ERR_OK) { setlaserStatus(LASER_STATUS_DISTANCE_QUERY_SEND); } */ break; } // mark data as process aka disposable by lwip tcp_recved(tpcb, p->tot_len); return error; } // callback to poll laser tcp connection err_t laserPoll(void * arg, struct tcp_pcb * tpcb) { // @TODO close connection on idle connection // z.B: wenn der Laser einfach nicht mehr antwortet, etc... return ERR_OK; } // callback on tcp error void laserError(void * arg, err_t err) { // @TODO handle error? wtf! } // close tcp connection void closeLaserConnection(struct tcp_pcb *tpcb) { tcp_arg(tpcb, NULL); tcp_sent(tpcb, NULL); tcp_recv(tpcb, NULL); tcp_close(tpcb); setLaserStatus(LASER_STATUS_CONNECTION_CLOSED); } /* * - establish TCP connection * - register receive/poll/error callbacks */ struct tcp_pcb * laserInitTCP(struct ip_addr * laserIp, uint16_t laserPort) { err_t error; struct tcp_pcb * pcb = NULL; setLaserStatus(LASER_STATUS_CONNECTING); pcb = tcp_new(); error = tcp_bind(pcb, IP_ADDR_ANY, 55555); error = tcp_connect(pcb, laserIp, laserPort, laserConnect); tcp_recv(pcb, laserReceive); tcp_poll(pcb, laserPoll, 1); tcp_err(pcb, laserError); return pcb; } int main(void) { struct ip_addr laserIp; struct tcp_pcb * laser_pcb = NULL; // do it! ;) DAVE_Init(); lwIPStack_init(); // establish TCP connetion IP4_ADDR(&laserIp, 192,168,0,10); laser_pcb = laserInitTCP(&laserIp, 10940); while (laser_status != LASER_STATUS_CONNECTION_CLOSED) { // app still running, do idle in main task } return 0; }
Ich hab so das gefühl, dass eine leere main-loop hier falsch ist. LWIP benötigt sicher eine polling-funktion. Die rufst du nur einmal beim Initialisieren deines Sockets auf, aber sonst nicht mehr. Check das mal!
@Little Basdart
So jetzt habe ich das folgende geändert...
struct tcp_pcb * laserInitTCP(struct ip_addr * laserIp, uint16_t
laserPort)
{
err_t error;
struct tcp_pcb * pcb = NULL;
setLaserStatus(LASER_STATUS_CONNECTING);
pcb = tcp_new();
error = tcp_bind(pcb, IP_ADDR_ANY, 55555); // 'bind' brauchen wir
nicht, oder doch!?
error = tcp_connect(pcb, laserIp, laserPort, laserConnect);
tcp_recv(pcb, laserReceive);
while(laser_status != LASER_STATUS_VV_SENT)
{
tcp_poll(pcb, laserPoll, 1);
}
tcp_err(pcb, laserError);
}
meintest du das in der Art? hier pollt er jetzt so lange bis sich der
Laser_Status geändert hat und das VV gesendet wurden...
ich habe folgenden beispielcode gefunden:
int main(void)
{
/* configure Ethernet (GPIOs, clocks, MAC, DMA) */
ETH_BSP_Config();
/* Initilaize the LwIP stack */
LwIP_Init();
/* tcp echo server Init */
tcp_echoserver_init();
/* Infinite loop */
while (1)
{
/* check if any packet received */
if (ETH_CheckFrameReceived())
{
/* process received Ethernet packet */
LwIP_Pkt_Handle();
}
/* handle periodic timers for LwIP */
LwIP_Periodic_Handle(LocalTime);
}
}
das ist allerdings für ein anderes board.
Ich brauche etwas in der while schleie main funktion was dem lwIP stack
Porzessorzeit gibt damit dieser auch was macht.. weiß da einer wie das
auf dem XMC4500 geht?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.