Toda a verdade sobre o RTOS. Artigo 28. Temporizadores de software

A idéia de temporizadores de software foi introduzida em um artigo anterior . Eles são objetos do kernel que fornecem tarefas com uma maneira simples de disparar eventos dentro do prazo ou, na maioria das vezes, uma maneira de executar ações regularmente. Todos os detalhes da funcionalidade relacionada ao tempo (precisão, manipulação de interrupções etc.) no Nucleus SE foram discutidos em um artigo anterior .




Usando temporizadores


Os cronômetros de programa podem ser configurados para disparar uma vez, ou seja, eles iniciam e, depois de um período especificado, simplesmente encerram o ciclo. Ou o cronômetro pode ser configurado para reiniciar: após a contagem ser concluída, o cronômetro é reiniciado automaticamente. O tempo de operação após uma reinicialização pode diferir do tempo de operação inicial. Além disso, o temporizador pode opcionalmente ser configurado para executar uma função de finalização especial, que é executada quando (ou toda vez) o cronômetro completa o ciclo de trabalho.

Configurações do temporizador


Número de temporizadores


Como na maioria dos aspectos do Nucleus SE, as configurações do timer são controladas pelas diretivas #define em nuse_config.h . O parâmetro principal é NUSE_TIMER_NUMBER , que define os cronômetros configurados no aplicativo. Por padrão, esse valor é zero (ou seja, os temporizadores não são usados ​​no aplicativo) e pode levar valores até 16. Um valor incorreto levará a um erro de compilação, que será gerado ao verificar o arquivo nuse_config_check.h (esse arquivo está incluído no nuse_config.c e compila junto com ele), que acionará a diretiva #error .

A seleção de um valor diferente de zero é o principal ativador do timer. Este parâmetro é usado ao definir estruturas de dados, e seu tamanho depende de seu valor. Além disso, um valor diferente de zero ativa as configurações da API.

Ativação da função de conclusão


No Nucleus SE, tentei encontrar a oportunidade de tornar a funcionalidade opcional, onde economizará memória. Um bom exemplo é o suporte para funções de conclusão do timer. Além do fato de esse recurso ser opcional para cada timer, o mecanismo pode ser ativado (ou não) para todo o aplicativo usando o parâmetro NUSE_TIMER_EXPIRATION_ROUTINE_SUPPORT em nuse_config.h . Definir esse parâmetro como FALSE bloqueia a definição de duas estruturas de dados na ROM, que serão descritas em detalhes neste artigo.

Ativação de API


Cada função de API (chamada de utilitário) no Nucleus SE possui uma diretiva #define de ativação em nuse_config.h. Para temporizadores, esses símbolos incluem:
NUSE_TIMER_CONTROL
NUSE_TIMER_GET_REMAINING
NUSE_TIMER_RESET
NUSE_TIMER_INFORMATION
NUSE_TIMER_COUNT

Por padrão, todos os ativadores são definidos como FALSE , portanto, todas as chamadas de serviço são desativadas, bloqueando a inclusão do código que as implementa. Para configurar temporizadores no aplicativo, é necessário selecionar as chamadas de serviço da API necessárias e configurá-las como TRUE .

A seguir, um trecho de código do arquivo nuse_config.h padrão.

#define NUSE_TIMER_NUMBER 0/*      0-16 */ /*    */ #define NUSE_TIMER_CONTROL FALSE #define NUSE_TIMER_GET_REMAINING FALSE #define NUSE_TIMER_RESET FALSE #define NUSE_TIMER_INFORMATION FALSE #define NUSE_TIMER_COUNT FALSE 

Se a função API relacionada ao cronômetro estiver ativada e não houver cronômetros configurados no aplicativo (exceto a função NUSE_Timer_Count () , que sempre está ativada), ocorrerá um erro de compilação. Se o seu código usar uma chamada de API que não foi ativada, ocorrerá um erro de layout porque o código de implementação não foi incluído no aplicativo.

Chamadas de serviço do timer


