programação por microcontrolador vs programação orientada a objetos

11

Eu fiz alguma programação básica orientada a objetos com C ++ (criando uma árvore B, algoritmos de hash, listas duplas vinculadas) e eu fiz um pequeno projeto em C (como fazer uma calculadora científica etc.)

Quão diferente é a programação de hardware (especificamente para microcontroladores) da programação orientada a software / objeto em termos de mentalidade e "pensamento" que o programador precisa ter?

Um é geralmente considerado mais difícil que o outro, o meu maior número de pessoas?

Com minha formação (conforme descrito acima), eu precisaria de muita preparação para entrar na programação de hardware ou posso me aprofundar sem muita preparação?

rrazd
fonte
4
A maior curva de aprendizado será como conduzir o hardware específico no seu micro. Isso envolverá debruçar-se sobre as folhas de dados por horas. Infelizmente, não há saída fácil.
22411 drxzcl
@rrazd, notei que você incluiu a tag arduino. Isso ocorre porque você deseja usar a linguagem de conexão e as bibliotecas do arduino? Ou você estará escrevendo seus aplicativos incorporados em C puro? Se você pretende se manter no ambiente do arduino, é muito seguro e fácil brincar, pois eles fizeram algumas abstrações longe do hardware.
Jon G
@ Jon, pretendo usar uma placa de arduino para iniciantes. Não é semelhante à linguagem C? Eu pensei que envolveu os mesmos conceitos básicos ....
rrazd
1
Pergunto-me se você quer dizer o que muitas pessoas chamariam de 'programação de E / S' ou se você espera reorganizar o hardware com o código. O arduino é decididamente o primeiro; o último seria o domínio dos FPGAs.
JustJeff
1
@rrazd - mudei o título; "programação de hardware" parece muito com HDL (linguagem de descrição de hardware), por exemplo, VHDL e Verilog, que são usadas para programar FPGAs e CPLDs.
Stevenvh

Respostas:

10

Você terá que abandonar completamente o paradigma orientado a objetos ao lidar com a maioria dos microcontroladores.

Os microcontroladores geralmente são limitados por registro e RAM, com taxas de clock baixas e sem caminhos de código em pipelining / paralelo. Você pode esquecer o Java em um PIC, por exemplo.

Você precisa entrar em uma mentalidade de linguagem assembly e escrever proceduralmente.

Você deve manter seu código relativamente plano e evitar recursões, pois as limitações de RAM geralmente podem levar a problemas de pilha.

Você precisa aprender a escrever rotinas de serviço de interrupção que sejam eficientes (geralmente na linguagem assembly).

Pode ser necessário refatorar partes do código manualmente, em linguagem assembly, para implementar funcionalidades que o compilador não suporta (ou suporta pouco).

Você precisa escrever um código matemático que leve em consideração o tamanho da palavra e a falta de recursos de FPU da maioria dos microcontroladores (por exemplo, multiplicação de 32 bits em um micro = mal de 8 bits).

É um mundo diferente. Para mim, ter formação em ciência da computação ou programação profissional pode ser tanto um obstáculo quanto não ter conhecimento algum ao lidar com microcontroladores.

