Boas abordagens para implementar mais de uma função de tempo crítico usando um microcontrolador?

8

Qual é a filosofia ou abordagem adotada para implementar funções altamente críticas em microcontroladores, se houver alguma?

Estou trabalhando em um projeto que envolve uma forma de onda precisa de onda quadrada de frequência variável. Eu fiz isso usando um timer e uma função de interrupção. No entanto, mesmo para implementar isso corretamente, tive que calibrar o deslocamento para o número de ciclos de relógio realizados durante a rotina de serviço de interrupção. Eu imagino que essa precisão seja perturbada por ter outra forma de onda funcionando ao lado (digamos que a frequência precise ser alterada exatamente ao mesmo tempo). Ter um microcontrolador para cada uma dessas funções críticas parece um desperdício.

Tomemos outro exemplo, da implementação de uma função de relógio (como na hh: mm: ss). Não consigo imaginar que todos os microncontroladores / computadores de alto nível tenham um chip de relógio em tempo real dedicado apenas para acompanhar o tempo. No entanto, acho difícil imaginá-lo sendo medido com precisão usando o processador principal, que está ocupado atendendo uma infinidade de funções que ocorrem em intervalos assíncronos nesse meio tempo. Eu imagino que a contagem do tempo teria erros de deslocamento, que mudam dependendo das funções que estão sendo executadas.

Existe um processo ou abordagem de design para conter ou tolerar a precisão alcançável? Ou alguém tem alguma sugestão ou sugestão sobre onde eu poderia encontrar mais informações sobre isso?

azul da meia noite
fonte
Coisas que exigem RTC preciso geralmente possuem um chip ou subfunção dedicada com sua própria energia e cristal, a fim de acompanhar o tempo quando o dispositivo é desligado. O tempo é um grande aborrecimento.
Pjc50 02/03
Pare de usar uma arquitetura tão horrível (ou comece a usá-la corretamente) - os temporizadores de hardware não devem depender do tempo gasto na manutenção do ISR - desde que as recargas sejam feitas 'no tempo', isso não deve importar.
Spehro Pefhany
Qual microcontrolador? Permitiria respostas de melhor qualidade.
StainlessSteelRat
@SpehroPefhany Devo dizer que sou bastante inexperiente nisso. O problema que estou tendo com a onda quadrada é que gostaria que a frequência mudasse em cada transição de saída (que para duas ondas quadradas diferentes estaria em intervalos assíncronos e poderia até mesmo coincidir). Uma onda quadrada era uma parte menor de uma pergunta maior que eu tinha em mente. Na geração de formas de onda, como você implementaria mais de uma forma de onda analógica arbitrária? O sacrifício seria criar uma "taxa de amostragem" comum?
midnightBlue
@StainlessSteelRat Eu deliberadamente não especifiquei um microcontrolador específico, pois senti que a pergunta era bastante ampla. Para mim, parece que isso poderia se aplicar à arquitetura do processador em computadores grandes através de microcontroladores. Em parte, quero saber se existem recursos disponíveis para aprender como criar bons projetos / limitar o erro ao implementar mais de uma função que é sensível ao tempo.
midnightBlue

Respostas:

10

Para gerar ondas quadradas precisas, use o hardware. A maioria dos microcontroladores possui geradores PWM embutidos que podem fazer isso. Você define o período e o tempo em ciclos de relógio, e o hardware faz o resto. Para alterá-lo para uma nova frequência, escreva o novo período no registro do período e metade do período no registro do ciclo de serviço.

Quanto ao relógio em tempo real perder tempo devido a outra carga do processador, ele não funciona dessa maneira, a menos que seja muito mal escrito. Geralmente, o hardware seria usado para criar uma interrupção periódica de vários segundos, e o firmware se divide mais a partir daí. Isso funciona independentemente de quão ocupado o processador esteja, pois a interrupção é executada sempre que necessário. Enquanto a rotina de interrupção demorar uma pequena fração dos ciclos gerais, a maior parte do processador ainda será aplicada à tarefa em primeiro plano.

Também existem maneiras de manter o tempo pesquisando a intervalos um tanto desconhecidos. Você mantém o hardware atualizado e, sempre que atualiza o relógio, atualiza-o com base no número total de ticks decorridos. Contanto que essa rotina seja executada com frequência suficiente para que qualquer contador usado não seja encapsulado entre as execuções, nenhum tempo será perdido.

Olin Lathrop
fonte
Desculpa! Eu deveria ter sido mais amplo com a minha pergunta. Uma onda quadrada era apenas um exemplo particular de uma aplicação de tempo crítico que eu tinha em mente. Com o método gerador PWM que você mencionou, seria possível (se necessário) atualizar a frequência em cada transição de onda quadrada? E se você tivesse que fazer isso por duas ondas quadradas assíncronas? E as dez? Gostaria de saber se existem abordagens gerais de design para essas coisas. Os métodos que você menciona sobre interrupção e sondagem periódica para atualizar o relógio certamente estão lançando alguma luz.
midnightBlue
1
@mid: A maioria dos micros pode interromper no início de um período PWM. Alguns possuem registros com buffer duplo, para que você possa atualizar os parâmetros durante um período e depois fazer com que eles entrem em vigor no início do próximo período. Alguns micros podem alimentar o PWM via DMA. Eu usei isso uma vez para ter o hardware automaticamente no pontilhamento.
21716 Olin Lathrop
3