O Nucleus RTOS suporta oito chamadas de utilitário relacionadas ao timer que fornecem a seguinte funcionalidade:

  • Temporizador de gestão (iniciar / parar). O núcleo SE é implementado na função NUSE_Timer_Control () .
  • Recuperando o tempo restante do timer. No Nucleus SE, implementado em NUSE_Timer_Get_Remaining () .
  • Restaurando o timer para seu estado original (redefinir). Núcleo SE implementado em NUSE_Timer_Reset () .
  • Fornecendo informações sobre um cronômetro específico. O núcleo SE é implementado em NUSE_Timer_Information () .
  • Retorna o número de temporizadores configurados (atualmente) no aplicativo. O núcleo SE é implementado em NUSE_Timer_Count () .
  • Adicionando um novo cronômetro ao aplicativo (criação). O núcleo SE não está implementado.
  • Removendo um cronômetro do aplicativo. O núcleo SE não está implementado.
  • Retornando ponteiros para todos os cronômetros no aplicativo. O núcleo SE não está implementado.

A implementação de cada chamada de serviço será discutida em detalhes abaixo.

Serviços de Timer


As operações fundamentais que podem ser executadas com um timer são controle (iniciar e parar) e leitura do valor atual. O Nucleus RTOS e o Nucleus SE fornecem duas chamadas básicas de utilitário de API para essas operações.

Controle do temporizador


Uma chamada de utilitário à API do Nucleus RTOS para controlar o cronômetro permite ativar e desativar o cronômetro (iniciar e parar). O Nucleus SE fornece funcionalidade semelhante.

Desafio de controle do temporizador no núcleo RTOS
Protótipo de chamada de serviço:

STATUS NU_Control_Timer (temporizador NU_TIMER *, ativação de OPÇÃO);

Parâmetros:
timer - ponteiro para o bloco de controle do timer fornecido pelo usuário;
enable é a função necessária; ele pode assumir os valores NU_ENABLE_TIMER ou NU_DISABLE_TIMER .

Valor de retorno:
NU_SUCCESS - a chamada foi concluída com sucesso;
NU_INAVLID_TIMER - ponteiro de timer inválido;
NU_INAVLID_ENABLE - função inválida.

Desafio de controle do temporizador no Nucleus SE
Essa chamada de API suporta a funcionalidade completa da API do Nucleus RTOS.

Protótipo de chamada de serviço:
STATUS NUSE_Timer_Control (temporizador NUSE_TIMER, ativação de OPTION);

Parâmetros:
timer - índice (ID) do timer usado;
enable é a função necessária; ele pode assumir os valores NUSE_ENABLE_TIMER ou NUSE_DISABLE_TIMER .

Valor de retorno:
NUSE_SUCCESS - a chamada foi concluída com sucesso;
NUSE_INCALID_TIMER - índice de timer inválido;
NUSE_INVALID_ENABLE é uma função inválida.

Implementar o gerenciamento de timer no Nucleus SE
O código de função da API NUSE_Timer_Control () (depois de verificar os parâmetros) é bastante simples:

 NUSE_CS_Enter(); if (enable == NUSE_ENABLE_TIMER) { NUSE_Timer_Status[timer] = TRUE; if (NUSE_Timer_Expirations_Counter[timer] == 0) { NUSE_Timer_Value[timer] = NUSE_Timer_Initial_Time[timer]; } else { NUSE_Timer_Value[timer] = NUSE_Timer_Reschedule_Time[timer]; } } else /* enable == NUSE_DISABLE_TIMER */ { NUSE_Timer_Status[timer] = FALSE; } NUSE_CS_Exit(); 

Se a função NUSE_DISABLE_TIMER foi especificada, o status do timer (parâmetro NUSE_Timer_Status [] ) é definido como FALSE , que ignora o timer pelo manipulador de interrupções.

Quando você seleciona a função NUSE_ENABLE_TIMER, o contador do timer ( NUSE_Timer_Value [] ) é definido como NUSE_Timer_initial_Time [] , desde que o timer nunca pare desde a última redefinição. Caso contrário, é atribuído o valor NUSE_Timer_Reschedule_Time [] . Em seguida, o status do timer (parâmetro NUSE_Timer_Status [] ) é definido como TRUE , o que faz com que o timer seja processado pelo manipulador de interrupções.

Leitura do temporizador


