Tool/software: TI-RTOS
I am trying to setup my Tiva to receive single byte packets over UDP. I have had some success: I can receive packets correctly. However, after 12 consecutive packets (1 byte per packet), I can no longer receive. Specifically, the fdSelect function hangs with no timeout, or times out if I give it one. I have pinpointed that it fdSelect calls fdPoll and that is the hang up. Here is my code:
// // Configure UDP // #define UDPPORT 5005 /** Setup the UDP task. * This hook is called when the device connects to the network, * and the connection becomes available for usage. */ Void networkOpenHook() { Task_Handle taskHandle; Task_Params taskParams; Error_Block eb; // Ensure that the error block is initialized. Error_init(&eb); // Create the UDP task handler. // The first argument is the the port that the task listens to. // Set this to be a high priority task. Task_Params_init(&taskParams); taskParams.stackSize = 1024; taskParams.priority = 1; taskParams.arg0 = UDPPORT; taskHandle = Task_create((Task_FuncPtr) udpHandler, &taskParams, &eb); if (taskHandle == NULL) System_printf("Failed to create udpHandler task.\n"); }
Void udpHandler(UArg arg0, UArg arg1) { SOCKET lSocket; struct sockaddr_in sLocalAddr; struct sockaddr_in client_addr; struct timeval to; fd_set readfds; int addrlen = sizeof(client_addr); int status; HANDLE hBuffer; IPN LocalAddress = 0; Int nbytes; Bool flag = TRUE; Char* buffer; fdOpenSession(TaskSelf()); lSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (lSocket < 0) { System_printf("udpHandler: socket failed\n"); Task_exit(); return; } memset((char *)&sLocalAddr, 0, sizeof(sLocalAddr)); sLocalAddr.sin_family = AF_INET; //sLocalAddr.sin_len = sizeof(sLocalAddr); sLocalAddr.sin_addr.s_addr = LocalAddress; sLocalAddr.sin_port = htons(arg0); status = bind(lSocket, (struct sockaddr *)&sLocalAddr, sizeof(sLocalAddr)); if (status < 0) { System_printf("udpHandler: bind failed: returned: %d, error: %d\n", status, fdError()); fdClose(lSocket); Task_exit(); return; } to.tv_sec = 5; to.tv_usec = 0; // Loop while we receive data static uint32_t trigger_count = 0; while (flag) { FD_ZERO(&readfds); FD_SET(lSocket, &readfds); if (fdSelect(0, &readfds, NULL, NULL, &to) != 1) { status = fdError(); System_printf("timed out waiting for client\n", status); System_printf("udpHandler: received %u triggers so far\n", trigger_count); System_flush(); continue; } nbytes = recvncfrom(lSocket, (void **)&buffer, MSG_WAITALL, (struct sockaddr *)&client_addr, &addrlen, &hBuffer); if (nbytes >= 0) { // If reply byte was received, then echo it. uint8_t data = *((uint8_t*) buffer); if (data == 0xAA) { sendto(lSocket, (char*) &data, 1, 0, (struct sockaddr *)&client_addr, sizeof(client_addr)); recvncfree(hBuffer); System_printf("udpHandler: Echo'd %u to client.\n", data); } else { trigger_count++; System_printf("udpHandler: Received %u from client.\n", data); } } else { status = fdError(); if (status == EWOULDBLOCK) { System_printf("udpHandler: Waiting for client to send UDP data.\n"); continue; } else { System_printf( "udpHandler: recvfrom failed: returned: %d, error: %d\n", nbytes, status); fdClose(lSocket); flag = FALSE; } } } System_printf("udpHandler: received %u triggers\n", trigger_count); System_printf("udpHandler stop, lSocket = 0x%x\n", lSocket); System_flush(); if (lSocket) { fdClose(lSocket); } fdCloseSession(TaskSelf()); /* * Since deleteTerminatedTasks is set in the cfg file, * the Task will be deleted when the idle task runs. */ Task_exit(); }
/* * ======== main ======== */ int main(void) { /* Call board init functions */ Board_initGeneral(); Board_initEMAC(); Board_initGPIO(); /* Turn on user LED */ GPIO_write(Board_LED0, Board_LED_ON); // Initialize the config_t to use the global solenoids global_config.solenoids = global_solenoids; global_config.num_solenoids = NUM_SOLENOIDS; System_printf("Starting the example\nSystem provider is set to SysMin. " "Halt the target to view any SysMin contents in ROV.\n"); /* SysMin will only print to the console when you call flush or exit */ System_flush(); /* Start BIOS */ BIOS_start(); return (0); }
I don't know if it matters, but In addition to the UDP code, I am running the HTTP server as well (successfully).