Raspberry Pi Pico Dual Core Programming

Tempo de leitura: 6 minutes

Neste post, aprenderemos como usar o dual core do Raspberry Pi Pico usando o MicroPython. Vamos discutir como fazer a programação dual core do Raspberry Pi Pico. Raspberry Pi Pico é uma placa de baixo custo e alto desempenho baseada no chip microcontrolador Raspberry Pi RP2040. O chip RP2040 contém um microcontrolador dual-core córtex M0+ que pode operar até 133MHz. Este chip oferece 26 pinos GPIO multifuncionais e 2 MB de memória Flash integrada.

Pré-requisitos Raspberry Pi Pico Programação GPIO

Para começar, verifique se você já realizou os seguintes procedimentos:

  • Baixou e instalou a versão mais recente do Python 3 no seu PC.
  • Baixou e instalou a versão mais recente do Thonny IDE.
  • Configure o MicroPython no Raspberry Pi Pico.

 

RP2040 Dual Core Processor

O chip RP2040 no Raspberry Pi Pico possui dois núcleos de processador M0+, conforme mostrado na visão geral do sistema do chip RP2040 abaixo, retirado de sua folha de dados.

Core

Um núcleo é uma unidade funcional no processador capaz de executar o código do programa. Ao ter vários núcleos em um processador, podemos executar vários segmentos do código simultaneamente. Para Raspberry Pi Pico, por padrão, o core0 executa o código sempre que programamos nossa placa, enquanto o segundo núcleo fica em standby. O uso do segundo núcleo nos permite tornar nossos projetos Raspberry Pi Pico mais poderosos usando completamente um thread de execução separado.

Na figura abaixo você pode ver a representação dos dois núcleos.

Cada núcleo executa separadamente seu próprio código de forma independente. Ambos têm código de programa e espaço de memória separados. No entanto, há casos em que os núcleos podem compartilhar código de programa e espaço de memória. O compartilhamento de código não é problemático porque buscar código é uma instrução de leitura e não cria uma condição de corrida. No entanto, compartilhar o mesmo local para dados é problemático, pois cria a possibilidade de existir uma condição de corrida onde os acessos mútuos à memória não são garantidos. Portanto, os núcleos não devem compartilhar memória diretamente. Para que os núcleos se comuniquem entre si, a placa Raspberry Pi Pico possui duas estruturas FIFOs (First In First Out) separadas. Eles atuam como um mecanismo de comunicação entre os núcleos. Apenas um FIFO é gravável por core0 e apenas um FIFO é gravável por core1. Dessa forma, nenhum núcleo está gravando no mesmo local ao mesmo tempo.

 

Exemplo de programação de núcleo duplo Raspberry Pi Pico

Agora vamos iniciar nosso projeto no qual usaremos ambos os núcleos do Raspberry Pi Pico no MicroPython com a ajuda do Thonny IDE.

Usaremos o dual core do Raspberry Pi Pico para controlar dois LEDs. Isso será alcançado usando multithreading. Vamos controlar vários programas simultaneamente usando esta técnica (um thread por núcleo).

Para realizar este projeto, precisamos dos seguintes equipamentos:

  • Protoboard
  • Dois LEDs
  • Dois resistores de 220 ohms
  • Fios de conexão
  • Placa Raspberry Pi Pico

Conexão de LEDs com Raspberry Pi Pico

Conecte os componentes conforme mostrado no diagrama esquemático abaixo:

Agora faça as conexões do Raspberry Pi Pico com os dois LEDs. Conecte o GP0 do Raspberry Pi Pico com o terminal do ânodo do LED vermelho através de um resistor limitador de corrente de 220 ohms. Além disso, certifique-se de conectar o terminal catódico do LED vermelho com o pino terra da placa. Da mesma forma, conecte o GP1 do Raspberry Pi Pico com o terminal do ânodo do LED verde através de um resistor limitador de corrente de 220 ohms. Além disso, certifique-se de conectar o terminal catódico do LED verde com o pino terra da placa.

 

Script MicroPython de programação dual core

Primeiro, crie um novo arquivo clicando em File > New no Thonny IDE.

Copie este código para a nova janela sem título aberta:

import machine
import _thread
from time import sleep

led_red = machine.Pin(0, machine.Pin.OUT)
led_green = machine.Pin(1, machine.Pin.OUT)

sLock = _thread.allocate_lock()

def CoreTask():
    while True:
        sLock.acquire()
        print("Enter second Thred")
        sleep(1)
        led_green.high()
        print("Green LED is turned ON")
        sleep(2)
        led_green.low()
        print("Green LED is turned OFF")
        sleep(1)
        print("Exit second Thread")
        sleep(1)
        sLock.release()
