2022-08-30 09:19 AM
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM1_Init();
MX_TIM2_Init();
MX_USART3_UART_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);
HAL_TIM_OC_Start_IT(&htim1, TIM_CHANNEL_1);
/* USER CODE END 2 */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* definition and creation of defaultTask */
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 2048);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
/* Start scheduler */
osKernelStart();
/* We should never get here as control is now taken by the scheduler */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
void StartDefaultTask(void const * argument)
{
/* init code for LWIP */
MX_LWIP_Init();
/* USER CODE BEGIN 5 */
/* Infinite loop */
}
if I call MX_LWIP_Init(); before
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 2048);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
then it runs just fine but my main app is not running anymore.
It looklike an issue with FreeRTOS but I am beginner with it so I can't tell for sure.
2022-08-30 12:47 PM
Is that REALLY your code? Your StartDefaultTask() will exit immediately after calling MX_LWIP_Init(). What happens to a task when it returns/hits the end of the function? Hint - normally tasks don't ever return. If all you want to do in StartDefaultTask() is start/init LWIP, then add an infinite loop after that calling osDelay() to allow other tasks to run.
I don't see your "main app" in the code above. Could be a priority issue where a higher priority task never gives lower priority tasks (like ethernetif_set_link) a chance to run.
2022-08-30 12:53 PM
Its not all of my code. Here's the "main" loop of the application.
I also handles TIM1 & TIM2 for "other stuff"
void StartDefaultTask(void const * argument)
{
/* init code for LWIP */
MX_LWIP_Init();
/* USER CODE BEGIN 5 */
/* Infinite loop */
struct sockaddr_in address, client_addr;
socklen_t sin_size;
int s_create;
int addrlen = sizeof(address);
int opt = 1;
int socket_check;
/*Create a socket*/
s_create = lwip_socket(AF_INET, SOCK_STREAM, 0);
socket_check = lwip_setsockopt(s_create, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt));
memset(&address,0,sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(IPADDR_ANY);
address.sin_port = htons(HTTP_PORT); // C++ Client/Server might need to use 8080
socket_check = lwip_bind(s_create, (struct sockaddr*)&address, sizeof(address));
socket_check = lwip_listen(s_create, 1); //returns 0 on succes, -1 on failure
char recvBuff[100];
acqBuff_0.size = 0;
acqBuff_0.startIndex = 0;
acqBuff_1.size = 0;
acqBuff_1.startIndex = 0;
manager.masterIndex = 0;
manager.ready = 0;
manager.selector = 0;
HAL_TIM_OC_Stop_IT(&htim1, TIM_CHANNEL_1);
HAL_GPIO_WritePin(TRIG_IN_LED_GPIO_Port, TRIG_IN_LED_Pin, 0);
HAL_GPIO_WritePin(TRIG_OUT_LED_GPIO_Port, TRIG_OUT_LED_Pin, 0);
for(;;)
{
HAL_GPIO_WritePin(MCU_STATUS_LED_GPIO_Port, MCU_STATUS_LED_Pin, 1);
sin_size = sizeof(struct sockaddr_in);
new_socket = lwip_accept(s_create, (struct sockaddr *)&client_addr, &sin_size);
if (new_socket > 0){
msgSize = sprintf(printMsg, "New client connected from IP: %s, Port: %d\r\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
HAL_UART_Transmit(&huart3, (uint8_t*)printMsg, msgSize, 10);
ledTimer = HAL_GetTick();
connectionClosed = 0;
while(!connectionClosed){
memset(recvBuff, 0, sizeof(recvBuff));
retVal = lwip_recv(new_socket, recvBuff, sizeof(recvBuff), MSG_DONTWAIT);
// Process buffer
processMsg(recvBuff);
//Toggle LED every second
updateLED();
// Send acquired Z-Encoder Data
if(manager.ready){
if(manager.selector){ //buffer_0 is full and ready to be sent.
acqBuff_0.startIndex = manager.masterIndex; // insert current index into structure
retVal = lwip_write(new_socket, &acqBuff_0, (4*(acqBuff_0.size) + 8));
acqBuff_0.size = acqBuff_0.size - (retVal-8)/4;
memset(acqBuff_0.data, -2, sizeof(acqBuff_0.data));
manager.masterIndex += (retVal-8)/4; // Increment Index according to size of buffer sent
manager.ready = 0;
if(retVal <0 ){
// Client is disconnected
goto socket_close;
}
}
else if(!manager.selector){ //buffer_1 is full and ready to be sent.
acqBuff_1.startIndex = manager.masterIndex;
retVal = lwip_write(new_socket, &acqBuff_1, (4*(acqBuff_1.size) + 8));
acqBuff_1.size = acqBuff_1.size - (retVal-8)/4;
memset(acqBuff_1.data, -2, sizeof(acqBuff_1.data));
manager.ready = 0;
manager.masterIndex += (retVal-8)/4;
if(retVal <0 ){
// Client is disconnected
goto socket_close;
}
}
}
osDelay(100);
}// End of client connected loop
socket_close:
lwip_close(new_socket);
}
}
/* USER CODE END 5 */
}
2022-08-30 01:18 PM
if your lwip_accept() call returns <= 0 (no connection) then your main loop here never yields to lower priority tasks (like ethernetif_set_link).
2022-08-30 01:28 PM
That is good point, I dont understand how lwip_accept() handles multiple thread in the background but it seems like it does.
Anyway, I found the issue to be total heap size
in FreeRTOSConfig.h
I modify
#define configTOTAL_HEAP_SIZE ((size_t)16360)
to
#define configTOTAL_HEAP_SIZE ((size_t)30720)
and all threads are now running !
2022-09-04 09:36 AM
Socket API in lwIP is like the old BSD-style socket API. Netconn API provides similar functionality, but is simpler and more efficient.