Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Сколько ОЗУ должна занимать задача?
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > FreeRTOS
Cosmojam
Всем привет!
Нужно сделать на базе LPC1768 + FreeRTOS + LwIP сервер обслуживающий максимум соединений.
Под кучу FreeRTOS и буферы EMAC используется RamAHB32. Под всё остальное - RamLoc32
Тестовый сервер на сокетах выглядит так:
Код
static void accept_thread(void *socket)
{
    int32_t sock = *((int32_t *)socket);
    uint_fast8_t exit_flag = 1;
    while(exit_flag)
    {
        char temp[20] = {0};
        sprintf(temp, "s %d h %d s %d\n", sock, xPortGetFreeHeapSize(), uxTaskGetStackHighWaterMark(NULL));
        lwip_send(sock, temp, strlen(temp), 0);
        uint8_t inbyte = 0;
        int32_t recvret = lwip_recv(sock, &inbyte, sizeof(inbyte), 0);
        if(recvret > 0u)
        {
            const char * const welcome = "hello\n";
            lwip_send(sock, welcome, strlen(welcome), 0);
        }
        else
        {
            exit_flag = 0;
        }
    }
    lwip_close(sock);
    vTaskDelete(NULL);
}

void server_main(void *parameters)
{
    int32_t socket = lwip_socket(AF_INET, SOCK_STREAM, 0);
    int32_t client_socket;
    struct sockaddr_in local_addr, client_addr;
    size_t client_addr_size = sizeof(client_addr);

    TSPRINTF("Server started\n");

    if(socket >= 0)
    {
        memset((void *)&local_addr, 0, sizeof(local_addr));
        local_addr.sin_family = AF_INET;
        local_addr.sin_len = sizeof(local_addr);
        local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        local_addr.sin_port = ntohs(((uint16_t)6666));
        if(lwip_bind(socket, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0 )
        {
            lwip_close(socket);
            TSPRINTF("Cannot bind port\n");
            vTaskDelete(NULL);
        }

        if(lwip_listen(socket, 20) != 0 )
        {
            lwip_close(socket);
            TSPRINTF("Cannot listen port\n");
            vTaskDelete(NULL);
        }
        uint16_t counter_conns = 0;
        while(1)
        {
            memset((void *)&client_addr, 0, sizeof(client_addr));
            client_socket = 0;
            client_socket = lwip_accept(socket, (struct sockaddr *)&client_addr, &client_addr_size);
            if(client_socket > 0u)
            {
                int32_t temp_socket = client_socket;
                if(xTaskCreate(accept_thread, "accept thread", 128 , (void *)&temp_socket, 2, NULL) == pdPASS)
                {
                    TSPRINTF("Created %d connection\n", ++counter_conns);
                }
                else
                {
                    TSPRINTF("Cannot create connection\n");
                }
            }
        }
    }
    TSPRINTF("Destroy server task\n");
    vTaskDelete(NULL);
}

Всё как обычно. В задаче accept_thread при каждом новом соединении отправляется по этому соединению объём доступной памяти в куче FreeRTOS. И вот что получается каждая новая задача отъедает ровно 880 байт и тем самым на 20-м соединении заканчивается вся куча. Может я что-то не понимаю? Куда расходуется столько памяти из кучи?
Cosmojam
Я мега-дятел sm.gif Размер стека задачи задаётся в portBASE_TYPE, а не в байтах.
Хотя всё равно получается 128 * 4 = 512 байт стека + 64 под TCB и длина имени задачи до 880 никак не дотягивает
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.