Para obter o tempo restante do timer, a chamada de serviço da API do Nucleus RTOS retorna o número de medidas até que ela expire. O Nucleus SE fornece funcionalidade semelhante.

Ligue para obter o tempo restante no Nucleus RTOS

Protótipo de chamada de serviço:
STATUS NU_Get_Remaining_Time (NU_TIMER * timer, UNSIGNED * restante_time);

Parâmetros:
timer - ponteiro para o bloco de controle do timer fornecido pelo usuário;
restante_time - um ponteiro para o armazenamento do valor de tempo restante, que é uma variável do tipo UNSIGNED .

Valor de retorno
NU_SUCCESS - a chamada foi concluída com sucesso;
NU_INVALID_TIMER - ponteiro de timer inválido.

Ligue para obter o tempo restante no Nucleus SE
Essa chamada de API suporta a funcionalidade completa da API do Nucleus RTOS.

Protótipo de chamada de serviço:
STATUS NUSE_Timer_Get_Remaining (temporizador NUSE_TIMER, U16 * tempo_ restante);

Parâmetros:
timer - índice (ID) do timer usado;
restante_time - um ponteiro para o armazenamento do valor de tempo restante, que é uma variável do tipo U16 .

Valor de retorno:
NUSE_SUCCESS - a chamada foi concluída com sucesso;
NUSE_INVALID_TIMER - índice de timer inválido;
NUSE_INVALID_POINTER - ponteiro nulo para o tempo restante ( NULL ).

Implementando uma leitura de timer no Nucleus SE
A variante de código de função da API NUSE_Timer_Get_Remaining () (depois de verificar os parâmetros) é trivialmente simples. O valor NUSE_Timer_Value [] é obtido e retornado na seção crítica.

Serviços Auxiliares de Temporizador


O Nucleus RTOS possui quatro chamadas de API que fornecem funções auxiliares relacionadas aos cronômetros: redefinição de um cronômetro, obtenção de informações sobre o cronômetro, obtenção do número de cronômetros em um aplicativo e indicação de todos os cronômetros em um aplicativo. As três primeiras funções são implementadas no Nucleus SE.

Reset do temporizador


Essa chamada de API redefine o timer para seu estado original e não utilizado. O timer pode ser ativado ou desativado após o término desta chamada. Só pode ser usado depois que o timer foi desativado (usando NUSE_Timer_Control () ). Na próxima vez que o timer for ativado, ele será inicializado com o parâmetro NUSE_Timer_Initial_Time [] . O núcleo RTOS permite fornecer um novo estado inicial e tempo de reagendamento, além de especificar a função de conclusão quando o timer for redefinido. No Nucleus SE, esses valores são definidos durante a instalação e não podem ser alterados, pois são armazenados na ROM.

Ligue para redefinir um timer no Nucleus RTOS

Protótipo de chamada de serviço:
STATUS NU_Reset_Timer (NU_TIMER * timer, VOID (* expiration_routine) (UNSIGNED), UNSIGNED initial_time, UNSIGNED reschedule_time, opção habilitada);

Parâmetros:
timer - um ponteiro para um timer reinicializável;
expiration_routine - indica a função que será executada quando o loop terminar;
initial_time - o número inicial de marcadores de tempo até o loop terminar;
reschedule_time - o número de marcações do timer até o segundo e subsequente ciclo ser concluído;
enable - o estado necessário do cronômetro após uma redefinição, pode assumir os valores NU_ENABLE_TIMER ou NU_DISABLE_TIMER .

Valor de retorno:
NU_SUCCESS - a chamada foi concluída com sucesso;
NU_INVALID_TIMER - ponteiro inválido para a unidade de controle do temporizador;
NU_INVALID_FUNCTION - ponteiro nulo para a função de conclusão ( NULL );
NU_INVALID_ENABLE - o estado especificado está incorreto;
NU_NOT_DISABLED - o timer já está em execução (deve ser parado antes de chamar esta função).

Ligue para redefinir o timer no Nucleus SE
Esta chamada de serviço da API suporta uma versão simplificada da funcionalidade principal da API do Nucleus RTOS.