Adam Lawrence
fonte
1
Você não precisa abandonar completamente o paradigma orientado a objetos, mas em micros menores, pode ser necessário abandonar implementações de objetos pesados ​​e realmente pensar sobre qual é a melhor maneira de resolver cada problema. Muitas vezes, isso é processual, mas objetos leves, bem implementados (geralmente à mão), às vezes podem reduzir o tamanho de projetos complicados de microcontroladores.
Chris Stratton
6
Tudo isso é verdade, exceto abandonar a orientação a objetos. Você provavelmente não usará um idioma com recursos OO, mas isso não descarta a orientação a objetos. Para microcontroladores, você escreverá drivers para todos os periféricos de hardware (ADCs, controladores de barramento serial, PWM, etc etc). Esse driver deve sempre ser escrito de maneira orientada a objetos, para que seja 1) autônomo e não saiba / se preocupa com o restante do programa; e 2) implementando o encapsulamento privado, para que o restante do programa não possa entre e brinque com isso. Isso é 100% possível em C e não afeta o desempenho.
Lundin
1
Discordo totalmente da primeira frase, todos os meus projetos de microcontroladores foram construídos com C ++ e uma abordagem orientada a objetos, e os micros que usamos não eram muito grandes (32kB de ROM), o gerenciador de inicialização também orientado a objetos estava em menos de 2kB. realmente não vejo limitação. Você não pode fazer coisas malucas, mas o design pode ser orientado a objetos sem problemas.
Arsenal
@ Arsenal Note que eu disse 'a maioria', e observe que você está comentando um tópico de quatro anos. :)
Adam Lawrence
Discordo completamente da primeira e da última frase. E também o assembly é usado muito raramente e, principalmente, apenas para MCUs de 8 bits (basta verificar neste fórum, quantas postagens com o código do assembly você pode encontrar?). Você certamente pode e (IMHO) deve escrever no estilo OO para 32 bits MCUs
Andrejs Gasilovs
10

Você precisa pensar em várias coisas:

  • Você usará C como idioma
  • Você ainda pode criar uma sensação de orientação a objetos usando ponteiros de função para substituir funções, etc. Eu usei esse método nos projetos anteriores e atuais e funciona muito bem. Portanto, o OO está parcialmente lá, mas não no sentido de C ++.

Existem outras limitações que serão reproduzidas, como velocidade e memória limitadas. Como orientação geral, evito:

  • Usando heap, se houver uma maneira de resolver o problema sem o Malloc, eu faço isso. Por exemplo, pré-aloco os buffers e apenas os uso.
  • Intencionalmente reduzo o tamanho da pilha nas configurações do compilador para enfrentar os problemas de tamanho da pilha desde o início, otimizo-o com cuidado.
  • Presumo que cada linha de código seja interrompida por um evento, por isso evito código não reentrante
  • Eu suponho que mesmo interrupções sejam aninhadas, então eu escrevo esse código de acordo
  • Evito usar o SO, a menos que seja necessário. 70% dos projetos incorporados realmente não precisam de um sistema operacional. Se eu precisar usar um sistema operacional, use apenas algo com o código-fonte disponível. (Freertos etc)
  • se estou usando um sistema operacional, quase sempre abstrato as coisas para poder mudar o sistema operacional em questão de horas.
  • Para drivers etc., usarei apenas as bibliotecas fornecidas pelo fornecedor, nunca mexo diretamente nos bits, a menos que não tenha outra escolha. Isso torna o código legível e melhora a depuração.
  • Olho os loops e outras coisas, especialmente no ISR, para garantir que eles sejam rápidos o suficiente.
  • Eu sempre mantenho alguns GPIOs à mão para medir coisas, alternância de contexto, tempo de execução do ISR etc.

A lista continua, provavelmente estou abaixo da média em termos de programação de software, tenho certeza de que existem melhores práticas.

Frank
fonte
3
+1 para "você pode usar paradigmas de OO, se quiser". O que você precisa verificar na porta não é o projeto OO. OOD é apenas uma filosofia que incentiva você a manter códigos e dados relacionados juntos. O que você precisa deixar para trás é a maneira como o OO é implementado nos sistemas corporativos, com várias camadas de abstração, inversão de controle e todo esse jazz. A tarefa do seu firmware é dirigir o hardware, é isso.
21411 drxzcl #
7

Eu faço as duas coisas, então aqui está a minha opinião.

Eu acho que a habilidade mais importante de longe incorporada é a sua capacidade de depuração. A mentalidade necessária é muito diferente, pois muito mais pode dar errado, e você deve estar muito aberto a considerar todas as diferentes maneiras pelas quais você está tentando fazer pode dar errado.

Esse é o maior problema para os novos desenvolvedores incorporados. As pessoas de PC tendem a ser mais ásperas, pois estão acostumadas a trabalhar apenas para elas. Eles tendem a perder muito tempo procurando ferramentas para fazer as coisas por eles (dica: não há muitos). Há muitas cabeças batendo nas paredes repetidas vezes, sem saber o que mais fazer. Se você sentir que está ficando paralisado, dê um passo atrás e descubra se consegue identificar o que tudo está dando errado. Sistematicamente, refine sua lista de problemas em potencial até que você descubra. Segue-se diretamente deste processo que você deve limitar o escopo dos problemas, não alterando muito de uma vez.