A palavra-chave aqui é "suporte de hardware". Para qualquer coisa séria, você precisará de hardware de suporte no µC. O periférico integrado mais comum são os circuitos de timer, que são executados com relativa precisão e sem interferência de outras operações da CPU.

Com base nisso, você pode ter muitas funções executadas em tempo médio, tão precisas quanto a fonte de relógio do seu controlador.

Mas: como você já deve ter experimentado, além da precisão de médio ou longo prazo, também há sempre instabilidade de tempo envolvida no manuseio de eventos de hardware por software (incluindo coisas como excesso de temporizador). Isso é causado por diferentes estados possíveis de execução no momento em que um evento ocorre, resultando em atrasos variados até que a resposta real ao evento possa ocorrer.

Portanto, a linha inferior é: Para qualquer coisa com requisitos de instabilidade de alta velocidade ou quase zero, o suporte de hardware é essencial. Muitos periféricos de hardware estão incluídos na maioria dos µCs, como UARTs & c, e quanto mais poderoso e caro o µC, mais o hardware de suporte geralmente é incorporado. Se o seu µC não fornecer o hardware necessário, você deverá considerar um hardware externo dedicado para a tarefa.

JimmyB
fonte
Entender a instabilidade é fundamental - você pode ter vários temporizadores de hardware, e todos acompanharão independentemente, mas se todos acionarem uma interrupção ao mesmo tempo, nem todos poderão ser reparados de uma só vez.
Pjc50 02/03
2

Faça o máximo que puder com o hardware, especialmente para funções críticas com muito tempo. Todos os microcontroladores têm temporizadores / contadores criados especificamente para contar e registrar eventos.

Além disso, essa é realmente uma questão muito ampla. Portanto, não há uma boa resposta.

A única resposta verdadeira é a experiência. Experimente, analise, enfatize, corrija. Você precisa identificar áreas de código com alto uso. 20% do software em execução 90% do tempo, significa que todas as instruções removidas melhoram o desempenho.

Um bom design sempre equilibrou hardware, software e memória. Isso se aplica a todos os microprocessadores, mas especialmente aos microcontroladores. Maximize um ou use ineficientemente um e você terá um produto ruim. À medida que as densidades de silício aumentam, mais e mais recursos são incluídos no hardware dos microcontroladores. Mas mais recursos significam mais expectativas. Dupla memória interna e você adicionará algum recurso que a utilize.

Todos os ISRs têm custos indiretos, o que depende dos registros usados ​​pelo ISR. Se a latência para salvar o estado da máquina for significativa em comparação com a manutenção do ISR para funções altamente críticas, seu design poderá não ser escalável. Portanto, o consenso geral de respostas para o uso de hardware.

O uso de interrupções de software pode diminuir o inchaço do estado da máquina ISR.

// Timer0 ISR
Temp = Temp + 1
if (Temp == 150)
    call Inc_Seconds()

Todos os registros de Inc_Seconds () devem ser enviados por push, quando usados ​​apenas uma vez a cada 150 ciclos.

// Timer0 ISR
Temp = Temp + 1
if (Temp == 150)
    _Software_Interrupt
...
// Software_Interrupt ISR
    call Inc_Seconds()

Agora, a ocorrência de latência ocorre apenas uma vez a cada 150 ciclos.

Se você implementar um relógio em tempo real em hh: mm: ss, isso importa se estiver a 50ms de distância. Ninguém detectaria o erro. Isso certamente não é uma preocupação operacional em tempo real.

Quanto aos eventos que devem ocorrer ao mesmo tempo. Eles devem? Se necessário, o design do hardware deve cuidar disso. Caso contrário, algum comprometimento de software deve ocorrer. Se você não pode definir dois bits ao mesmo tempo, defina um bit. A próxima instrução define a outra. Precisão de um ciclo de clock nos procesores RISC. Eu diria que isso foi bom o suficiente.

StainlessSteelRat
fonte
0

Para a forma de onda quadrada, você deve usar um periférico PWM que é PLLM com o seu XTAL usando algum tipo de contador para saber quando dar um ciclo (para definir a pouca frequência). Cada folha de dados dirá como fazer isso :)

Para manter o tempo , sim, você precisará de um RTC para fazê-lo com precisão, a menos que opcodes de montador e autor, para que você saiba à mão o tempo exato do exec de cada instrução em qualquer caminho do exec. Provavelmente, também lançará uma nova luz sobre a afirmação testada e verdadeira de 'goto é considerado prejudicial'.

AlexanderBrevig
fonte
3
Seus comentários sobre o software RTC seriam aplicáveis ​​apenas às soluções implementadas de forma descuidada. Uma maneira sã e confiável de fazer isso é usar um timer de hardware para gerar uma interrupção uma vez a cada 1 ms (ou 10 ms). Na rotina de serviço, tem uma variável de contador estático que conta, em seguida, o número de interrupções até 1000 (ou 100). Quando a contagem total for atingida, redefina o contador e aumente o contador de segundos. A cada 60 segundos, você redefine a variável do contador de segundos para zero e incrementa a variável do contador de minutos. Estenda isso até meses e anos, se necessário.
Michael Karas