Protótipo de chamada de serviço:
STATUS NUSE_Timer_Reset (temporizador NUSE_TIMER, ativação de OPTION);

Parâmetros:
timer - índice (ID) do timer de redefinição;
enable - o estado necessário após a redefinição, pode assumir os valores NUSE_ENABLE_TIMER ou NUSE_DISABLE_TIMER .

Valor de retorno:
NUSE_SUCCESS - a chamada foi concluída com sucesso;
NUSE_INVALID_TIMER - índice de timer inválido;
NUSE_INVALID_ENABLE - o estado especificado está incorreto;
NUSE_NOT_DISABLED - o timer já está em execução (ele deve ser parado antes de chamar esta função).

Implementando uma redefinição de timer no Nucleus SE
A versão do código de função da API NUSE_Timer_Reset () (depois de verificar os parâmetros e o estado atual) é bastante simples:

 NUSE_CS_Enter(); NUSE_Init_Timer(timer); if (enable == NUSE_ENABLE_TIMER) { NUSE_Timer_Status[timer] = TRUE; } /*  enable == NUSE_DISABLE_TIMER    FALSE */ NUSE_CS_Exit(); 

Uma chamada para NUSE_Init_Timer () inicializa o valor do tempo e limpa o contador de conclusão. Depois disso, se necessário, o valor do estado necessário é verificado e se o temporizador está ativado.

Informações do temporizador


Esta chamada de serviço permite que você obtenha um conjunto de informações do temporizador. A implementação do Nucleus SE difere do Nucleus RTOS, pois retorna menos informações, pois a nomeação de objetos não é suportada.

Solicite informações sobre o temporizador no Nucleus RTOS

Protótipo de chamada de serviço:
STATUS NU_Timer_Information (NU_TIMER * timer, CHAR * nome, OPTION * enable, expirações UNSIGNED *, UNSIGNED * id, UNSIGNED * initial_time, UNSIGNED * reschedule_time);

Parâmetros:
timer - um ponteiro para um timer sobre quais informações são solicitadas;
name - ponteiro para a região de 8 caracteres para o nome do timer;
enable - apontador para uma variável que leva o estado atual do ativador do timer: NU_ENABLE_TIMER ou NU_DISABLE_TIMER ;
vencimentos - um ponteiro para uma variável que controla o número de conclusões do ciclo do cronômetro desde sua última redefinição;
id - ponteiro para uma variável que leva o valor do parâmetro passado para a função final do ciclo do timer;
initial_time - um ponteiro para uma variável que assume um valor no qual o timer será inicializado após uma redefinição;
reschedule_time - um ponteiro para uma variável que leva um valor no qual o timer será inicializado após a conclusão.

Valor de retorno:
NU_SUCCESS - a chamada foi concluída com sucesso;
NU_INVALID_TIMER - ponteiro de timer inválido.

Ligue para obter informações sobre o temporizador no Nucleus SE
Essa chamada de API suporta a funcionalidade principal da API do Nucleus RTOS.

Protótipo de chamada de serviço:
STATUS NUSE_Timer_Information (timer NUSE_TIMER, OPTION * enable, U8 * expirações, U8 * id, U16 * tempo_inicial, U16 * tempo de reagendamento);

Parâmetros:
timer - índice do timer sobre o qual as informações são solicitadas;
enable - um ponteiro para uma variável que assume o valor TRUE ou FALSE , dependendo se o timer está ativado ou não;
vencimentos - um ponteiro para uma variável do tipo U8 que leva o valor do número de conclusões do timer desde sua última redefinição;
id - ponteiro para uma variável do tipo U8 que leva o valor do parâmetro passado para a função de conclusão do timer (retornará um valor vazio se as funções de conclusão estiverem desativadas);
initial_time - um ponteiro para uma variável do tipo U16 que assume um valor pelo qual o timer será inicializado após uma redefinição;
reschedule_time - um ponteiro para uma variável do tipo U16 , que assume o valor pelo qual o timer será inicializado após a conclusão.

Valor de retorno:
NUSE_SUCCESS - a chamada foi concluída com sucesso;
NUSE_INVALID_TIMER - índice de timer inválido;
NUSE_INVALID_POINTER - um ou mais parâmetros do ponteiro estão incorretos.

