Posso ter 1 núcleo de processador apenas para o meu programa?

12

Preciso calcular a diferença horária entre a borda do sinal alto -> baixo e baixo -> alto nos pinos GPIO. Eu escrevi um programa simples que faz isso. Depois de executá-lo por algum tempo, fiquei muito feliz com o resultado (variações de 0,01 s). Mas de tempos em tempos havia um erro de 0,5 s. Eu estava pensando que isso pode ser devido a algum outro processo do sistema em execução naquele momento. Então, minha pergunta é:

Posso reservar um núcleo de processador apenas para o meu programa e permitir outros 3 núcleos para o sistema?

Estou usando o Raspbian Jessie Lite, então acho que 3 núcleos serão suficientes para executá-lo.

NonStandardModel
fonte
4
Presumo que você esteja pesquisando em um loop o status do pino GPIO. Isso é altamente suscetível a como o sistema operacional decide executar seu programa, que passará a maior parte do tempo mantendo a CPU ocupada sem fazer nada realmente útil. Você pode procurar uma maneira de configurar uma interrupção em um determinado pino GPIO, que pode ser usado para deixar seu programa dormir entre as bordas do sinal nos pinos GPIO.
Florian Castellane
4
Não sabe qual é o seu projeto, mas às vezes um microcontrolador é mais adequado, especialmente quando você precisa de um sistema mais parecido com o tempo real. O Arduino oferece muitas opções e você pode escrever seu programa em C / C ++.
SnakeDoc
@Florian Há uma função no RPi.GPIO que é semelhante à interrupção. Ele bloqueará o programa até que a borda seja detectada (fonte: sourceforge.net/p/raspberry-gpio-python/wiki/Inputs ).
NonStandardModel
@SnakeDoc Eu sei que o microcontrolador é melhor. Eu esperava evitá-lo, porque não preciso de precisão de microssegundos. 1/100 de segundo é mais que suficiente. Também preciso da diferença de horário, por isso, se houver um atraso, espero que seja o mesmo para iniciar e parar. Se isso não funcionar, tenho que usar o microcontrolador conectado ao RPi para armazenar os dados.
NonStandardModel
1
Ou instale um sistema operacional em tempo real no PI. O problema com sua instalação é que depende de um "melhor esforço" do sistema operacional. Dependendo do que mais está acontecendo ao mesmo tempo em que seu programa solicita acesso privilegiado aos GPIOs, ele pode ficar na fila atrás de outras tarefas que o sistema operacional está executando naquele instante. Seu programa userland terá uma prioridade mais baixa que as tarefas do sistema. Há também preempção, que meios durante a execução do seu programa pode ser "uma pausa e 'pôr de lado' pelo sistema operacional para outro processo de execução, ou seja, suas observações de cronometragem pode ser distorcida.
SnakeDoc

Respostas:

13

Dedicar um núcleo provavelmente é um exagero.

Eu sugiro que você tente minha biblioteca pigpio . Por padrão, o tempo de GPIO mudará para 10µs.

Como um teste rápido, sugiro que você observe este exemplo Python , que imprimirá qualquer transição no nível GPIO e o tempo em microssegundos desde a última transição nesse GPIO.

O pigpio não está instalado por padrão no Jessie Lite. Instale a versão mais recente do site vinculado ou instale a versão mais antiga nos repositórios.

sudo apt-get install pigpio python-pigpio python3-pigpio

pigpio - Library for Raspberry Pi GPIO control
python-pigpio - Python module which talks to the pigpio daemon (Python 2)
python3-pigpio - Python module which talks to the pigpio daemon (Python 3)
joan
fonte
Vou tentar sua biblioteca pigpio. Agora eu tenho que terminar outro projeto, mas voltarei a isso. Vou relatar em algumas semanas. Obrigado!
NonStandardModel
4

Você pode bloquear seu programa em um núcleo usando schedutilso descrito neste artigo da Cyberciti :

sudo apt-get install schedutils
sudo taskset -c 3 -p 13545  # Lock PID 13545 to core 3

Outros processos ainda podem ser agendados no mesmo núcleo. Portanto, a segunda coisa a fazer é garantir que seu comando seja executado com a maior prioridade usando o comando nice (isso informará ao kernel do Linux que outros processos devem ser antecipados, se necessário). Inicie seu programa desta maneira:

