마이크로 컨트롤러 프로그래밍과 객체 지향 프로그래밍


11

나는 C ++ (B-Tree, Hashing Algorithms, Double Linked Lists 생성)을 사용하여 기본적인 객체 지향 프로그래밍을 수행했으며 C에서 작은 프로젝트를 수행했습니다 (과학 계산기 만들기 등).

프로그래머가 가지고 있어야하는 사고 방식과 "생각"측면에서 하드웨어 프로그래밍 (특히 마이크로 컨트롤러 전용)과 소프트웨어 / 객체 지향 프로그래밍의 차이점은 무엇입니까?

대부분의 사람들이 다른 사람들보다 더 어려운 것으로 간주됩니까?

(위에서 설명한 것처럼) 저의 배경으로 하드웨어 프로그래밍에 들어가기 위해 많은 준비가 필요합니까? 아니면 너무 많은 준비없이 바로 뛰어들 수 있습니까?


4
가장 큰 학습 곡선은 마이크로에서 특정 하드웨어를 구동하는 방법입니다. 여기에는 몇 시간 동안 데이터 시트를 포어 링해야합니다. 불행히도 쉬운 방법은 없습니다.
drxzcl

@rrazd, arduino 태그가 포함 된 것으로 나타났습니다. arduino 배선 언어와 라이브러리를 사용하고 싶습니까? 아니면 순수 C로 임베디드 응용 프로그램을 작성 하시겠습니까? arduino 환경을 고수하려는 경우 하드웨어에서 약간의 추상화를 수행했기 때문에 매우 안전하고 쉽게 재생할 수 있습니다.
Jon L

@Jon 나는 초보자를 위해 arduino 보드를 사용할 계획입니다. C 언어와 비슷하지 않습니까? 나는 ....이 같은 기본 개념을 포함 생각
rrazd

1
많은 사람들이 'I / O 프로그래밍'이라고 부르는 것이 무엇인지 또는 코드를 사용하여 하드웨어를 다시 정렬해야하는지 궁금합니다. arduino는 분명히 전자입니다. 후자는 FPGA의 도메인입니다.
JustJeff

1
@rrazd-제목을 변경했습니다. "하드웨어 프로그래밍"은 FPGA 및 CPLD를 프로그래밍하는 데 사용되는 VHDL 및 Verilog와 같은 HDL (하드웨어 설명 언어)과 너무 비슷하게 들립니다.
stevenvh

답변:


10

대부분의 마이크로 컨트롤러를 다룰 때 객체 지향 패러다임을 완전히 버려야합니다.

마이크로 컨트롤러는 일반적으로 레지스터 및 RAM이 제한되며 클럭 속도가 느리고 파이프 라인 / 병렬 코드 경로가 없습니다. 예를 들어 PIC에서 Java를 잊을 수 있습니다.

당신은 어셈블리 언어 사고 방식에 들어가서 절차 적으로 작성해야합니다.

RAM 제한으로 인해 스택 문제가 발생할 수 있으므로 코드를 비교적 평평하게 유지하고 재귀를 피해야합니다.

효율적인 인터럽트 서비스 루틴 (일반적으로 어셈블리 언어)을 작성하는 방법을 배워야합니다.

컴파일러가 지원하지 않거나 제대로 지원하지 않는 기능을 구현하려면 어셈블리 언어로 코드 일부를 리팩터링해야 할 수도 있습니다.

대부분의 마이크로 컨트롤러의 단어 크기와 FPU 기능 부족을 고려한 수학적 코드를 작성해야합니다 (예 : 8 비트 마이크로 = 악의에 32 비트 곱셈 수행).

다른 세상입니다. 컴퓨터 공학이나 전문 프로그래밍 배경을 갖는 것은 마이크로 컨트롤러를 다룰 때 전혀 지식이없는 것만 큼 방해가 될 수 있습니다.


