Semáforos no Nucleus RTOS: Serviços Utilitários e Estruturas de Dados
Veja a série RTOS Revealed
Este artigo continua a análise dos semáforos.
Serviços Utilitários de Semáforo
Nucleus RTOS oferece quatro chamadas de API que fornecem utilitários essenciais para gerenciamento de semáforos: resetar semáforo, recuperar informações detalhadas, contar total de semáforos na aplicação, e obter ponteiros para todos objetos semáforo. As três primeiras funções são totalmente implementadas no Nucleus SE.
Resetando Semáforo
Diferente da maioria dos objetos kernel, resetar semáforo restaura-o a contagem inicial especificada em vez de simplesmente reinicializá-lo ao valor de compilação. Quaisquer tarefas bloqueadas no semáforo são imediatamente acordadas e recebem código de retorno NUSE_SEMAPHORE_WAS_RESET (ou NU_SEMAPHORE_RESET no Nucleus RTOS).
Chamada de API Nucleus RTOS para Resetar Semáforo
Protótipo da chamada de serviço:
STATUS NU_Reset_Semaphore(NU_SEMAPHORE *semaphore,
UNSIGNED initial_count);
Parâmetros:
semaphore – ponteiro para bloco de controle do semáforo fornecido pelo usuário.
initial_count – valor para o qual contador do semáforo deve ser definido.
Retornos:
NU_SUCCESS – operação completada com sucesso.
NU_INVALID_SEMAPHORE – ponteiro do semáforo não é válido.
Chamada de API Nucleus SE para Resetar Semáforo
Protótipo da chamada de serviço:
STATUS NUSE_Semaphore_Reset(NUSE_SEMAPHORE semaphore,
U8 initial_count);
Parâmetros:
semaphore – índice (ID) do semáforo a resetar.
initial_count – valor para o qual contador do semáforo deve ser definido.
Retornos:
NUSE_SUCCESS – operação completada com sucesso.
NUSE_INVALID_SEMAPHORE – índice do semáforo não é válido.
Implementação Nucleus SE de Reset de Semáforo
A rotina NUSE_Semaphore_Reset() valida seus argumentos e então escreve nova contagem no array NUSE_Semaphore_Counter[]. Quando bloqueio habilitado, loopa pela tabela de tarefas para localizar tarefas suspensas no semáforo, marca-as como prontas, atribui código de retorno NUSE_SEMAPHORE_WAS_RESET, e finalmente dispara reschedule se scheduler de prioridade ativo.
while (NUSE_Semaphore_Blocking_Count[semaphore] != 0) { U8 index; for (index = 0; index < NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_SEMAPHORE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == semaphore)) { NUSE_Task_Blocking_Return[index] = NUSE_SEMAPHORE_WAS_RESET; NUSE_Task_Status[index] = NUSE_READY; break; } } NUSE_Semaphore_Blocking_Count[semaphore]--; } #if NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER NUSE_Reschedule(NUSE_NO_TASK); #endif
Todas tarefas suspensas são portanto transicionadas para estado ready com código de retorno apropriado. Se scheduler de prioridade ativo, NUSE_Reschedule() garante que tarefas de maior prioridade possam preemptar as de menor.
Informação de Semáforo
Esta chamada de serviço recupera detalhes-chave sobre semáforo. No Nucleus SE, menos campos são retornados porque nomeação de objetos, ordenação de suspensão e task suspend podem não ser suportados.
Chamada de API Nucleus RTOS para Informação de Semáforo
Protótipo da chamada de serviço:
STATUS NU_Semaphore_Information(NU_SEMAPHORE *semaphore,
CHAR *name, UNSIGNED *current_count, OPTION *suspend_type,
UNSIGNED *tasks_waiting, NU_TASK **first_task);
Parâmetros:
semaphore – ponteiro para bloco de controle do semáforo requisitado.
name – buffer de destino para nome do semáforo (8 caracteres + terminador null).
current_count – recebe valor atual do contador do semáforo.
suspend_type – recebe política de suspensão (ex.: NU_FIFO ou NU_PRIORITY).
tasks_waiting – recebe número de tarefas suspensas no semáforo.
first_task – recebe ponteiro para bloco de controle da primeira tarefa suspensa.
Retornos:
NU_SUCCESS – chamada completada com sucesso.
NU_INVALID_SEMAPHORE – ponteiro do semáforo inválido.
Chamada de API Nucleus SE para Informação de Semáforo
Protótipo da chamada de serviço:
STATUS NUSE_Semaphore_Information(NUSE_SEMAPHORE semaphore,
U8 *current_count, U8 *tasks_waiting, NUSE_TASK *first_task);
Parâmetros:
semaphore – índice do semáforo.
current_count – recebe valor atual do contador.
tasks_waiting – recebe número de tarefas suspensas (se task suspend habilitado).
first_task – recebe índice da primeira tarefa suspensa (se task suspend habilitado).
Retornos:
NUSE_SUCCESS – chamada completada com sucesso.
NUSE_INVALID_SEMAPHORE – índice do semáforo inválido.
NUSE_INVALID_POINTER – um ou mais argumentos ponteiro inválidos.
Implementação Nucleus SE de Informação de Semáforo
A implementação é concisa: entra seção crítica, copia valor do contador, e se blocking habilitado, enumera tabela de tarefas para contar tarefas esperando e identificar primeira tarefa suspensa. Caso contrário, waiting count e first task são zerados.
NUSE_CS_Enter(); *current_count = NUSE_Semaphore_Counter[semaphore]; #if NUSE_BLOCKING_ENABLE *tasks_waiting = NUSE_Semaphore_Blocking_Count[semaphore]; if (NUSE_Semaphore_Blocking_Count[semaphore] != 0) { U8 index; for (index = 0; index < NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_SEMAPHORE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == semaphore)) { *first_task = index; break; } } } else { *first_task = 0; } #else *tasks_waiting = 0; *first_task = 0; #endif NUSE_CS_Exit(); return NUSE_SUCCESS;
Obtendo Número de Semáforos
Este serviço retorna contagem total de semáforos definidos na aplicação. No Nucleus RTOS o valor pode mudar em runtime; no Nucleus SE é fixo em tempo de build.
Chamada de API Nucleus RTOS para Contagem de Semáforos
Protótipo da chamada de serviço:
UNSIGNED NU_Established_Semaphores(VOID);
Retorna: Número de semáforos criados na aplicação.
Chamada de API Nucleus SE para Contagem de Semáforos
Protótipo da chamada de serviço:
U8 NUSE_Semaphore_Count(void);
Retorna: Número de semáforos configurados na aplicação.
Implementação Nucleus SE de Contagem de Semáforos
A rotina simplesmente retorna valor da constante de compilação NUSE_SEMAPHORE_NUMBER.
Continue para página dois: “Estruturas de Dados” >>
Integrado
- Nuvem vs. Servidores In-House: Escolhendo a Solução de Hospedagem Certa
- Microsoft Azure Anuncia Serviços de Tokenização Blockchain e Gerenciamento de Dados
- Fundamentos de Memória Digital: Endereçamento, Acesso e Volatilidade
- Domine Variáveis e Tipos de Dados Primitivos em C#: Guia Completo
- Estruturas vs Classes em C++: Guia Prático para Desenvolvedores Embarcados
- Mailboxes no Nucleus SE: Guia Prático de Configuração e Uso
- Semáforos no Nucleus SE: Visão Geral, Configuração e APIs Essenciais
- Dominando Grupos de Event Flags: Serviços Utilitários e Estruturas de Dados no Nucleus RTOS/SE
- Grupos de Event Flags no Nucleus SE: Guia Introdutório de Configuração e Uso da API
- Queues no Nucleus SE: Introdução e Chamadas de Serviço Centrais