Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial Internet of Things >> Integrado

Semáforos:introdução e serviços básicos


Veja a série RTOS Revelado

Os semáforos foram introduzidos em um artigo anterior. Seu uso principal é o controle de acesso aos recursos.

Usando semáforos

No Nucleus SE, os semáforos são configurados no momento da construção. Pode haver no máximo 16 semáforos configurados para um aplicativo. Se nenhum semáforo for configurado, nenhuma estrutura de dados ou código de chamada de serviço pertencente aos semáforos será incluído no aplicativo.

Um semáforo é simplesmente um contador do tipo U8 , o acesso é controlado para que possa ser utilizado com segurança por várias tarefas. Uma tarefa pode diminuir (obter) um semáforo e incrementá-lo (liberá-lo). Tentar obter um semáforo com valor zero pode resultar em erro ou suspensão da tarefa, dependendo das opções selecionadas na chamada API e da configuração do Nucleus SE.

Configuração de semáforos

Número de semáforos

Como acontece com a maioria dos aspectos do Nucleus SE, a configuração dos semáforos é controlada principalmente por # definir declarações em nuse_config.h . A configuração principal é NUSE_SEMAPHORE_NUMBER , que determina quantos semáforos são configurados para o aplicativo. A configuração padrão é 0 (ou seja, sem semáforos em uso) e você pode definir qualquer valor até 16. Um valor incorreto resultará em um erro de tempo de compilação, que é gerado por um teste em nuse_config_check.h (isso está incluído em nuse_config.c e, portanto, compilado com este módulo) resultando em um # erro declaração sendo compilada.

A escolha de um valor diferente de zero é a “habilitação do mestre” para semáforos. Isso resulta em algumas estruturas de dados sendo definidas e dimensionadas de acordo, sobre o que falaremos mais adiante neste artigo. Ele também ativa as configurações de ativação da API.

Ativa API

Cada função API (chamada de serviço) no Nucleus SE tem um # definir de ativação símbolo em nuse_config.h . Para semáforos, são:

NUSE_SEMAPHORE_OBTAIN
NUSE_SEMAPHORE_RELEASE
NUSE_SEMAPHORE_RESET
NUSE_SEMAPHORE_INFORMATION
NUSE_SEMAPHORE_COUNT

Por padrão, todos eles são definidos como FALSO , desabilitando cada chamada de serviço e inibindo a inclusão de qualquer código de implementação. Para configurar semáforos para um aplicativo, você precisa selecionar as chamadas de API que deseja usar e definir seus símbolos de ativação para TRUE .

Aqui está um trecho do padrão nuse_config.h Arquivo.

 #define NUSE_SEMAPHORE_NUMBER 0 / * Número de semáforos no sistema - 0-16 * / # define NUSE_SEMAPHORE_OBTAIN FALSE / * Ativador de chamada de serviço * / # define NUSE_SEMAPHORE_RELEASE FALSE / * Ativador de chamada de serviço * / # define NUSE_SEMAPHORE_RESET Service call enabler * / # define NUSE_SEMAPHORE_INFORMATION FALSE / * Service call enabler * / # define NUSE_SEMAPHORE_COUNT FALSE / * Service call enabler * / 

Um erro de tempo de compilação resultará se uma função API de semáforo estiver habilitada e nenhum semáforo estiver configurado (exceto para NUSE_Semaphore_Count () que é sempre permitido). Se o seu código usar uma chamada de API, que não foi habilitada, ocorrerá um erro de tempo de link, pois nenhum código de implementação terá sido incluído no aplicativo.

Chamadas de serviço de semáforo

O Nucleus RTOS oferece suporte a oito chamadas de serviço pertencentes a semáforos, que fornecem a seguinte funcionalidade:

  • Obtenha um semáforo. Implementado por NUSE_Semaphore_Obtain () no Núcleo SE.

  • Libere um semáforo. Implementado por NUSE_Semaphore_Release () no Núcleo SE.

  • Restaura um semáforo para o estado não usado, sem tarefas suspensas (redefinir). Implementado por NUSE_Semaphore_Reset () no Núcleo SE.

  • Fornece informações sobre um semáforo especificado. Implementado por NUSE_Semaphore_Information () no Núcleo SE.

  • Retorne uma contagem de quantos semáforos estão (atualmente) configurados para o aplicativo. Implementado por NUSE_Semaphore_Count () no Núcleo SE.

  • Adicionar um novo semáforo ao aplicativo (criar). Não implementado no Nucleus SE.

  • Remover um semáforo do aplicativo (excluir). Não implementado no Nucleus SE.

  • Retorna ponteiros para todos os semáforos (atualmente) no aplicativo. Não implementado no Nucleus SE.