_thread.start_new_thread(CoreTask, ())

while True:
    sLock.acquire()
    print("Enter main Thread")
    led_red.toggle()
    sleep(0.15)
    print("Red LED toggling...")
    sleep(1)
    print("Exit main Thread")
    sleep(1)
    sLock.release()

Como o código funciona?

Nesta seção, veremos como os códigos funcionam.

Importando MicroPython GPIO e bibliotecas de tempo

No MicroPython, um módulo de máquina contém classes de diferentes periféricos de um microcontrolador como GPIO, ADC, PWM, I2C, SPI, etc. Neste tutorial, estamos usando pinos GPIO do Raspberry Pi Pico. Portanto, importaremos a classe GPIO de um módulo de máquina. Portanto, aqui importamos a classe Pin do módulo da máquina. Podemos criar várias instâncias da classe Pin para configurar diferentes pinos GPIO do Raspberry Pi Pico.

O módulo time no MicroPython contém diferentes métodos como delay, sleep, etc. Por exemplo, podemos usar um método sleep() para inserir atrasos em nosso script MicroPython.

Além disso, importaremos o módulo _thread, pois temos que usar dois núcleos do Raspberry Pi Pico.

import machine
import _thread
from time import sleep

Criamos duas instâncias do objeto Pin: “led_red” e “led_green”.

led_red = machine.Pin(0, machine.Pin.OUT)
led_green = machine.Pin(1, machine.Pin.OUT)

Aqui a classe Pin() recebe dois parâmetros:

  • O primeiro é o número do pino para o qual queremos configurar em diferentes modos, como entrada, saída, etc.
  • O segundo é o modo de pino, como entrada digital (Pin.IN), saída digital (Pin.OUT), dreno aberto (OPEN_DRAIN).

A função a seguir retorna um novo objeto de bloqueio que especificamos como ‘sLock’. Inicialmente, o bloqueio é desbloqueado. Esta função será responsável por fornecer um bloqueio de semáforo para ambas as threads.

sLock = _thread.allocate_lock()

Em seguida, definimos uma função chamada CoreTask(). Esta função será executada em um núcleo diferente com um único thread. Primeiro, obteremos o bloqueio do semáforo usando o método Acquir() no objeto sLock. Em seguida, vamos acender o LED verde por dois segundos e depois desligá-lo. Enquanto isso, imprimiremos mensagens relevantes no terminal Thonny shell indicando o status do processo. Após a conclusão do encadeamento, o bloqueio do semáforo é liberado usando o método release() no objeto sLock.

def CoreTask():
    while True:
        sLock.acquire()
        print("Enter second Thred")
        sleep(1)
        led_green.high()
        print("Green LED is turned ON")
        sleep(2)
        led_green.low()
        print("Green LED is turned OFF")
        sleep(1)
        print("Exit second Thread")
        sleep(1)
        sLock.release()
_thread.start_new_thread(CoreTask, ())

Além disso, chamaremos a função _thread.start_new_thread() para iniciar uma nova thread. Levará em dois parâmetros. O primeiro parâmetro é a função que definimos e o segundo parâmetro são os argumentos que não são nenhum no nosso caso.

_thread.start_new_thread(CoreTask, ())

Dentro do loop while, iremos novamente adquirir outro bloqueio de semáforo e então alternar o LED vermelho. Depois disso, o bloqueio será liberado. Observe que o thread principal continuará em execução até que seja concluído.

while True:
    sLock.acquire()
    print("Enter main Thread")
    led_red.toggle()
    sleep(0.15)
    print("Red LED toggling...")
    sleep(1)
    print("Exit main Thread")
    sleep(1)
    sLock.release()

 

Demonstração

Após copiar o código para um novo arquivo no Thonny, clique no ícone “Salvar”. Isso oferece duas opções para salvar esse arquivo no seu computador ou diretamente em seus dispositivos, como o Raspberry Pi Pico. Isso significa que também podemos enviar arquivos diretamente para um dispositivo. Mas, por enquanto, salve-o em seu computador. Você pode selecionar qualquer local em seu computador onde deseja salvar este arquivo. Salve-o como blink.py

Você também pode usar qualquer outro nome, apenas certifique-se de que ele termine em .py

Agora clique no botão “Executar” para fazer o upload do código para o Raspberry Pi Pico. Antes de fazer o upload do código, certifique-se de que a placa correta esteja selecionada.

O terminal Thonny shell exibirá todos os processos que estão ocorrendo atualmente:

 

 

Visits: 5 Visits: 1126040