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

Caixas de correio:introdução e serviços básicos


Veja a série RTOS Revelado

As caixas de correio foram apresentadas em um artigo anterior. Eles são talvez o segundo método mais simples de comunicação entre tarefas - depois dos sinais - com suporte do Nucleus SE. Eles fornecem um meio de baixo custo, mas flexível, de passar mensagens simples entre tarefas.

Usando caixas de correio

No Nucleus SE, as caixas de correio são configuradas no momento da construção. Pode haver no máximo 16 caixas de correio configuradas para um aplicativo. Se nenhuma caixa de correio for configurada, nenhuma estrutura de dados ou código de chamada de serviço pertencente às caixas de correio será incluído no aplicativo.

Uma caixa de correio é simplesmente um local de armazenamento, grande o suficiente para conter uma única variável do tipo ADDR , o acesso é controlado para que possa ser utilizado com segurança por várias tarefas. Uma tarefa pode gravar em uma caixa de correio. Ele estará então cheio e nenhuma tarefa poderá ser enviada a ele até que uma tarefa faça uma leitura na caixa de correio ou que a caixa de correio seja redefinida. Tentar enviar para uma caixa de correio cheia ou ler de uma vazia pode resultar em erro ou suspensão da tarefa, dependendo das opções selecionadas na chamada API e na configuração do Nucleus SE.

Caixas de correio e filas

Em algumas implementações de sistema operacional, as caixas de correio não são implementadas e o uso de uma fila de entrada única é recomendado como alternativa. Isso parece razoável, já que essa fila forneceria a mesma funcionalidade que uma caixa de correio. No entanto, uma fila é uma estrutura de dados um pouco mais complexa do que uma caixa de correio e carrega consideravelmente mais sobrecarga de dados (ponteiros de cabeça e cauda etc.), código e tempo de execução.

Com o Nucleus SE, assim como o Nucleus RTOS, você tem a opção de escolher os dois tipos de objeto e pode tomar a decisão por si mesmo.

Vale a pena considerar a abordagem alternativa se seu aplicativo incluir várias filas, mas talvez uma única caixa de correio. Substituir essa caixa de correio por uma fila gerará uma pequena sobrecarga de dados, mas elimina todo o código de API relacionado à caixa de correio. Seria muito fácil configurar o aplicativo das duas maneiras e comparar as pegadas de memória e o desempenho.

As filas serão discutidas em artigos futuros.

Configurando caixas de correio

Número de caixas de correio

Como acontece com a maioria dos aspectos do Nucleus SE, a configuração das caixas de correio é controlada principalmente por #define declarações em nuse_config.h . A configuração principal é NUSE_MAILBOX_NUMBER , que determina quantas caixas de correio são configuradas para o aplicativo. A configuração padrão é 0 (ou seja, nenhuma caixa de correio está em uso) e você pode defini-la com 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 #error declaração sendo compilada.

A escolha de um valor diferente de zero é a “habilitação principal” para caixas de correio. Isso resulta em algumas estruturas de dados sendo definidas e dimensionadas de acordo, sobre o que falaremos no próximo artigo. Ele também ativa as configurações de ativação da API.

Ativa API

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

NUSE_MAILBOX_SEND
NUSE_MAILBOX_RECEIVE
NUSE_MAILBOX_RESET
NUSE_MAILBOX_INFORMATION
NUSE_MAILBOX_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 caixas de correio 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.
  / * Número de caixas de correio no   sistema - 0-16 * /   #define NUSE_MAILBOX_NUMBER 0   / * Ativadores de chamada de serviço:* /   #define NUSE_MAILBOX_SEND FALSE   #define NUSE_MAILBOX_RECEIVE FALSE   #define NUSE_MAILBOX_RESET FALSE   #define NUSE_MAILBOX_INFORMATION FALSE   #define NUSE_MAILBOX_COUNT FALSE  