1
객체 지향 패러다임을 완전히 버릴 필요는 없지만 작은 마이크로에서는 무거운 객체 구현을 버리고 각 문제를 해결하는 가장 좋은 방법이 무엇인지 생각해야 할 수도 있습니다. 종종 그것은 절차 적이지만, 잘 구현 된 (일반적으로 손으로) 가벼운 객체는 때때로 복잡한 마이크로 컨트롤러 프로젝트의 크기를 줄일 수 있습니다.
Chris Stratton

6
객체 지향을 버리는 것을 제외하고는이 모든 것이 사실입니다. OO 기능이있는 언어를 사용하지는 않지만 객체 방향을 배제하지는 않습니다. 마이크로 컨트롤러의 경우 모든 하드웨어 주변 장치 (ADC, 직렬 버스 컨트롤러, PWM 등) 용 드라이버를 작성합니다. 이러한 드라이버는 항상 객체 지향 방식으로 작성되어 1) 자율적이며 나머지 프로그램에 대해 알지 못 / 신경 쓰지 않고 2) 나머지 캡슐화를 할 수 없도록 개인 캡슐화를 구현합니다. 들어가서 바이올린을 사용하십시오. 이것은 C에서 100 % 가능하며 성능에 영향을 미치지 않습니다.
Lundin

1
첫 번째 문장에 동의하지 않습니다. 모든 마이크로 컨트롤러 프로젝트는 C ++ 및 객체 지향 접근 방식으로 작성되었으며 우리가 사용한 마이크로 크기는 크지 않았습니다 (ROM의 32kB). 또한 객체 지향 부트 로더는 2kB 미만이었습니다. 실제로 제한을 보지 마십시오. 미친 짓을 할 수는 없지만 디자인은 문제가없는 객체 지향적 일 수 있습니다.
아스날

@Arsenal Note 나는 '가장 많이'라고 말했고 4 살짜리 실에 대해 언급하고 있습니다. :)
Adam Lawrence

나는 첫 번째와 마지막 문장에 완전히 동의하지 않습니다. 또한 어셈블리는 거의 사용되지 않으며 주로 8 비트 MCU에만 사용됩니다 (이 포럼을 확인하십시오. 조립 코드가있는 게시물 수는 얼마입니까?). 당신은 확실히 (IMHO) 32 비트 MCU를위한 OO 스타일로 작성해야합니다
Andrejs Gasilovs

10

몇 가지 사항에 대해 생각해야합니다.

  • C를 언어로 사용합니다
  • 함수 포인터를 사용하여 객체 방향 감각을 만들 수 있으므로 함수 등을 재정의 할 수 있습니다. 과거와 현재 프로젝트 에서이 방법을 사용했으며 매우 잘 작동합니다. 따라서 OO는 부분적으로 있지만 C ++ 의미는 아닙니다.

제한된 속도와 메모리와 같은 다른 제한 사항이 있습니다. 따라서 일반적인 지침으로 다음을 피합니다.

  • Malloc없이 문제를 해결할 수있는 방법이 있다면 힙을 사용합니다. 예를 들어, 버퍼를 미리 할당하고 사용합니다.
  • 컴파일러 설정에서 스택 크기를 의도적으로 줄이고 초기에 스택 크기 문제에 직면하여 신중하게 최적화합니다.
  • 모든 한 줄의 코드가 이벤트에 의해 중단된다고 가정하므로 재진입하지 않는 코드를 피하십시오.
  • 인터럽트조차도 중첩되어 있다고 가정하므로 그에 따라 해당 코드를 작성합니다.
  • 필요하지 않으면 OS를 사용하지 마십시오. 임베디드 프로젝트의 70 %는 실제로 OS가 필요하지 않습니다. OS를 사용해야한다면 소스 코드가있는 것만 사용하십시오. (Freertos 등)
  • OS를 사용하는 경우 거의 항상 추상화하여 몇 시간 만에 OS를 변경할 수 있습니다.
  • 드라이버 등의 경우 공급 업체에서 제공 한 라이브러리 만 사용하며 다른 선택이없는 한 직접 비트를 피킹하지 않습니다. 이렇게하면 코드를 읽을 수있게되고 디버깅이 향상됩니다.
  • 루프와 다른 것들, 특히 ISR에서 루프가 충분히 빠르다는 것을 확인합니다.
  • 나는 물건, 상황 전환, ISR 런타임 등을 측정하기 위해 항상 몇 개의 GPIO를 편리하게 유지합니다.