Implementando informações de timer no Nucleus SE
A implementação desta chamada de API é bastante simples:

 NUSE_CS_Enter(); if (NUSE_Timer_Status[timer]) { *enable = NUSE_ENABLE_TIMER; } else { *enable = NUSE_DISABLE_TIMER; } *expirations = NUSE_Timer_Expirations_Counter[timer]; #if NUSE_TIMER_EXPIRATION_ROUTINE_SUPPORT *id = NUSE_Timer_Expiration_Routine_Parameter[timer]; #endif *initial_time = NUSE_Timer_Initial_Time[timer]; *reschedule_time = NUSE_Timer_Reschedule_Time[timer]; NUSE_CS_Exit(); 

A função retorna o status do timer. O valor do parâmetro da função de finalização é retornado apenas se o suporte tiver sido ativado no aplicativo.

Obtendo o número de temporizadores


Essa chamada de utilitário retorna o número de temporizadores configurados no aplicativo. No Nucleus RTOS, esse valor pode mudar com o tempo e o valor de retorno exibirá o número atual de temporizadores. No Núcleo SE, o valor de retorno é definido durante a fase de montagem e não pode ser alterado.

Ligue para um contador de temporizadores no Nucleus RTOS

Protótipo de chamada de serviço:
NU_Established_Timers NÃO-ASSINADOS (VOID);

Parâmetros: nenhum

Valor de retorno: o número de temporizadores criados no sistema.

Chamando o contador do temporizador no núcleo SE
Essa chamada de API suporta a funcionalidade principal da API do Nucleus RTOS.

Protótipo de chamada de serviço:
U8 NUSE_Timer_Count (nulo);

Parâmetros: nenhum

Valor de retorno:
o número de temporizadores configurados no aplicativo

Implementação do contador de timer


A implementação desta chamada de API é bastante simples: o valor do símbolo #define NUSE_TIMER_NUMBER é retornado .

Estruturas de dados


Os cronômetros usam cinco ou sete estruturas de dados (localizadas na RAM ou ROM) que (como outros objetos do Nucleus SE) são um conjunto de tabelas cujo tamanho e número correspondem ao número de cronômetros configurados e parâmetros selecionados.

Eu recomendo fortemente que o código do aplicativo não use acesso direto a essas estruturas de dados, mas faça referência a elas através das funções de API fornecidas. Isso evitará a incompatibilidade com versões futuras do Nucleus SE e efeitos colaterais indesejados, além de simplificar a portabilidade de aplicativos para o Nucleus RTOS. A seguir, é apresentada uma visão geral detalhada das estruturas para simplificar o entendimento da chamada de serviço e do código de depuração.

Dados RAM


Esses dados têm a seguinte estrutura:
NUSE_Timer_Status [] é uma matriz do tipo U8 que possui uma entrada para cada timer configurado e armazena o status do timer (em execução ou parado: TRUE ou FALSE ).
NUSE_Timer_Value [] é uma matriz do tipo U16 que possui uma entrada para cada timer configurado e armazena o valor atual do contador do timer.
NUSE_Timer_Expirations_Counter [] - uma matriz do tipo U8 , contendo um contador do número de casos em que os temporizadores chegaram ao final do ciclo desde a última redefinição.

Todas essas estruturas de dados são inicializadas pela função NUSE_Init_Timer () quando o Nucleus SE é iniciado. Um dos artigos a seguir conterá uma descrição completa dos procedimentos de inicialização do Nucleus SE.

A seguir, estão as definições dessas estruturas de dados no arquivo nuse_init.c :
RAM U8 Timer_Status [NUSE_TIMER_NUMBER];
RAM U16 NUSE_Timer_Value [NUSE_TIMER_NUMBER];
RAM U8 NUSE_Timer_Expirations_Counter [NUSE_TIMER_NUMBER];

Dados ROM