Um erro de tempo de compilação ocorrerá se uma função de API de caixa de correio estiver habilitada e nenhuma caixa de correio for configurada (exceto para NUSE_Mailbox_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 caixa de correio

O Nucleus RTOS suporta nove chamadas de serviço que pertencem às caixas de correio, que fornecem a seguinte funcionalidade:

  • Envie uma mensagem para uma caixa de correio. Implementado por NUSE_Mailbox_Send () no Núcleo SE.

  • Receber uma mensagem de uma caixa de correio. Implementado por NUSE_Mailbox_Receive () no Núcleo SE.

  • Restaure uma caixa de correio para o estado não usado, sem tarefas suspensas (redefinir). Implementado por NUSE_Mailbox_Reset () no Núcleo SE.

  • Fornece informações sobre uma caixa de correio especificada. Implementado por NUSE_Mailbox_Information () no Núcleo SE.

  • Retorne uma contagem de quantas caixas de correio estão (atualmente) configuradas para o aplicativo. Implementado por NUSE_Mailbox_Count () no Núcleo SE.

  • Adicionar uma nova caixa de correio ao aplicativo (criar). Não implementado no Nucleus SE.

  • Remover uma caixa de correio do aplicativo (excluir). Não implementado no Nucleus SE.

  • Retorne ponteiros para todas as caixas de correio (atualmente) no aplicativo. Não implementado no Nucleus SE.

  • Envie uma mensagem para todas as tarefas que estão suspensas em uma caixa de correio (transmissão). Não implementado no Nucleus SE.


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

Serviços de gravação e leitura de caixa de correio

As operações fundamentais, que podem ser realizadas em uma caixa de correio, são a gravação de dados nela - o que às vezes é denominado envio ou postagem - e lendo dados dele - que também é denominado recebimento . O Nucleus RTOS e o Nucleus SE fornecem, cada um, duas chamadas API básicas para essas operações, que serão discutidas aqui.

Escrevendo para uma caixa de correio

A chamada da API Nucleus RTOS para gravar em uma caixa de correio é 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 escrever para uma caixa de correio cheia. O Nucleus SE fornece o mesmo serviço, exceto que a suspensão da tarefa é opcional e o tempo limite não é implementado.

O Nucleus RTOS também oferece um recurso de transmissão para uma caixa de correio, mas isso não é compatível com o Nucleus SE. Será descrito em APIs não implementadas no próximo artigo.

Chamada de API Nucleus RTOS para envio para uma caixa de correio

Protótipo de chamada de serviço:


STATUS NU_Send_To_Mailbox (caixa de correio NU_MAILBOX *, mensagem VOID *, suspender NÃO ASSINADO);

Parâmetros:

caixa de correio - ponteiro para a caixa de correio a ser utilizada

mensagem - um ponteiro para a mensagem a ser enviada, que é quatro não assinada elementos

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_INVALID_MAILBOX - o ponteiro da caixa de correio é inválido

NU_INVALID_POINTER - o ponteiro da mensagem é NULL

NU_INVALID_SUSPEND - a suspensão foi tentada a partir de um thread sem tarefa

NU_MAILBOX_FULL - a caixa de correio está cheia e a suspensão não foi especificada

NU_TIMEOUT - a caixa de correio ainda está cheia, mesmo após a suspensão pelo período especificado

NU_MAILBOX_DELETED - a caixa de correio foi excluída enquanto a tarefa estava suspensa

NU_MAILBOX_WAS_RESET - a caixa de correio foi redefinida enquanto a tarefa estava suspensa

Chamada de API do Nucleus SE para envio para uma caixa de correio

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

Protótipo de chamada de serviço:

STATUS NUSE_Mailbox_Send (caixa de correio NUSE_MAILBOX, mensagem ADDR *, U8 suspender);

Parâmetros:

caixa de correio - o índice (ID) da caixa de correio a ser utilizada

mensagem - um ponteiro para a mensagem a ser enviada, que é uma variável única do tipo ADDR

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_INVALID_MAILBOX - o índice da caixa de correio é inválido

NUSE_INVALID_POINTER - o ponteiro da mensagem é NULL

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_MAILBOX_FULL - a caixa de correio está cheia e a suspensão não foi especificada

NUSE_MAILBOX_WAS_RESET - a caixa de correio foi redefinida enquanto a tarefa estava suspensa

Implementação Nucleus SE de Mailbox Send

A maior parte do código de NUSE_Mailbox_Send () 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 e o código requer pouca explicação:
 if (NUSE_Mailbox_Status [caixa de correio]) / * caixa de correio cheia * / {return_value =NUSE_MAILBOX_FULL;} else / * caixa de correio vazia * / {NUSE_Mailbox_Data [caixa de correio] =* mensagem; NUSE_Mailbox_Status [caixa de correio] =TRUE; return_value =NUSE_SUCCESS;} 

A mensagem é armazenada no elemento apropriado de NUSE_Mailbox_Data [] e a caixa de correio marcada como em uso.

Quando o bloqueio está habilitado, o código se torna mais complexo:
 faça {if (! NUSE_Mailbox_Status [caixa de correio]) / * caixa de correio vazia * / {NUSE_Mailbox_Data [caixa de correio] =* mensagem; NUSE_Mailbox_Status [caixa de correio] =TRUE; if (NUSE_Mailbox_Blocking_Count [caixa de correio]! =0) {índice U8; / * verificar se uma tarefa está bloqueada * / / * nesta caixa de correio * / NUSE_Mailbox_Blocking_Count [caixa de correio] -; para (índice =0; índice  
Alguma explicação pode ser útil:

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

Se a caixa de correio estiver vazia, a mensagem fornecida será armazenada e o status da caixa de correio será alterado para indicar que está cheia. É feita uma verificação para saber se alguma tarefa está suspensa (esperando para receber) na caixa de correio. Se houver alguma tarefa esperando, a primeira será ativada. O suspender variável está definida para NUSE_NO_SUSPEND e a chamada API sai com NUSE_SUCCESS .

Se a caixa de correio estiver cheia e suspender está definido para NUSE_NO_SUSPEND , a chamada da API sai com NUSE_MAILBOX_FULL . Se suspender foi definido 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 uma mensagem foi lida (em oposição a uma redefinição da caixa de correio), o código retorna ao topo.

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 aos ilhós e como eles funcionam
  4. Uma introdução ao aço inoxidável e como ele é feito
  5. COVID 19 e Nuvem; COVID 19 e seu impacto nos negócios
  6. Entrada e saída básica em C#
  7. Semáforos:serviços utilitários e estruturas de dados
  8. Semáforos:introdução e serviços básicos
  9. Grupos de sinalizadores de evento:serviços de utilidade e estruturas de dados
  10. Grupos de sinalizadores de evento:introdução e serviços básicos