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

Filas:introdução e serviços básicos


Veja a série RTOS Revelado

As filas foram apresentadas em um artigo anterior. Eles fornecem um meio mais flexível de passar mensagens simples entre tarefas do que as caixas de correio.

Usando filas

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

Uma fila é simplesmente um conjunto de locais de armazenamento, cada um grande o suficiente para conter um único item de dados do tipo ADDR , o acesso é controlado para que possa ser utilizado com segurança por várias tarefas. As tarefas podem gravar em uma fila repetidamente até que todos os locais estejam cheios. As tarefas podem ler de uma fila e os dados são normalmente recebidos em uma base primeiro a entrar, primeiro a sair (FIFO). Tentar enviar para uma fila cheia ou ler de uma vazia pode resultar em erro ou suspensão da tarefa, dependendo das opções selecionadas na chamada API e da configuração do Nucleus SE.

Filas e canais

O Nucleus SE também oferece suporte a tubos, que também foram introduzidos em um artigo anterior e são abordados em detalhes em um artigo futuro. A principal diferença entre filas e canais é o tamanho da mensagem. As filas transportam mensagens compreendendo um único ADDR - normalmente seriam ponteiros. Um tubo transporta mensagens com um número arbitrário de bytes de comprimento; o tamanho é fixo para cada tubo na aplicação e definido no momento da configuração.

Configuração de filas

Número de filas

Como acontece com a maioria dos aspectos do Nucleus SE, a configuração das filas é controlada principalmente por #define declarações em nuse_config.h . A configuração principal é NUSE_QUEUE_NUMBER , que determina quantas filas são configuradas para o aplicativo. A configuração padrão é 0 (ou seja, nenhuma fila 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 filas. 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 filas, são:

NUSE_QUEUE_SEND
NUSE_QUEUE_RECEIVE
NUSE_QUEUE_JAM
NUSE_QUEUE_RESET
NUSE_QUEUE_INFORMATION
NUSE_QUEUE_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 filas 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 extrato do arquivo nuse_config.h padrão.

#define NUSE_QUEUE_NUMBER 0 / * Número de filas no
Sistema - 0-16 * /
/ * Ativadores de chamada de serviço * /
#define NUSE_QUEUE_SEND FALSE
#define NUSE_QUEUE_RECEIVE FALSE
#define NUSE_QUEUE_JAM FALSE
#define NUSE_QUEUE_RESET FALSE
#define NUSE_QUEUE_INFORMATION FALSE
#define NUSE_QUEUE_COUNT FALSE


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

O Nucleus RTOS oferece suporte a dez chamadas de serviço que pertencem às filas, que fornecem a seguinte funcionalidade:


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

Serviços de gravação e leitura de fila

As operações fundamentais, que podem ser realizadas em uma fila, são gravar dados nela - o que às vezes é denominado envio - e lendo dados dele - que também é denominado recebimento . Também é possível gravar dados na frente de uma fila - o que também é denominado congestionamento . O Nucleus RTOS e o Nucleus SE fornecem, cada um, três chamadas API básicas para essas operações, que serão discutidas aqui.

Gravando em uma fila

A chamada da API Nucleus RTOS para gravar em uma fila é 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 gravar em uma fila 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 fila, mas isso não é compatível com o Nucleus SE. Ele é descrito em APIs não implementadas no próximo artigo.

Chamada de Nucleus RTOS API para envio para uma fila

Protótipo de chamada de serviço:

STATUS NU_Send_To_Queue (NU_QUEUE * fila, VOID * mensagem,
tamanho UNSIGNED, UNSIGNED suspender);


Parâmetros:

fila - ponteiro para o bloco de controle de fila fornecido pelo usuário

mensagem - um ponteiro para a mensagem a ser enviada

tamanho - o número de NÃO ASSINADO elementos de dados na mensagem. Se a fila suportar mensagens de comprimento variável, este parâmetro deve ser igual ou menor que o tamanho da mensagem suportado pela fila. Se a fila suportar mensagens de tamanho fixo, este parâmetro deve ser exatamente igual ao tamanho da mensagem suportado pela fila.

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_QUEUE - o ponteiro da fila é inválido