Pessoas embarcadas experientes tendem a aceitar a depuração como certa ... a maioria das pessoas que não consegue fazer isso bem não dura muito (ou trabalha em grandes empresas que simplesmente aceitam "o firmware é difícil" como resposta para por que um determinado recurso está atrasado)

Você está trabalhando no código que é executado em um sistema externo ao seu sistema de desenvolvimento, com vários graus de visibilidade do seu destino de plataforma para plataforma. Se você estiver sob seu controle, solicite auxílio ao desenvolvimento para ajudar a aumentar essa visibilidade em seu sistema de destino. Use portas seriais de depuração, saída de depuração de batida de bits, a famosa luz piscante etc. etc. Certamente, no mínimo, aprenda como usar um osciloscópio e use E / S de pino com o escopo 'para ver quando determinadas funções entram / saem, ISRs disparam, etc. Eu assisti as pessoas lutando literalmente por anos mais do que o necessário, simplesmente porque nunca se preocuparam em configurar / aprender a usar um link de depurador JTAG adequado.

É muito mais importante estar ciente exatamente de quais recursos você possui em relação a um PC. Leia as folhas de dados com atenção. Considere o 'custo' do recurso de qualquer coisa que você esteja tentando fazer. Aprenda truques de depuração orientados a recursos, como preencher o espaço da pilha com um valor mágico para rastrear o uso da pilha.

Embora seja necessário algum grau de habilidade de depuração para PC e software incorporado, é muito mais importante com o incorporado.

darron
fonte
5

Presumo que sua experiência em C ++ seja baseada em PC.

Um erro frequentemente cometido pelos programadores que passam do PC para o microcontrolador é que eles não percebem como os recursos podem ser limitados . Em um PC, ninguém o interrompe quando você cria uma tabela com 100.000 entradas ou escreve um programa que compila até 1 MB de código de máquina.
Não são microcontroladores que têm uma riqueza de recursos de memória, especialmente na parte alta, mas ainda é muito longe do que você vai ser usado para. Para um projeto de hobby, você provavelmente sempre pode ir ao máximo, mas em um projeto profissional, muitas vezes você é forçado a trabalhar com o dispositivo menor, porque é mais barato .
Em um projeto, eu estava trabalhando com uma TI MSP430F1101. 1KB de memória de programa, 128 bytes de configuração Flash, 128 bytes de RAM. O programa não cabia no 1K, então tive que escrever uma função de 23 bytes na configuração do Flash. Com esses pequenos controladores, você calcula pelo byte . Em outra ocasião, a memória do programa era 4 bytes muito pequena. O Boss não me deixou usar o controlador com mais memória, mas tive que otimizar um código de máquina já otimizado (já estava escrito em assembler) para ajustar os 4 bytes extras. Você entendeu.

Dependendo da plataforma em que você está trabalhando, você terá que lidar com E / S de nível muito baixo . Alguns ambientes de desenvolvimento têm funções para gravar em um LCD, mas em outros você está por conta própria e precisará ler a folha de dados do LCD do início ao fim para saber como controlá-lo.
Pode ser necessário controlar um relé, mais fácil que um LCD, mas será necessário que você vá para o nível de registro do microcontrolador. Novamente uma folha de dados ou manual do usuário. Você precisará conhecer a estrutura do microcontrolador, que você encontrará em um diagrama de blocos, novamente na folha de dados. Nos dias do microprocessador falamos sobre um modelo de programação, que era basicamente uma linha de registros do processador. Os microcontroladores de hoje são tão complexos que uma descrição de todos os registros pode ter a melhor parte de uma folha de dados de 100 páginas. O IIRC apenas a descrição do módulo de relógio para o MSP430 tinha 25 páginas.

μ

