이것은 답변보다 의견 / 의견입니다.
당신은 C로 프로그래밍하고 싶지 않으며 그렇게해서는 안된다. C ++ 은 올바른 방식으로 사용될 때 훨씬 우수하다. (좋아요, 잘못된 방식으로 사용하면 C보다 훨씬 나쁩니다.) AVR을 포함하여 GCC에서 지원하는 거의 모든 (현대) C ++ 컴파일러가있는 칩으로 제한합니다. 일부 제한 사항에서 filo는 비 균일 주소 공간의 문제를 언급하지만 거의 모든 PIC를 제외합니다 (PIC32는 지원 될 수 있지만 아직 괜찮은 포트는 보지 못했습니다).
C / C ++에서 알고리즘을 프로그래밍 할 때 언급 한 선택 사항의 차이는 작습니다 (여러분이 16, 32 또는 그 이상의 비트 산술을 수행 할 때 8 또는 16 비트 칩이 심각한 불리 함을 제외하고). 마지막 성능의 온스가 필요할 경우 어셈블러 (공급 업체 또는 타사에서 제공 한 코드 또는 자체)를 사용해야합니다. 이 경우 선택한 칩을 다시 고려할 수 있습니다.
하드웨어를 코딩 할 때 일부 추상화 계층 (주로 제조업체에서 제공)을 사용하거나 데이터 시트 및 / 또는 예제 코드를 기반으로 자체 추상화 계층을 작성할 수 있습니다. IME 기존 C 추상화 (mbed, cmsis, ...)는 종종 기능적으로 (거의) 정확하지만 성능에 크게 실패합니다 (핀 세트 작업을 위해 6 개의 간접 레이어가 간접적인지 확인), 유용성 및 이식성. 그들은 특정 칩의 모든 기능을 당신 에게 노출하려고합니다 . 거의 모든 경우에 당신은 필요하지 않고 신경 쓰지 않을 것이며, 코드를 특정 벤더 (그리고 아마도 특정 칩)에 고정시킵니다.
이것은 C ++이 훨씬 더 잘 할 수 있다는 것입니다. 올바르게 설정하면 핀 세트가 6 개 이상의 추상화 계층을 통과 할 수 있습니다 (더 나은 (휴대용!) 인터페이스와 더 짧은 코드를 가능하게 하기 때문에) 대상과 독립적 인 인터페이스를 제공합니다 간단한 경우에 , 그리고 당신이 어셈블러로 작성하는 것처럼 여전히 같은 기계 코드 발생 .
내가 사용하는 코딩 스타일의 스 니펫은 당신을 열정적으로 만들거나 공포에서 벗어날 수 있습니다.
// GPIO part of a HAL for atsam3xa
enum class _port { a = 0x400E0E00U, . . . };
template< _port P, uint32_t pin >
struct _pin_in_out_base : _pin_in_out_root {
static void direction_set_direct( pin_direction d ){
( ( d == pin_direction::input )
? ((Pio*)P)->PIO_ODR : ((Pio*)P)->PIO_OER ) = ( 0x1U << pin );
}
static void set_direct( bool v ){
( v ? ((Pio*)P)->PIO_SODR : ((Pio*)P)->PIO_CODR ) = ( 0x1U << pin );
}
};
// a general GPIO needs some boilerplate functionality
template< _port P, uint32_t pin >
using _pin_in_out = _box_creator< _pin_in_out_base< P, pin > >;
// an Arduino Due has an on-board led, and (suppose) it is active low
using _led = _pin_in_out< _port::b, 27 >;
using led = invert< pin_out< _led > >;
실제로는 추상화 계층이 더 있습니다. 그러나 LED의 최종 사용은 전원을 켜고 대상의 복잡성이나 세부 사항을 보여주지 않습니다 (아두 인 우노 또는 ST32 파란색 알약의 경우 코드가 동일 함).
target::led::init();
target::led::set( 1 );
컴파일러는 이러한 모든 계층에 위협을받지 않으며, 옵티마이 저가 모든 것을 통해 보는 가상 기능이 없기 때문에 (주변 클럭 활성화와 같은 일부 세부 사항은 생략)
mov.w r2, #134217728 ; 0x8000000
ldr r3, [pc, #24]
str r2, [r3, #16]
str r2, [r3, #48]
이것이 어셈블러에서 어떻게 작성했는지입니다. PIO 레지스터를 공통베이스의 오프셋과 함께 사용할 수 있다는 것을 깨달았습니다. 이 경우 아마도 그렇 겠지만 컴파일러는 나보다 그런 것들을 최적화하는 데 훨씬 좋습니다.
내가 대답하는 한 그것은 하드웨어에 대한 추상화 계층을 작성하지만 현대 C ++ (개념, 템플릿)로 수행하면 성능에 해를 끼치 지 않습니다. 이를 통해 다른 칩으로 쉽게 전환 할 수 있습니다. 당신은 당신이 누워있는 임의의 칩에서 개발을 시작할 수 있고, 친숙하고, 좋은 디버깅 도구를 가지고 있으며, 나중에 (필요한 메모리, CPU 속도 등에 대한 자세한 정보가있을 때까지) 최종 선택을 연기 할 수 있습니다.
임베디드 개발의 잇점 중 하나 인 IMO는 먼저 칩을 선택하는 것입니다 (이 포럼에서 자주 묻는 질문입니다. 어떤 칩을 선택해야하는지 .... 가장 좋은 대답은 일반적으로 중요하지 않습니다).
(편집- "현명한 성능, C 또는 C ++의 레벨이 같습니까?"에 대한 응답)
동일한 구성의 경우 C와 C ++은 동일합니다. C ++에는 도구와 마찬가지로 선이나 악에 사용될 수있는 추상화 (클래스, 템플릿, constexpr)에 대한 훨씬 더 많은 구성이 있습니다. 토론을 더 흥미롭게 만들기 위해 : 모든 사람이 좋고 나쁜 것에 동의하지는 않습니다 ...