A implementação de cada uma dessas chamadas de serviço é examinada em detalhes.

Serviços de obtenção e liberação de semáforo

As operações fundamentais, que podem ser realizadas em um semáforo, são obtê-lo (decrementar) e liberá-lo (incrementá-lo). O Nucleus RTOS e o Nucleus SE fornecem, cada um, duas chamadas API básicas para essas operações, que serão discutidas aqui.

Obtenção de um semáforo

A chamada da API Nucleus RTOS para obter um semáforo é muito flexível, permitindo suspender indefinidamente, ou com um tempo limite, se a operação não puder ser concluída imediatamente; ou seja, você tenta obter um semáforo que atualmente tem o valor zero. O Nucleus SE fornece o mesmo serviço, exceto que a suspensão da tarefa é opcional e o tempo limite não é implementado.

Chamada de Nucleus RTOS API para obtenção de um semáforo

Protótipo de chamada de serviço:


STATUS NU_Obtain_Semaphore (NU_SEMAPHORE * semáforo,
suspender NÃO ASSINADO);

Parâmetros:

semáforo - ponteiro para o bloco de controle do semáforo fornecido pelo usuário

suspender - especificação para suspensão de tarefa; pode ser NU_NO_SUSPEND ou NU_SUSPEND ou um valor de tempo limite

Retorna:

NU_SUCCESS - a chamada foi completada com sucesso

NU_UNAVAILABLE - o semáforo tinha o valor zero

NU_INVALID_SEMAPHORE - o ponteiro do semáforo é inválido

NU_INVALID_SUSPEND - a suspensão foi tentada a partir de uma tarefa não

NU_SEMAPHORE_WAS_RESET - o semáforo foi reiniciado enquanto a tarefa estava suspensa

Chamada de Nucleus SE API para obtenção de um semáforo

Esta chamada de API oferece suporte à funcionalidade principal da API Nucleus RTOS.

Protótipo de chamada de serviço:

STATUS NUSE_Semaphore_Obtain (NUSE_SEMAPHORE semáforo,
U8 suspender);

Parâmetros:

semáforo - o índice (ID) do semáforo a ser utilizado

suspender - especificação para suspensão de tarefa; pode ser NUSE_NO_SUSPEND ou NUSE_SUSPEND

Retorna:

NUSE_SUCCESS - a chamada foi completada com sucesso

NUSE_UNAVAILABLE - o semáforo tinha o valor zero

NUSE_INVALID_SEMAPHORE - o índice do semáforo é inválido

NUSE_INVALID_SUSPEND - a suspensão foi tentada a partir de um thread não-tarefa ou quando o bloqueio de chamadas de API não estava habilitado

NUSE_SEMAPHORE_WAS_RESET - o semáforo foi reiniciado enquanto a tarefa estava suspensa

Implementação do Nucleus SE de Obter Semaphore

A maior parte do código de NUSE_Semaphore_Obtain () A função API - após a verificação do parâmetro - é selecionada por compilação condicional, dependendo se o suporte para bloquear (suspender a tarefa) chamadas de API está habilitado. Veremos as duas variantes separadamente aqui.

Se o bloqueio não estiver habilitado, a lógica para esta chamada de API é bastante simples:
 if (NUSE_Semaphore_Counter [semáforo]! =0) / * semáforo disponível * / {NUSE_Semaphore_Counter [semáforo] -; return_value =NUSE_SUCCESS;} else / * semáforo indisponível * / {return_value =NUSE_UNAVAILABLE;} 

O valor do semáforo é testado e, se diferente de zero, diminuído.

Quando o bloqueio está habilitado, a lógica se torna mais complexa:
 faça {if (NUSE_Semaphore_Counter [semáforo]! =0) / * semáforo disponível * / {NUSE_Semaphore_Counter [semáforo] -; return_value =NUSE_SUCCESS; suspender =NUSE_NO_SUSPEND; } else / * semáforo indisponível * / {if (suspender ==NUSE_NO_SUSPEND) {return_value =NUSE_UNAVAILABLE; } else {/ * bloquear tarefa * / NUSE_Semaphore_Blocking_Count [semáforo] ++; NUSE_Suspend_Task (NUSE_Task_Active, semáforo <<4) | NUSE_SEMAPHORE_SUSPEND); return_value =NUSE_Task_Blocking_Return [NUSE_Task_Active]; if (return_value! =NUSE_SUCCESS) {suspend =NUSE_NO_SUSPEND; }}}} enquanto (suspender ==NUSE_SUSPEND); 