A estrutura desses dados:
NUSE_Timer_Initial_Time [] é uma matriz do tipo U16 que possui uma entrada para cada timer configurado e armazena o valor de cada timer.
NUSE_Timer_Reschedule_Time [] é uma matriz do tipo U16 que possui uma entrada para cada timer configurado e armazena o valor no qual o timer será definido após a conclusão. Um valor zero indica que o timer é "único" e não deve reiniciar automaticamente.
NUSE_Timer_Expiration_Routine_Address [] - uma matriz do tipo ADDR que contém o endereço dos procedimentos de expiração do timer. Essa matriz existe apenas se o suporte ao procedimento de expiração do timer tiver sido ativado.
NUSE_Timer_Expiration_Routine_Parameter [] - uma matriz do tipo U8 que contém os valores do parâmetro que é passado para a função de conclusão do timer. Essa matriz existe apenas se o suporte para funções de conclusão tiver sido ativado.

Essas estruturas de dados são declaradas e inicializadas (estaticamente) no arquivo nuse_config.c , assim:

 ROM U16 NUSE_Timer_Initial_Time[NUSE_TIMER_NUMBER] = { /*   ------ */ }; ROM U16 NUSE_Timer_Reschedule_Time[NUSE_TIMER_NUMBER] = { /*      ------ */ }; #if NUSE_TIMER_EXPIRATION_ROUTINE_SUPPORT || NUSE_INCLUDE_EVERYTHING /*    */ ROM ADDR NUSE_Timer_Expiration_Routine_Address[NUSE_TIMER_NUMBER] = { /*     ------ */ /*   NULL */ }; ROM U8 NUSE_Timer_Expiration_Routine_Parameter[NUSE_TIMER_NUMBER] = { /*     ------ */ }; #endif 

A quantidade de memória para o timer


Como todos os outros objetos do Nucleus SE, a quantidade de dados necessária para os temporizadores é previsível.

A quantidade de dados na RAM (em bytes) para todos os cronômetros no aplicativo pode ser calculada da seguinte maneira:
NUSE_TIMER_NUMBER * 4

A quantidade de dados na ROM (em bytes) para todos os cronômetros no aplicativo, se o suporte para funções de conclusão estiver desativado, pode ser calculado da seguinte maneira:
NUSE_TIMER_NUMBER * 4

Caso contrário, é igual a:
NUSE_TIMER_NUMBER * (sizeof (ADDR) + 5)

Chamadas de API não realizadas


O Nucleus SE não implementa as três chamadas de API que podem ser encontradas no RTOS.

Criação de temporizador


Essa chamada de API cria um cronômetro. O Nucleus SE não precisa, pois os temporizadores são criados estaticamente.

Protótipo de chamada de serviço:
STATUS NU_Create_Timer (NU_TIMER * timer, CHAR * nome, VOID (* expiration_routine) (UNSIGNED), ID NÃO ASSINADO, NÃO ASSINADO tempo_inicial, horário não assinado, habilitação de opção);

Parâmetros:
timer - ponteiro para o bloco de controle do timer fornecido pelo usuário; será usado para controlar temporizadores em outras chamadas de API;
nome - ponteiro para o nome de 7 caracteres do cronômetro com um zero final;
expiration_routine - indica a função que deve ser executada após o término do timer;
id - um elemento de dados do tipo UNSIGNED passado para a função de terminação: este parâmetro pode ser usado para identificar temporizadores com a mesma função de terminação;
initial_time - indica o número inicial de tiques do timer antes que o timer termine;
reschedule_time - indica o número de marcações do timer até o segundo e subsequente ciclo ser concluído; se este parâmetro for igual a zero, o temporizador para apenas uma vez;
enable - este parâmetro pode assumir os valores NU_ENABLE_TIMER e NU_DISABLE_TIMER ; NU_ENABLE_TIMER ativa um timer depois que ele é criado; NU_DISABLE_TIMER deixa o cronômetro desativado; os cronômetros criados com o parâmetro NU_DISABLE_TIMER devem ser ativados chamando NU_Control_Timer .

Valor de retorno:
NU_SUCCESS - a chamada foi concluída com sucesso;
NU_INVALID_TIMER - um ponteiro nulo para uma unidade de controle de temporizador ( NULL ) ou a unidade de controle já está em uso;
NU_INVALID_FUNCTION - ponteiro nulo para o programa de conclusão ( NULL );
NU_INVALID_ENABLE - parâmetro de ativação inválido;
NU_INVALID_OPERATION - o parâmetro initial_time era zero.

