Unidade 3 / 9

Sistemas embarcados e código de microcontrolador

Ganhos:

  • Capacidade de definir requisitos de registro, interrupção e temporização para o microcontrolador com um prompt claro
  • Capacidade de verificar o código C/Arduino produzido pela IA em termos de configurações de registro, buffer overflow e restrições de tempo real
  • Capacidade de aplicar o hábito de verificar o código gerado medindo-o em hardware (osciloscópio, porta serial)

O desenvolvimento de sistemas embarcados é onde o software e o hardware se cruzam: definir um bit de registro incorretamente, manter uma interrupção por muito tempo ou transbordar um buffer causará falhas estranhas e difíceis de reproduzir no campo, mesmo que o código seja "compilado" e executado. A IA é verdadeiramente um acelerador nesta área; Pode produzir esqueletos iniciais, funções de abstração de hardware, máquinas de estado e rotinas de comunicação. Mas a IA não vê a folha de dados da sua placa, não conhece a frequência do seu clock e não percebe suas restrições de tempo real. Nesta unidade, abordaremos como definir claramente o trabalho do microcontrolador para IA, como verificar o código C/Arduino gerado e por que você deve medir tudo em hardware.

Definindo claramente o requisito: registro, corte, tempo

Dizer à IA para “acender um LED” não funcionará; Qual placa, qual pino, qual frequência de clock, qual tempo? Ao atribuir uma tarefa incorporada à IA, use esta estrutura: hardware (família MCU, relógio, pino), função (o que acontecerá), restrição (tempo, energia, memória) e interface (registro, HAL, biblioteca Arduino).

Alerta Fraco/Prompt Forte

FRACO: "Produza PWM com STM32." (Resultado: qual temporizador, qual frequência, qual pino não está claro; geral, código nomeado de registro provavelmente errado.) FORTE: "Produza PWM de serviço ajustável de 20 kHz, 0-100% no TIM3 CH1 (PA6) para STM32F103 (relógio do sistema de 72 MHz). Escreva no nível do registro (não HAL). - Valores do pré-escalador e ARR para 20 kHz CALCULE e mostre o cálculo na linha de comentários. - Defina o dever com um parâmetro de função entre 0-100 - Comente cada bit de registro que você usa. Observe que os valores mudarão se sua suposição de clock estiver errada.

A diferença é que o prompt poderoso faz com que o modelo mostre o cálculo e revele a suposição do relógio. Assim, você pode verificar os valores do prescaler/ARR de forma independente:

Para PWM de 20 kHz (relógio de 72 MHz):Timer_clock = 72 MHzSe quisermos prescaler = 72-1 → counter clock = 1 MHzARR = (1 MHz / 20 kHz) - 1 = 50 - 1 = 49Verificação: 1e6 / (49+1) = 20 000 Hz ✓

Auditoria de código de IA: o que procurar?

Só porque o código gerado é compilado não significa que funcione corretamente. Siga esta lista de verificação:

área de controle

O que procurar

Configurações de registro/bit

Exatamente compatível com folha de dados, máscara de bits correta

Interrupção (ISR)

É curto? Sem atraso no bloqueador? Volátil é usado?

buffer/matriz

Existe controle de fronteira? Risco de transbordamento?

tempo

Com atraso ou temporizador? A restrição de tempo real foi atendida?

Tipo e largura

Estouro de 8/16/32 bits, confusão assinada/não assinada

poder/cão de guarda

Cão de guarda de alimentação de loop infinito?

As rotinas de serviço de interrupção (ISR) são a fonte mais comum de erros. A IA às vezes coloca delay() ou loop longo dentro do ISR. Isso leva à perda de outras interrupções e à redefinição do watchdog. Regra: o ISR deve ser o mais curto possível; A tarefa principal deve ser configurar um sinalizador e movê-lo para o loop principal.

// FRACO (AI às vezes produz isso): Função bloqueadora em ISR void TIM3_IRQHandler(void) { if (TIM3->SR & TIM_SR_UIF) { TIM3->SR &= ~TIM_SR_UIF; sensor_leitura(); // pode demorar muito - BAD CASE_Delay(10); // atraso no ISR - MUITO RUIM }}// FORTE: ISR curto; o trabalho é movido para o loop principal volátil uint8_t tick_flag = 0; // volátil CONDITIONvoid TIM3_IRQHandler(void) { if (TIM3->SR & TIM_SR_UIF) { TIM3->SR &= ~TIM_SR_UIF; tick_flag = 1; //apenas definir flag }}// no loop principal:if (tick_flag) { tick_flag = 0; sensor_leitura(); }