목록은 계속됩니다. 아마도 소프트웨어 프로그래밍 측면에서 평균보다 낮을 것입니다. 더 나은 방법이 있다고 확신합니다.


3
"원하는 경우 OO 패러다임을 사용할 수 있습니다"는 +1입니다. 문에서 확인해야 할 것은 OO 디자인이 아닙니다. OOD는 관련 코드와 데이터를 함께 유지하도록 독려하는 철학입니다. 기업 시스템에서 OO가 구현되는 방식은 여러 계층의 추상화, 역전 제어 및 모든 재즈를 포함하는 것입니다. 펌웨어 작업은 하드웨어를 구동하는 것입니다.
drxzcl

7

둘 다하므로 여기에 내 견해가 있습니다.

임베디드에서 가장 중요한 기술은 디버깅 능력이라고 생각합니다. 요구되는 사고 방식은 훨씬 더 잘못 될 수 있다는 점에서 매우 다르며, 수행하려는 작업이 잘못 될 수있는 다양한 방법을 모두 고려할 수 있어야합니다.

이것은 새로운 임베디드 개발자에게 가장 큰 문제입니다. PC 사람들은 자신을 위해 일하는 데 익숙하기 때문에 더 거칠어하는 경향이 있습니다. 대신 도구를 찾는 도구를 찾는 데 많은 시간을 허비하는 경향이 있습니다 (힌트 : 많지 않음). 무엇을 해야할지 모른 채 벽에 머리를 두드리는 소리가 많이 있습니다. 막히고 있다고 생각되면 뒤로 물러나서 무엇이 잘못 될 수 있는지 알아 내십시오. 잠재적 인 문제 목록을 파악할 때까지 범위를 좁히십시오. 이 프로세스에서 직접 따라 오므로 한 번에 너무 많이 변경하지 않으면 서 문제의 범위를 제한해야합니다.

숙련 된 임베디드 사람들은 당연한 디버깅을하는 경향이 있습니다 ... 잘 수행 할 수없는 사람들 대부분은 오래 가지 못합니다. 늦었 어)

플랫폼에 따라 대상에 대한 다양한 가시성으로 외부 시스템에서 개발 시스템의 코드로 작업하고 있습니다. 통제하에있는 경우 개발 시스템을 강요하여 대상 시스템에 대한 가시성을 높이십시오. 디버그 직렬 포트, 비트 뱅킹 디버그 출력, 유명한 깜박임 등을 사용하십시오. 확실히 오실로스코프를 사용하는 방법을 배우고 'scope와 핀 I / O를 사용하여 특정 기능이 언제 들어가고 나가는 지, ISR이 발생하는지 등을 확인하십시오. 나는 사람들이 적절한 JTAG 디버거 링크를 사용하는 방법을 설정 / 학습하지 않았기 때문에 문자 그대로 몇 년 이상 문자 그대로 필요 이상으로 어려움을 겪는 것을 보았다.

PC와 관련하여 어떤 리소스가 있는지 정확히 알고 있어야합니다. 데이터 시트를주의해서 읽으십시오. 당신이하려는 일의 자원 '비용'을 고려하십시오. 스택 공간을 마법의 가치로 채워서 스택 사용량을 추적하는 것과 같은 리소스 지향 디버깅 기법을 배웁니다.

PC와 임베디드 소프트웨어 모두 어느 정도의 디버깅 기술이 필요하지만 임베디드에서는 훨씬 더 중요합니다.


5

C ++ 경험이 PC 기반이라고 가정합니다.