nice -n -20 your-program

Existem outros motivos possíveis para os seus problemas de tempo. Não é tão fácil fazer nada sobre:

  • Se você estiver programando em Python, há um coletor de lixo que às vezes pausa o programa para liberar memória não utilizada.
  • Interrupções fazem com que a CPU lide com algo mais do que você deseja. Por exemplo, pacotes de rede ou outra entrada / saída.
  • Se o seu programa estiver dormindo muito, pode haver outros processos que preenchem os caches da CPU (cache L1 / L2). Isso força você a esperar pelo acesso à RAM.
    • Pior ainda, se sua RAM estiver cheia, para que seu processo seja trocado para o disco porque os cartões SD são vagarosamente.

Existem maneiras de tornar seu processo em tempo real , o que significa que ele será executado com certas garantias de tempo. O problema disso é que tudo o mais pode ser mais lento e esse é um tópico complexo. Se você quiser descer por essa toca de coelho, sugiro que comece a ler sobre processos em tempo real no Linux .

Emil Vikström
fonte
2
Em vez de agradável, seria melhor dar prioridade ao processo em tempo real, o que garantiria que ele fosse executado preferencialmente a processos não em tempo real.
Joan
Bom ponto, vou acrescentar uma nota sobre isso.
Emil Vikström
1
"gc.disable ()" o que acontece se você desabilitar o coletor de lixo?
21417 Keine
@ Keine Você pode obter um vazamento de memória. Digamos que você tenha um objeto A que tenha uma variável que aponte para B. O Python rastreará essa referência como um número, pois sabe que B tem 1 objeto apontando em sua direção. Remova A quando não precisar mais dele. A contagem de referência para B diminuirá e, se atingir 0, o Python também poderá liberar B. Isso é chamado de contagem de referência. Mas agora diga que B tem uma referência de volta a A. Agora você tem um cluster de objetos apontando um para o outro. Nenhum deles atingirá 0 e será liberado. O GC pode encontrar esses clusters e removê-los quando o programa principal não aponta "para dentro" do cluster.
Emil Vikström
1
Vou adicionar as sugestões que você fez ao meu projeto. Mas espero evitar tópicos muito complexos. Nesse caso, suponho que seja melhor fazer uma detecção de interrupção por microcontrolador e conectá-lo ao RPi apenas para salvar dados. Obrigado!
NonStandardModel
2

Como você está tendo requisitos de tempo, o Raspberry Pi não é mais a plataforma apropriada para isso. Não é uma plataforma em tempo real e o tempo pode ser alterado por várias fontes diferentes de interferência.

Em vez disso, você deve usar um microcontrolador para medir esse tempo, de preferência usando interrupções, e passar as informações para o Pi posteriormente.

Maxthon Chan
fonte
1
Não é possível obter interrupções nos pinos GPIO em um Raspberry Pi?
Florian Castellane
Certamente, isso depende se houver alguma outra parte dos requisitos de design que torne uma máquina Linux mais apropriada que uma MCU. O RPi é capaz de lidar bem com essa tarefa, assim como um MCU com clock de 10 MHz.
Sean Houlihane 14/02
1

Conforme sua exigência, não acho que você precise usar um processador de núcleo único. O que você precisa é garantir que seu programa seja executado o tempo todo. Para conseguir isso, você pode definir a prioridade do seu programa muito alta, para que ele não seja perturbado por nenhum outro processo.

Tanto quanto eu conheço o SO (General Purpose OS), que usamos, não foi projetado para ser usado em sistemas em tempo real; portanto, se você deseja executar seu processo em tempo real, para que nenhum outro processo o perturbe, é necessário para um sistema operacional em tempo real (RTOS). Talvez eles apresentem a seleção principal. :)

Vishwajeet Vishu
fonte
1
Existem bons RTOS gratuitos por aí?
21417 Keine
RTLinux e Vxworks são exemplos de RTOS e também são bons. Mas você precisa estudar sobre o sistema operacional (qual foi o foco de sua criação) antes de instalar, para que ele possa satisfazer suas necessidades.
Vishwajeet Vishu