Raspberry Pi RP2040 OS em tempo real
Projeto de aprendizado para criar um suporte de sistema operacional preventivo e em tempo real para o RP2040. O código do agendador está escrito em C para permitir uma fácil experimentação. Os recursos atuais incluem:
Preventivo
Prioridade do tópico
Espera/atrasos
Rendimento cooperativo
Mutexes
Cheques de pilha (questões de interrupção)
Os tempos de alternância de contexto no pico de 125MHz com quatro threads são:
Sem otimizações
| Tempo de contexto |
|---|
| Coleção de estatísticas: | 5.8 nós |
| Com estatísticas Collecton: | 9.3 nós |
| Com estatísticas/cheques de pilha: | 9,9 nós |
O código de exemplo possui um "top" simples, como a saída a cada dois segundos na porta serial. Os valores ctx = são a porcentagem de tempo gasto no comutador de contexto. UTIL = é a porcentagem de tempo gasto em um thread e ocioso = por cento gasto em um dos fios ociosos de núcleos.
O indicador S ou de status é simplesmente: W-Waiting, R-Running, Zombied ou Thread retornado.
Hora da parede 0:56:38
CPU0 CTX = 0,095%, UTIL = 1,229% de marcha lenta = 98,771%
CPU1 CTX = 0,074%, UTIL = 0,081% IDLE = 99,919%
Thrd Nome S Pri CPU LastCPU
0 Red LED W 100 0,001% 1
1 LED verde W 100 0,011% 0
2 relatório r 255 1,115% 0
3 Spinner Z 150 0,000% 0
A implementação atual consiste em três arquivos e um exemplo principal:
RP2040OS.H Cabeçalho do OS
implementação RP2040OS.C em C
função de implementação func.s na montagem
exemplo main.c
Um caso de uso simples para iniciar dois threads:
#include "rp2040.h"
estático uint32_t blink1stack [128];
Void Blink1 () {
while (true) {
setGpio (led_pin1);
atraso (300);
clrgpio (led_pin1);
atraso (300);
}
}
estático uint32_t blink2stack [128];
Void Blink2 () {
while (true) {
setGpio (led_pin2);
atraso (300);
clrgpio (led_pin2);
atraso (300);
}
}
int main () {
stdio_init_all ();
gpio_init (led_pin1);
gpio_set_dir (led_pin1, gpio_out);
gpio_init (led_pin2);
gpio_set_dir (led_pin2, gpio_out);
AddThread ("Red LED", Blink1, Blink1Stack, Sizeof (Blink1Stack), 100);
AddThread ("Green LED", Blink2, Blink2Stack, Sizeof (Blink2Stack), 100);
setupSched (); // sem retorno
}
Tamanhos de pilha ###
Esteja ciente de que quanto mais funções da biblioteca você ligar, mais espaço de pilha você pode precisar. Por exemplo, o uso da função Printf exigirá mais de 256 valores de 32 bits em uma pilha para lidar com os requisitos de memória de funções. Se a unidade em teste for anexada a um depurador, o STACK_WATCH poderá ser ativado e acionará um BKPT (ponto de interrupção) no depurador se algum dos valores de guarda de pilha for modificado, indicando uma possível condição de estouro.
### osconfig.h
Este arquivo permite personalizar como o agendador funciona. Por padrão, ele é definido como as especificações do RP2040 ou dois núcleos. Definir o user_tasks no valor correto do seu aplicativo minimizará a quantidade de memória usada. Informações adicionais sobre threads, como nomeação, estatísticas e monitoramento da pilha, também consomem um pouco mais de memória, mas podem ser muito úteis na depuração.
O contextsw_pin pode ser usado com um osciloscópio para ver os interruptores de contexto em tempo real.
Prédio
exportar pico_sdk_path = caminho para o seu pico-sdk
Copie o $ pico_sdk_path/externa/pico_sdk_import.cmake no diretório principal.
$> mkdir build
$> CD Build
$> cmake .. -dcmake_build_type = Debug
$> make