Cuidado: Qualquer variável compartilhada entre a interrupção e o loop principal deve ser volátil. Caso contrário, o compilador poderá armazenar em cache a variável no registrador e perder a atualização. A IA muitas vezes esquece essa palavra-chave; Procure-o especificamente ao ler o código.

Estouro de buffer e erros de tipo

A IA pode copiar dados da porta serial para um array de tamanho fixo sem verificação de limites. Em um sistema embarcado, isso significa destruir a memória contígua e travamentos inexplicáveis. Certifique-se de que o limite seja verificado em cada strcpy, índice de array e buffer DMA. Da mesma forma, um contador de 8 bits é redefinido após 255; A IA pode ignorar isso e confiar em uma conta transbordante.

Verificação em hardware: “Funcionamento” é medido, não presumido

Num sistema embarcado, a evidência mais confiável é o medidor, não o compilador. Verifique o código gerado destas três maneiras:

  1. Osciloscópio/analisador lógico: mede a frequência PWM, o tempo do sinal e a forma de onda de comunicação. Se você quisesse 20 kHz, veja 20 kHz na tela.
  2. Log da porta serial (UART): imprima valores de variáveis, transições de estado e contadores de erros e compare com o comportamento esperado.
  3. Testes de limite e de estresse: teste se o sistema resiste à carga mais alta, aos dados mais rápidos e ao pior momento.

Se o valor medido não estiver de acordo com o cálculo, a suposição do relógio, o valor do prescaler ou a configuração do registro estão incorretos; perseguir.

Mini Estojo

Uma equipe de estudantes faz com que a IA imprima um código de medição de distância com um sensor ultrassônico HC-SR04. O código compila mas a distância sempre dá valores ridículos. Ao conectá-lo ao osciloscópio, eles veem que a perna do eco calcula seu tempo em milissegundos, em vez de microssegundos; AI usou milis() em vez de micros(). Esse erro de uma palavra confundiu toda a medição por um fator de 1.000. Quando eles imprimem o tempo de eco bruto no registro serial e o comparam com uma régua real, eles encontram o erro e o corrigem. Lição: o código compilado não é o código correto; A medição no hardware revela o erro imediatamente.

Erros Comuns

  • Aceitar nomes de registradores e máscaras de bits sem compará-los com a folha de dados.
  • Permitindo atraso de bloqueio ou processamento longo dentro do ISR.
  • Esquecendo a volatilidade em variáveis ​​compartilhadas.
  • Ignorar verificação de limites de buffer e array; não vendo o transbordamento.
  • Confiar nas suposições de frequência e tempo do clock sem verificá-las.
  • Considerando o código "funcionando" sem medi-lo com osciloscópio/registro serial.

Em resumo

  • Defina claramente a tarefa incorporada em termos de hardware, função, restrições e interface.
  • Faça com que a IA calcule valores de tempo, como prescaler/ARR, e verifique-os de forma independente.
  • Mantenha os ISRs curtos, use voláteis em variáveis ​​compartilhadas.
  • Procure especificamente erros de registro, limite de buffer e largura de tipo.
  • "Funciona" é comprovado com um osciloscópio, analisador lógico e log serial, não com o compilador.
  • Se o valor medido não estiver de acordo com o cálculo, siga as suposições.

Tarefa de aplicativo

Com um microcontrolador que você possui (Arduino, STM32, ESP32), peça à IA PWM ou uma tarefa periódica em uma determinada frequência. Antes de carregar o código: (1) verifique os valores de frequência/tempo independentemente da conta na linha de comentários, (2) verifique se há volatilidade e bloqueio no ISR e nas variáveis ​​compartilhadas. Após o upload, meça a frequência real com um osciloscópio ou analisador lógico e compare-a com o alvo. Se houver um desvio, encontre a fonte e corrija-a, e observe o que foi considerado errado.