Os microcontroladores são muitas vezes programados em C . C ++ é bastante recursos com fome, então isso geralmente está fora. (A maioria das implementações de C ++ para microcontroladores oferece um subconjunto limitado de C ++.) Como eu disse, dependendo da plataforma, você pode ter uma extensa biblioteca de funções disponíveis, o que pode economizar bastante tempo de desenvolvimento. Vale a pena dedicar algum tempo para estudá-lo; pode economizar muito tempo mais tarde, se você souber o que está disponível.

stevenvh
fonte
Eu escrevi jogos para o Atari 2600, que é uma plataforma bastante limitada; meu primeiro jogo publicado foi essencialmente um código 4K (desde que eu tinha um carrinho de 32K, adicionei alguns extras, mas a versão 4K era totalmente jogável); RAM é de 128 bytes. Acho interessante contemplar que, no ano em que escrevi esse jogo (2005), outros jogos foram publicados literalmente um milhão de vezes maior.
Supercat
@supercat - Sim, mas isso era de se esperar, em 2005 o Atari 2600 já tinha 200 anos! Eu nunca joguei jogos de ação como FPSs, mas quando olho para o que é necessário para jogá-los, uma GPU muito mais poderosa que sua CPU, tanto programática quanto eletricamente, não posso deixar de balançar a cabeça :-). Joguei xadrez (Sargon) em um TRS-80 IIRC de 16k. O Flight Simulator do meu irmão não precisava de mais.
precisa saber é o seguinte
Não tem 200 anos. Ele estreou em 1977, então não tinha nem 30 anos. Embora eu concorde que isso foi há anos atrás em termos tecnológicos, ainda estou impressionado com o fato de não haver apenas um aumento de cem retenções, nem um aumento de mil vezes , mas um aumento de MILHÕES de vezes na RAM e no tamanho do código. A velocidade não recebeu tanto impulso, uma vez que o 2600 era de 1,19 MHz e os sistemas mais novos estão apenas na faixa de GHz baixo. Eles podem fazer muito mais por ciclo do que os 2600 (que poderiam - e tiveram que - gerar 1/76 de uma linha de vídeo a cada ciclo), mas não acho que sejam 1.000.000x mais rápidos.
Supercat
3

"programação de hardware" pode significar muitas coisas. Programar um chip muito pequeno (pense nas instruções 10F200, 512, alguns bytes de RAM) pode ser quase como projetar um circuito eletrônico. Por outro lado, a programação de um grande microcontrolador Cortex (1 Mb FLASH, 64 kB de RAM) pode ser muito parecido com a programação PC / GUI, usando um grande kit de ferramentas da GUI. IMHO, um bom programador embutido / em tempo real precisa de habilidades, tanto do lado da engenharia de software quanto do lado do design do circuito. Para o uC maior, o C ++ é uma boa opção de linguagem; para os mais pequenos, C pode ser a única opção. O conhecimento de montagem pode ser útil, mas eu não recomendaria a realização de projetos sérios inteiramente em montagem.

Fiz um trabalho sério incorporado com pessoas de ambos os lados (SWI e EE). Eu geralmente prefiro o pessoal da SWI, desde que eles tenham alguma experiência com programação multu-threaded.

Sua pergunta parece que você deseja mergulhar na programação incorporada. Por todos os meios, faça-o. Para os aspectos de baixo nível (interface dos periféricos do seu chip e do hardware ao seu redor), você precisará aprender algumas novas habilidades, mas é apenas muito trabalho sem muitos novos conceitos. Para as camadas mais altas dos seus projetos, você pode desenhar no knwoledge existente.

Wouter van Ooijen
fonte
1

Para cada método de biblioteca do arduino que você chama, existe uma variedade de códigos C / C ++ que possibilitam isso, é simplesmente empacotado de maneira agradável para você usar como API. Dê uma olhada no código fonte do arduino no diretório hardware / arduino / * e você verá todo o C / C ++ escrito para você, que interage diretamente com os registros do microcontrolador AVR. Se seu objetivo é aprender a escrever coisas como essa (diretamente para o hardware), há muito o que abordar. Se seu objetivo é conseguir que alguma coisa funcione usando suas bibliotecas, talvez não haja muito o que falar, pois a maior parte do trabalho é feito para você e suas bibliotecas e ambiente de desenvolvimento são muito fáceis de usar.