프로그래머가 PC에서 마이크로 컨트롤러로 이동하는 경우 종종 오류가 발생하는 것은 제한된 리소스 가 얼마나 제한되어 있는지 알지 못한다 는 것입니다. PC에서는 100 000 개의 항목이있는 테이블을 만들거나 1MB의 기계 코드로 컴파일되는 프로그램을 작성할 때 아무도 막을 수 없습니다.
있습니다 , 특히 하이 엔드에, 메모리 자원의 풍부한이 마이크로 컨트롤러는, 그러나 당신이하는 데 사용됩니다 어떤에서 여전히 거리가 멀다입니다. 취미 프로젝트의 경우 항상 최대로 갈 수 있지만 전문 프로젝트에서는 저렴한 장치 때문에 더 작은 장치 로 작업 해야하는 경우가 종종 있습니다 .
한 프로젝트에서 TI MSP430F1101을 사용하고있었습니다.. 1KB의 프로그램 메모리, 128 바이트의 구성 플래시, 128 바이트의 RAM. 이 프로그램은 1K에 맞지 않았으므로 구성 플래시에서 23 바이트 함수를 작성해야했습니다. 이 작은 컨트롤러를 사용하면 바이트로 계산됩니다 . 다른 경우에 프로그램 메모리는 4 바이트가 너무 작습니다. 보스는 더 많은 메모리를 사용하여 컨트롤러를 사용할 수 없지만 대신 4 바이트를 추가로 맞추기 위해 이미 최적화 된 머신 코드 (이미 어셈블러로 작성 됨)를 최적화해야했습니다.

작업중인 플랫폼에 따라 매우 낮은 수준의 I / O 를 처리해야합니다 . 일부 개발 환경에는 LCD에 기록 할 수있는 기능이 있지만 다른 환경에는 LCD를 작성 하는 방법을 알기 위해 LCD 데이터 시트 를 처음부터 끝까지 읽어야 합니다.
LCD보다 쉬운 릴레이를 제어해야 할 수도 있지만 마이크로 컨트롤러의 레지스터 레벨로 이동해야합니다. 다시 한 번 데이터 시트 나 사용자 설명서. 마이크로 컨트롤러의 구조를 알아야합니다.이 구조는 데이터 시트에서 다시 블록 다이어그램에서 찾을 수 있습니다. 마이크로 프로세서 시대에 우리는 프로그래밍 모델에 대해 이야기했습니다.기본적으로 프로세서 레지스터의 라인업이었습니다. 오늘날의 마이크로 컨트롤러는 너무 복잡하여 모든 레지스터에 대한 설명이 100 페이지 데이터 시트의 가장 큰 부분을 차지할 수 있습니다. IIRC는 MSP430의 시계 모듈에 대한 설명이 25 페이지 길이였습니다.

실시간 이벤트 처리 를 다루어야하는 경우가 종종 있습니다 . 은 중단 이 (10) 내에 처리해야 예를 들어, S, 같은 타이밍의 정확성을 필요로 또 다른 인터럽트가 그 동안. μ

마이크로 컨트롤러는 종종 C로 프로그래밍됩니다 . C ++은 다소 배가 고픈 리소스이므로 일반적으로 빠져 있습니다. (마이크로 컨트롤러를위한 대부분의 C ++ 구현은 제한된 C ++ 하위 집합을 제공합니다.) 앞서 말했듯이 플랫폼에 따라 사용 가능한 광범위한 함수 라이브러리를 사용하여 개발 시간을 상당히 절약 할 수 있습니다. 공부하는 데 시간이 걸리므로 나중에 무엇이 있는지 알면 나중에 많은 시간을 절약 할 수 있습니다.


나는 다소 제한된 플랫폼 인 Atari 2600 용 게임을 작성했습니다. 첫 번째로 게시 된 게임은 기본적으로 4K 코드였습니다 (32K 카트가 있었기 때문에 추가 혜택을 추가했지만 4K 버전은 완전히 재생할 수있었습니다). RAM은 128 바이트입니다. 나는 그 게임 (2005)을 썼던 해에 문자 그대로 백만 배나되는 다른 게임들이 출판되었다고 생각하는 것이 흥미 롭다 .
supercat

@ supercat-예, 그러나 2005 년 Atari 2600은 이미 200 살이었습니다! 나는 FPS와 같은 액션 게임을 한 번도 해 본 적이 없지만, CPU보다 훨씬 강력한 GPU를 프로그래밍 방식 및 전기 방식으로 재생하는 데 필요한 것을 볼 때 나는 머리를 흔들 수 없습니다. :-) 나는 16k TRS-80 IIRC에서 체스 (사르곤)를했다. 내 동생의 비행 시뮬레이터는 더 이상 필요하지 않았습니다.
stevenvh