Algumas explicações do código podem ser úteis:

O código está entre do ... while loop, que continua enquanto o parâmetro suspender tem o valor NUSE_SUSPEND .

Se o semáforo for diferente de zero, ele é decrementado. O suspender variável está definida para NUSE_NO_SUSPEND e a chamada API sai com NUSE_SUCCESS .

Se o semáforo for zero e suspender está definido para NUSE_NO_SUSPEND , a chamada API sai com NUSE_UNAVAILBLE . Se a suspensão foi definida como NUSE_SUSPEND , a tarefa é suspensa. No retorno (ou seja, quando a tarefa é ativada), se o valor de retorno for NUSE_SUCCESS , indicando que a tarefa foi ativada porque o semáforo foi liberado (em oposição a uma redefinição do semáforo), o código retorna ao topo.

Liberando um Semáforo

A chamada da API Nucleus RTOS para liberar um semáforo é bastante simples; o semáforo é incrementado e o sucesso relatado. O Nucleus SE fornece o mesmo serviço, exceto que uma verificação de estouro é executada.

Chamada de Nucleus RTOS API para liberação de semáforo

Protótipo de chamada de serviço:

STATUS NU_Release_Semaphore (NU_SEMAPHORE * semáforo);

Parâmetros:

semáforo - ponteiro para o bloco de controle do semáforo fornecido pelo usuário

Retorna:

NU_SUCCESS - a chamada foi completada com sucesso

NU_INVALID_SEMAPHORE - o ponteiro do semáforo é inválido

Chamada de Nucleus SE API para liberação de um semáforo

Esta chamada de API oferece suporte à funcionalidade principal da API Nucleus RTOS.

Protótipo de chamada de serviço:

STATUS NUSE_Semaphore_Release (NUSE_SEMAPHORE semáforo);

Parâmetros:

semáforo - o índice (ID) do semáforo a ser lançado

Retorna:

NUSE_SUCCESS - a chamada foi completada com sucesso

NUSE_INVALID_SEMAPHORE - o índice do semáforo é inválido

NUSE_UNAVAILABLE - o semáforo tem o valor 255 e não pode ser incrementado

Implementação do Semaphore de Lançamento do Nucleus SE

O código inicial de NUSE_Semaphore_Release () A função API - após a verificação dos parâmetros - é comum, esteja o bloqueio de tarefas habilitado ou não. O valor do semáforo é verificado e, se for menor que 255, decrementado.

O código adicional é selecionado por compilação condicional, se o suporte para bloquear (suspender a tarefa) chamadas de API estiver habilitado:
 NUSE_CS_Enter (); if (NUSE_Semaphore_Counter [semáforo] <255) {NUSE_Semaphore_Counter [semáforo] ++; return_value =NUSE_SUCCESS; #if NUSE_BLOCKING_ENABLE if (NUSE_Semaphore_Blocking_Count [semáforo]! =0) {índice U8; / * verificar se uma tarefa está bloqueada * / / * neste semáforo * / NUSE_Semaphore_Blocking_Count [semáforo] -; para (índice =0; índice  
Se alguma tarefa for suspensa neste semáforo, a primeira será ativada.

O próximo artigo cobrirá algumas chamadas API adicionais associadas a grupos de sinalizadores de evento, junto com as estruturas de dados relevantes.


Colin Walls tem mais de trinta anos de experiência na indústria eletrônica, em grande parte dedicada a software embarcado. Apresentador frequente em conferências e seminários e autor de vários artigos técnicos e dois livros sobre software integrado, Colin é um tecnólogo de software integrado da Mentor Embedded [a Mentor Graphics Embedded Software Division] e mora no Reino Unido. Seu blog regular está localizado em:http://blogs.mentor.com/colinwalls. Ele pode ser contatado por e-mail em [email protected]

Integrado

  1. Uma introdução aos Cam Locks e como funcionam
  2. Uma introdução aos parafusos de olho e como eles funcionam
  3. Uma introdução ao aço inoxidável e como ele é feito
  4. Entrada e saída básica em C#
  5. O que é um redator de serviços automotivos e o que eles fazem?
  6. Caixas de correio:introdução e serviços básicos
  7. Semáforos:serviços utilitários e estruturas de dados
  8. Grupos de sinalizadores de evento:serviços de utilidade e estruturas de dados
  9. Grupos de sinalizadores de evento:introdução e serviços básicos
  10. Filas:introdução e serviços básicos