Algumas regras práticas ao trabalhar com dispositivos com recursos limitados que podem ser aplicados ao ambiente do arduino ou a outros:

Esteja ciente de quanta memória você está usando. Tanto o tamanho do código (que vai para a memória flash) quanto o uso estático da RAM (constantes no seu código que sempre existirão na RAM). Eu diria que o uso de RAM estática é um pouco mais importante para começar, pois é fácil ignorar. Não é incomum você ter apenas 1000 bytes para trabalhar na sua pilha, pilha e constantes. Seja sábio em como você o gasta; portanto, evite coisas como longas matrizes de números inteiros (4 bytes cada) quando bytes ou caracteres não assinados (1 byte cada) serão suficientes. Outra resposta aqui cobre muito bem outros pontos importantes, então, para parar por aqui, eu queria entender o que há muito a ser abordado se você não estiver usando a biblioteca do arduino e escrevendo suas próprias bibliotecas C.

Jon L
fonte
0

Em relação ao microcontrolador versus programação OOP, eles não são algo opostos. É verdade que todas as bibliotecas de fornecedores estão em C simples, mas todas as plataformas também suportam C ++ OOP. Os desenvolvedores podem criar e criar bibliotecas de alto nível C ++ e firmware de dispositivo, além disso. O bom exemplo são as bibliotecas do Arduino, oficiais e criadas pelo usuário - principalmente classes C ++. Talvez nem todas as vantagens de OOP possam ser totalmente utilizadas no ambiente incorporado, mas as vantagens conhecidas de C ++ vs C também são válidas aqui.

Com relação à mentalidade e ao pensamento, como observado em outras respostas, os microcontroladores são plataformas com muitos recursos limitados (especialmente na RAM, menos velocidade) - como alocação dinâmica de memória, exceções de C ++ geralmente são descartadas. Dado que o hardware certo foi escolhido, é fácil adotar essas limitações e usar outras técnicas (também amplamente usadas em outras plataformas).

Na minha opinião, o desafio mais difícil pode ser mais uma dimensão extra encontrada na programação incorporada - o tempo. Isso ocorre porque geralmente o software incorporado lida muito com eventos em tempo real, protocolos estritamente cronometrados para direcionar o hardware periférico e a própria tarefa geral (esses são alguns paralelos em outras plataformas de "alto nível" também, como aplicativos multithread).

Esteja preparado para ler muitas planilhas de dados ao lidar com novo hardware - acho que isso pode estar relacionado à parte da pergunta "mindset" :) Certamente seria necessário algum conhecimento de EE e hardware.

Também gostaria de observar que atualmente o desenvolvimento de software embarcado não requer linguagem assembly. De fato, o Java (BTW é OOP por padrão) já está aqui e está ficando mais forte (pelo menos para alguma classe de dispositivos incorporados, por exemplo, dispositivos IoT, poderia ter um futuro muito brilhante).

Flanker
fonte
Em termos de preocupações, aqueles em torno da (re) alocação de memória dinâmica tendem a ser um impedimento maior ao OO tradicional do que ao tempo .
22616 Chris Stratton
Talvez você esteja certo. Mas há pessoas que programaram nos anos 80 e 90 para o software em modo real do MSDOS, com 64K (segmento de memória de dados) de espaço disponível e para eles era "natural". Talvez MSDOS PC foi mais "incorporado" ambiente do que hoje STM32F4 :)
Flanker
O STM32F4 normalmente possui mais memória de programa na forma de flash, mas o PC normalmente vem com muito mais memória RAM para armazenar objetos de tempo de execução mutáveis. Embora toda a coisa do ponteiro distante forçada pelo endereçamento segmentado tenha sido uma dor, os dois carecem de uma verdadeira MMU, e isso será uma preocupação ainda maior no sistema com menos RAM, que é o STM32F4. O tempo de atividade do PC também tendia a ser mais curto e as taxas de falha aceitáveis ​​mais altas.
22616 Chris Stratton