200 세가되지 않았습니다. 그것은 1977 년에 데뷔하여 30 세도되지 않았습니다. 그것은 기술적 인면에서 과거에 이미 동의 했음에도 불구하고, 백 홀드 증가 또는 1,000 배 증가가 아니라는 사실에 여전히 날아갔습니다. 그러나 RAM과 코드 크기가 수백만 배 증가합니다. 2600은 1.19MHz이고 최신 시스템은 낮은 GHz 범위에 있기 때문에 속도는 크게 향상되지 않았습니다. 2600보다주기 당 더 많은 작업을 수행 할 수 있지만 (1주기마다 비디오 라인의 1/76을 생성해야 했음에도 불구하고) 1,000,000 배라고 생각하지 않습니다.
supercat

3

"하드웨어 프로그래밍"은 많은 것을 의미 할 수 있습니다. 매우 작은 칩 (10F200, 512 명령어, 몇 바이트의 RAM)을 프로그래밍하는 것은 전자 회로 설계와 거의 같습니다. 반면에 큰 Cortex 마이크로 컨트롤러 (1Mb FLASH, 64kB RAM)는 큰 GUI 툴킷을 사용하여 PC / GUI 프로그래밍과 매우 유사 할 수 있습니다. 임베드 된 / 실시간 프로그래머 인 IMHO는 소프트웨어 예와 회로 설계 측면 모두에서 기술이 필요합니다. 더 큰 uC의 경우 C ++은 좋은 언어 선택이며 매우 작은 언어의 경우 C가 유일한 선택 일 수 있습니다. 조립 지식은 도움이 될 수 있지만, 진지한 프로젝트를 완전히 조립하는 것은 권장하지 않습니다.

나는 (SWI와 EE) 양쪽의 사람들과 함께 진지한 임베디드 작업을 수행했습니다. 멀티 스레드 프로그래밍에 대한 경험이 있다면 일반적으로 SWI 사람들을 선호합니다.

당신의 질문은 당신이 임베디드 프로그래밍에 뛰어 들고 싶어하는 것 같습니다. 꼭 그렇게하십시오. 저수준 측면 (칩의 주변 장치와 주변 하드웨어와 인터페이스)의 경우 새로운 기술을 배워야하지만 많은 새로운 개념이없는 많은 일입니다. 프로젝트의 상위 계층에 대해 기존 지식을 활용할 수 있습니다.


1

여러분이 호출하는 모든 arduino 라이브러리 메소드에는이를 가능하게하는 풍부한 C / C ++ 코드가 있으며, API로 사용할 수 있도록 잘 패키지되어 있습니다. 디렉토리 hardware / arduino / * 아래에서 arduino 소스 코드를 살펴보면 AVR 마이크로 컨트롤러의 레지스터와 직접 상호 작용하는 모든 C / C ++를 볼 수 있습니다. 당신의 목표가 이와 같은 것을 작성하는 방법을 배우는 것이라면 (직접 하드웨어를 위해), 다루어야 할 것이 많습니다. 라이브러리를 사용하여 작업 할 무언가를 얻는 것이 목표라면 대부분의 어려운 작업이 수행되고 라이브러리와 개발 환경이 매우 사용하기 쉽기 때문에 이야기 할 것이 많지 않을 수 있습니다.

그러나 arduino 환경이나 다른 환경에 적용 할 수있는 리소스가 제한된 장치로 작업 할 때는 몇 가지 규칙이 있습니다.

