AVR 내장 개발에서 C++를 잘 활용하고 싶어요.

13573 단어 AVRembeddedC++

C++ 기반 AVR 내장 개발 정보


C++에는 삽입식 개발에 유용한 요소가 많다.최근에 내가 사용한 AVR 마이크로컴퓨터의 개발에서 C++는 매우 비슷하게 사용할 수 있다.다행히도
C 언어 개발에는'주 함수에 뭐라고 쓰는가','모듈 디자인은 어떻게 해야 하는가','호출을 어떻게 하는가'등의 예의가 있는 것 같다.
C++면 어떻게 되나요?
그동안 고민하다 보니 이런 곳이라고 생각할 수 있는 곳이 온 것 같아요.뭐, 그냥 취미 범위 내에서 혼자 이러쿵저러쿵 얘기하는 것뿐이지 참고할 만한 요소가 있었으면 좋겠다.전문가한테는 당연한 거 아닐까요?
소규모 조립 개발에만 적용되는 부분도 있지만, 베터 C의 C++를 조금 넘어서는 게 목표다.

고민의 결과 요약

  • 클래스의 포함 관계로 프로그램의 등급 구조를 나타낸다
  • placeement new를 이용하여 헤더 파일의 의존성을 최소화하고 메모리 소모량을 명확히 한다
  • 호출 시 std:function 상당 라이브러리 사용
  • 1. 클래스의 포함 관계를 통해 프로그램의 차원 구조를 표현한다


    구체적인 조립 기계를 상상하여 설계하다.광센서 신호를 받아 스피커에서 야옹야옹 소리를 내는 내장 장치를 구상하다.나는 거기에 쓰는 프로그램을 고려할 것이다.

    main 함수에 모두 적는 것도 괜찮을 것 같아요. (마이크로컴퓨터가 필요없을 수도 있어요) 조금만 자세히 분할해서 생각해 보세요.
    우선 광센서 신호를 처리하는 부분이 있다.LightSensorHandler 학급이 있어서 좋은 것 같아요.
    그리고 스피커에 적당한 신호를 보내야 한다.SpeakerController 반이 있으면 편리할 거예요.
    그리고 목적행위에 집중하고 싶은ExampleApplication반.

    층구조ExampleApplicationLightSensorHandlerSpeakerController를 가지고 있다.따라서 ExampleApplication는 다음과 같은 종류로 나뉜다.
    ExampleApplication.h
    class LightSensorHandler; // #include "LightSensorHandler.h" はせずに、前方宣言のみにする
    class SpeakerController;  // こちらも同様
    
    class ExampleApplication
    {
    public:
        ExampleApplication();
        void run();
    private:
        LightSensorHandler *lightSensorHandler; // ポインタを所有する
        SpeakerController  *speakerController;  // こちらも同様
    };
    
    ExampleApplication.h에서 보듯이 유형의 전방선언만 하고 지침을 가지면 ExampleAPplication.h 안에서 다른 종류의 머리#include를 할 필요가 없기 때문에 다양한 동작을 스마트하게 할 수 있다.
    ExampleApplication.h로 다른 반 머리글 #include를...ExampleApplication.h 다른 종류의 헤더 파일#include을 변경한 후 어떤 헤더 파일의 변경을 재컴파일할 때 상당히 많은 (혹시 전부의).cpp 파일이 재컴파일된다.이런 낭비를 줄일 수 있다면 절약하는 것이 가장 좋다.
    여기에 ExampleApplication.h까지 아래 계층의 등급도 전부#include면 전체 내부의 등급을 볼 수 있다.이렇게 되면 이후 이들 반을 재활용할 때 "어떻게 사용하더라, 보이는 건 쓸 수 있겠지?"이렇게 되면 최초의 의도의 차원 구조는 잊혀질 수 있다.학급이 올바르게 사용할 수 있도록 최대한 노력하고 싶습니다.

    2.place ement new를 사용하여 헤더 파일의 의존성을 최소화하고 메모리 소모를 명확히 한다


    위의 코드는 몇 가지 의문점으로 여겨질 수 있다.포인터만 있으면 어떡해?또는, 삽입식 시스템에서 new 연산자를 사용할 수 있습니까?이런 부분이 신경 쓰인다.
    우선 지침이 가리키는 전방에서 메모리 구역을 잘 확보하고 초기화한 실례가 필요하다.끼워 넣지 않은 C++ 프로그램에서 new 연산자를 사용하는 것은 자연스럽지만, 끼워 넣는 시스템이라면 동적 메모리의 확보가 매우 싫을 것이다. (초기화할 때 new 연산자를 한 번만 호출하면 쉽게 허용될 수 있습니까?)
    New 연산자를 사용하더라도 AVR 개발 환경에서도 사용할 수 있는 SRAM 사용량 표시 기능에는 동적으로 확보된 SRAM 사용량(스태킹 변수도 있지만)이 표시되지 않는다.
    ↓ Atmel Studio를 통해 컴파일할 때 표시되는 이것입니다.
    Program Memory Usage : 19304 bytes 58.9 % Full
    Data Memory Usage : 1881 bytes 91.8 % Full
    이 숫자는 너무 억지스럽다.글로벌 변수 정적 변수로서 Data Memory Usage(동적 및 스택 변수가 포함되지 않은 SRAM 사용량)는 여유를 가늠할 수 있습니다.
    동적 확보 부분이 어떤지 이 숫자는 모르니 스스로 계산해야 한다.ExampleApplication의 구조기로 정태적으로 확보된 메모리에서 모든 반을 실례화할 수 있다면 상당히 편리하다.그래서placeement new라고 불리는 좀 이상한 new 연산자가 등장했다.

    저장 영역이 전역 변수로 되어 있는지 확인하고placeemenet new를 사용하십시오

    ExampleApplication.cpp의 개요는 다음과 같다.스토리지 영역이 글로벌 변수로 속하는 범주의 크기와 일치하는지 확인합니다.new(g_lightSensorHandlerBuffer) LightSensorHandler place ement new 섹션을 사용합니다.인스턴스를 배치할 영역의 시작 포인터가 ()에 지정됩니다.또한 이름 없는 공간에 설정하여 외부 참조를 방지합니다. (그렇지 않으면 외부에서 extern char g_lightSensorHandlerBuffer[...] 로 접근할 수 있습니다.)
    ExampleApplication.cpp #include "ExampleApplication.h" #include <stdint-gcc.h> #include "nonstd.h" #include "LightSensorHandler.h" #include "SpeakerController.h" namespace { char g_lightSensorHandlerBuffer[sizeof(LightSensorHandler)]; char g_speakerControllerBuffer[sizeof(SpeakerController)]; int someFunction(int x) {/* 단위 변환 등, 구성원 변수에 접근할 필요가 없는 작은 함수를 여기에 써도 괜찮습니다*/} } ExampleApplication::ExampleApplication() : lightSensorHandler(new(g_lightSensorHandlerBuffer) LightSensorHandler), speakerController(new(g_speakerController) SpeakerController) { //호출 관계 등록: 후술 lightSensorHandler->onBrightened = [this] { speakerController->meow(); }; } 3. 호출 시 std:function 상당 라이브러리와 주 행렬식 사용std::function는 함수 바늘 등을 저장할 수 있다.AVR C++의 호출 함수에서 이와 같은 것을 사용할 수 있다면 유연하게 활용할 수 있다.
    인터럽트 처리에서 시작된 각 단계의 처리 절차는 아래 그림과 같다.

    만약 아래의 문법을 채택한다면 그림과 같은 처리 절차를 실현할 수 있다.
    interrupt_handlers.cpp
    #include <avr/interrupt.h>
    ISR(PCINT0_vect)
    {
        LightSensorHandler::onPCINT0Interrupt();
    }
    
    LightSensorHandler.h
    #include "nonstd.h"
    class LightSensorHandler
    {
    public:
        LightSensorHandler();
    
        nonstd::function<void()> onBrightened;
    
        static nonstd::function<void()> onPCINT1Interrupt;
    };
    
    LightSensorHandler.cpp
    #include "LightSensorHandler.h"
    nonstd::function<void()> LightSensorHandler::onPCINT1Interrupt;
    LightSensorHandler::LightSensorHandler()
    {
        onPCINT1Interrpt = [this] { onBrightened(); };
    }
    
    nonstd:function 예여기.의 라이브러리를 Arduino로 설정합니다.h의 AVR을 사용하지 않기 위해 몇 가지 수정을 해서 사용했다.std::function는 상당한 기능을 가지고 있다.this 포획된 λ 공식을 저장함으로써 중단 처리 프로그램에서 특정한 실례의 구성원 함수를 순조롭게 호출할 수 있다.
    위에서 말한 바와 같이 앞에서 보여준 중단 호출을 진행할 수 있습니다! 4. 단점 및 요약 개인적으로는 만족하지만 인터럽트 프로세서 ISR(PCINT0 vect)에서 Meow() 함수가 호출될 때까지 여러 차례 함수 호출을 거쳤다.만약 처리 속도를 요구한다면, 이 작법은 매우 엄격할 것이다. 그럼에도 불구하고 최초의 목적인 베터 C의 C++를 조금 넘으면 달성할 수 있다고 생각합니다.C++가 좋아하는 삽입식 프로그래머, 자신만의 독특한 믿을 만한 맞춤법을 꼭 소개해 주십시오! 참고 문헌 (C 언어의 삽입식 소프트웨어 설계서) 끼워넣는 소프트웨어를 위한 구조화된 프로그램 설계(SESSSAMEWG2)|상영회사의 책

    좋은 웹페이지 즐겨찾기