NU_INVALID_POINTER - o ponteiro da mensagem é NULL

NU_INVALID_SIZE - o tamanho da mensagem é incompatível com o tamanho da mensagem suportado pela fila

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

NU_QUEUE_FULL - a fila está cheia e a suspensão não foi especificada

NU_TIMEOUT - a fila ainda está cheia, mesmo após a suspensão para o valor de tempo limite especificado

NU_QUEUE_DELETED - a fila foi excluída enquanto a tarefa estava suspensa

NU_QUEUE_RESET - a fila foi redefinida enquanto a tarefa estava suspensa

Chamada de API do Nucleus SE para envio para uma fila

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

Protótipo de chamada de serviço:

STATUS NUSE_Queue_Send (NUSE_QUEUE queue, ADDR * message,
U8 suspend);


Parâmetros:

fila - o índice (ID) da fila 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_QUEUE - o índice da fila é 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_QUEUE_FULL - a fila está cheia e a suspensão não foi especificada

NUSE_QUEUE_WAS_RESET - a fila foi redefinida enquanto a tarefa estava suspensa

Implementação Nucleus SE de ASend de Fila

A maior parte do código de NUSE_Queue_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, o código para esta chamada de API é bastante simples:

 if (NUSE_Queue_Items [fila] ==NUSE_Queue_Size [fila]) / * fila cheia * / {return_value =NUSE_QUEUE_FULL;} else / * elemento de fila disponível * / {NUSE_Queue_Data [fila] [NUSE_Queue_Head [fila] ++] *mensagem; if (NUSE_Queue_Head [fila] ==NUSE_Queue_Size [fila]) {NUSE_Queue_Head [fila] =0; } NUSE_Queue_Items [fila] ++; return_value =NUSE_SUCCESS;} 

A função simplesmente verifica se há espaço na fila e usa o NUSE_Queue_Head [] índice para armazenar a mensagem na área de dados da fila.

Quando o bloqueio está habilitado, o código se torna mais complexo:
 faça {if (NUSE_Queue_Items [queue] ==NUSE_Queue_Size [queue]) / * queue full * / {if (suspend ==NUSE_NO_SUSPEND) {return_value =NUSE_QUEUE_FULL; } else {/ * bloquear tarefa * / NUSE_Queue_Blocking_Count [queue] ++; NUSE_Suspend_Task (NUSE_Task_Active, (fila <<4) | NUSE_QUEUE_SUSPEND); return_value =NUSE_Task_Blocking_Return [NUSE_Task_Active]; if (return_value! =NUSE_SUCCESS) {suspend =NUSE_NO_SUSPEND; }}} else {/ * elemento de fila disponível * / NUSE_Queue_Data [fila] [NUSE_Queue_Head [fila] ++] =* mensagem; if (NUSE_Queue_Head [fila] ==NUSE_Queue_Size [fila]) {NUSE_Queue_Head [fila] =0; } NUSE_Queue_Items [fila] ++; if (NUSE_Queue_Blocking_Count [fila]! =0) {índice U8; / * verificar se uma tarefa está bloqueada nesta fila * / NUSE_Queue_Blocking_Count [fila] -; para (índice =0; índice  
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 a fila estiver cheia e suspender está definido para NUSE_NO_SUSPEND , a chamada da API sai com NUSE_QUEUE_FULL . 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 uma mensagem foi lida (em oposição a uma redefinição da fila), o código retorna ao topo.

Se a fila não estiver cheia, a mensagem fornecida é armazenada usando o NUSE_Queue_Head [] índice para armazenar a mensagem na área de dados da fila. É feita uma verificação para saber se alguma tarefa está suspensa (aguardando para receber) na fila. 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 .

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. Entrada e saída básica em C#
  6. Caixas de correio:introdução e serviços básicos
  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