사용중인 메모리 양에 유의하십시오. 코드 크기 (플래시 메모리로 이동)와 정적 RAM 사용 (코드에서 항상 RAM에 존재하는 상수). 정적 RAM 사용은 간과하기 쉬우므로 처음부터 조금 더 중요하다고 주장합니다. 스택, 힙 및 상수에 대해 1000 바이트 만 작업하는 것은 드문 일이 아닙니다. 바이트 또는 부호없는 문자 (각 1 바이트)로 충분할 때 긴 정수 배열 (각 4 바이트)과 같은 것을 피하십시오. 여기에있는 또 다른 대답은 다른 중요한 점을 잘 설명하므로 여기서 멈 춥니 다. 주로 arduino 라이브러리를 사용하지 않고 자신의 C 라이브러리를 작성하지 않을 경우 다루어야 할 점이 많았 습니다 .


0

마이크로 컨트롤러 대 OOP 프로그래밍과 관련하여, 그것들은 반대가 아닙니다. 모든 공급 업체 라이브러리는 일반 C에 있지만 모든 플랫폼은 C ++ OOP도 지원합니다. 개발자는 그 위에 C ++ 고급 라이브러리 및 장치 펌웨어를 빌드하고 빌드 할 수 있습니다. 좋은 예는 Arduino 라이브러리, 공식 및 사용자 빌드-주로 C ++ 클래스입니다. 모든 OOP 이점을 임베디드 환경에서 완전히 활용할 수있는 것은 아니지만 잘 알려진 C ++ vs C 이점도 여기에서 유효합니다.

다른 답변에서 지적했듯이 사고 방식과 사고와 관련하여 마이크로 컨트롤러는 매우 제한된 리소스 (특히 RAM에서는 속도가 느림)입니다-동적 메모리 할당과 같은 것들, 일반적으로 C ++ 예외는 배제됩니다. 올바른 하드웨어를 선택하면 이러한 제한 사항을 쉽게 채택하고 다른 기술 (다른 플랫폼에서도 널리 사용됨)을 쉽게 사용할 수 있습니다.

내 생각에 더 어려운 과제는 임베디드 프로그래밍 타이밍에서 발견되는 또 다른 차원 일 수 있습니다. 이것은 일반적으로 임베디드 소프트웨어가 실시간 이벤트, 주변 하드웨어 및 일반 작업 자체를 구동하기 위해 엄격히 시간이 정해진 프로토콜을 많이 처리하기 때문입니다 (이것은 멀티 스레드 응용 프로그램과 같은 다른 "고수준"플랫폼에서도 마찬가지입니다).

새로운 하드웨어를 다룰 때 많은 데이터 시트를 읽을 준비를하십시오. "마인드"질문 부분과 관련이있을 것 같습니다.) 확실히 EE와 하드웨어 지식이 필요할 것입니다.

또한 임베디드 소프트웨어 개발에는 어셈블리 언어가 필요하지 않습니다. 실제로 Java (BTW는 기본적으로 OOP 임)가 이미 강해지고 있습니다 (적어도 일부 등급의 임베디드 장치, 예를 들어 IoT 장치의 경우 미래가 매우 밝을 수 있음).


우려의 관점에서, 동적 메모리 (재) 할당 주변 사람들 은 타이밍 보다 전통적인 OO에 더 큰 장애가되는 경향이있다 .
Chris Stratton

당신이 옳은 것 같다. 그러나 64K (데이터 메모리 세그먼트)의 RAM 공간을 사용할 수있는 MSDOS 리얼 모드 소프트웨어를 위해 80-90 년대에 프로그래밍 한 사람들이 있으며 "자연"입니다. 아마 MSDOS PC는 오늘날의 STM32F4보다 더 "내장 된"환경 일 것입니다.
Flanker

STM32F4는 일반적으로 플래시 형태로 더 많은 프로그램 메모리를 가지고 있지만 PC에는 일반적으로 가변 런타임 객체를 저장하기 위해 훨씬 더 많은 RAM 메모리가 제공됩니다. 세그먼트 화 된 어드레싱 (addressed addressing)에 의해 강요된 모든 것들은 고통 스러웠지만, 둘 다 진정한 MMU가 없으며, 이는 RAM이 적은 시스템 (STM32F4)에서 훨씬 더 큰 관심사가 될 것입니다. 또한 PC 가동 시간은 더 짧았으며 허용 가능한 고장률은 더 높았습니다.
Chris Stratton
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.