Excluir timer


Essa chamada de API exclui um cronômetro criado anteriormente. O Nucleus SE não precisa, porque os temporizadores são criados estaticamente e não podem ser excluídos.

Protótipo de chamada de serviço:
STATUS NU_Delete_Timer (NU_TIMER * timer);

Parâmetros:
timer - ponteiro para o bloco de controle do timer.

Valor de retorno:
NU_SUCCESS - a chamada foi concluída com sucesso;
NU_INVALID_TIMER - ponteiro de timer inválido;
NU_NOT_DISABLED - O cronômetro especificado não está desativado.

Ponteiros do temporizador


Essa chamada de API forma uma lista seqüencial de ponteiros para todos os cronômetros no sistema. O Nucleus SE não precisa, pois os temporizadores são determinados por um índice simples, não por um ponteiro.

Protótipo de chamada de serviço:
UNSIGNED NU_Timer_Pointers (NU_TIMER ** pointer_list, UNSIGNED maximum_pointers);

Parâmetros:
pointer_list - ponteiro para uma matriz de ponteiros NU_TIMER ; será preenchido com ponteiros para temporizadores configurados no sistema;
maximum_pointers - o número máximo de ponteiros na matriz.

Valor de retorno:
O número de ponteiros NU_TIMER colocados na matriz.

Compatível com núcleo RTOS


Como com todos os outros objetos do Nucleus SE, meu objetivo era maximizar a compatibilidade do código do aplicativo com o Nucleus RTOS. Os temporizadores não são exceção e, do ponto de vista do usuário, eles são implementados da mesma maneira que no Nucleus RTOS.Há também uma certa incompatibilidade, que eu considerava admissível, pois, como resultado, o código se tornaria mais compreensível e mais eficiente em termos da quantidade de memória necessária. Caso contrário, as chamadas da API do Nucleus RTOS poderão ser portadas quase diretamente para o Nucleus SE.

Identificadores de objeto


No Nucleus RTOS, todos os objetos são descritos por uma estrutura de dados - um bloco de controle que possui um tipo de dados específico. Um ponteiro para esta unidade de controle é um identificador de timer. Decidi que no Nucleus SE é necessária uma abordagem diferente para o uso eficiente da memória: todos os objetos do kernel são descritos por um conjunto de tabelas na RAM e / ou ROM. O tamanho dessas tabelas é determinado pelo número de objetos configurados de cada tipo. O identificador de um objeto específico é o índice nesta tabela. Então eu defini NUSE_TIMER como o equivalente a U8, uma variável (não um ponteiro) desse tipo serve como identificador do cronômetro. Essa ligeira incompatibilidade é fácil de lidar se o código for portado do Nucleus SE para o Nucleus RTOS e vice-versa. Normalmente, nenhuma operação é executada nos identificadores de objeto além de mover e armazenar.
O núcleo RTOS também suporta temporizadores de nomeação. Esses nomes são usados ​​apenas para depuração. Excluí-os do Nucleus SE para economizar memória.

Tamanho do temporizador


No Nucleus RTOS, os temporizadores são implementados usando contadores de 32 bits. Decidi reduzir esse valor para 16 bits no Nucleus SE. Isso levou a melhorias significativas na eficiência e no tempo de execução da memória. O Núcleo SE pode ser modificado se o aplicativo exigir um tempo de execução mais longo.

Funções de conclusão


O Nucleus SE implementa funções de terminação de maneira semelhante ao Nucleus RTOS, somente elas podem ser desligadas completamente (o que permite economizar memória) e também são determinadas estaticamente. A função final não pode ser alterada quando o timer é redefinido.

Chamadas de API não realizadas


O núcleo RTOS suporta oito chamadas de serviço de timer. Destes, três não estão implementados no Nucleus SE. Uma descrição detalhada dessas chamadas, bem como os motivos dessa decisão, pode ser encontrada anteriormente neste artigo, na seção "Chamadas de API não realizadas".

O artigo a seguir examinará as interrupções.

Source: https://habr.com/ru/post/pt455072/


All Articles