[프로그래밍의 아름다움] 마이크로 컨트롤러 펌웨어의 모듈 형 아키텍처 설계에 대한 자세한 논의

[안내] 왜이 기사를 쓰나요? 최근에 마이크로 컨트롤러의 초심자, 마이크로 컨트롤러 개발을 막 시작하고 아직 RTOS를 사용하지 않은 학생들을 만났는데, 처음 시작했을 때 RTOS를 직접 사용하기 어려울 수 있습니다. 어떤 학생들은 제한된 리소스로 비교적 오래된 마이크로 컨트롤러를 사용하고 RTOS 실행에 적합하지 않습니다. . 또는 RTOS를 사용하여 전반적인 아이디어가 혼란스럽고 어디서부터 시작해야할지 모르겠습니다.이 기사에서는 MCU 프로그램의 전체 프레임 설계에 대한 내 생각 중 일부에 대해 설명합니다.

건축을 논의하는 이유

마이크로 컨트롤러 시스템 개발자의 목표 중 하나는 프로그래밍 환경에서 펌웨어를 만들어 저비용 시스템, 소프트웨어 안정성 및 신속한 개발 반복 시간을 달성하는 것입니다. 이 프로그래밍 환경을 구현하는 가장 좋은 방법은 제품 개발 중에 프레임 워크 역할을하고 "펌웨어 모듈화"또는 하위 시스템을 지원하는 통합 펌웨어 아키텍처 아키텍처를 사용하는 것입니다.

통합 설계 아키텍처를 채택하지 않으면 비즈니스 요구 사항 간의 결합 관계가 복잡해지고 설계 우선 개발 방법론이 채택되지 않습니다. 어디에 작성해야할지 생각하면 나중에 프로그램의 유지 관리가 매우 어려워지고 잠재적 인 버그 / 결함의 위험이 도입됩니다. 그것은 또한 크게 증가 할 것이며 다 인간 협업 개발의 ​​가능성은 없습니다.

펌웨어 모듈성, 테스트 가능성 및 호환성의 올바른 조합과 결합 할 수있는 설계 아키텍처 구조는 모든 펌웨어 개발 프로젝트에 적용하여 코드 재사용 성을 극대화하고 펌웨어 디버깅 속도를 높이며 펌웨어 이식성을 향상시킬 수 있습니다.

모듈 식 아키텍처 설계?

모듈 식 프로그래밍은 프로그램 기능을 펌웨어 모듈 / 서브 시스템으로 분해하며, 각 모듈은 기능을 수행하고 기능을 완료하는 데 필요한 모든 소스 코드와 변수를 포함합니다.

모듈화 / 하위 시스템화는 팀에있는 많은 사람들의 병렬 작업을 조정하고 프로젝트의 다양한 부분 간의 상호 의존성을 관리하며 설계자와 시스템 통합자가 복잡한 시스템을 신뢰할 수있는 방식으로 조립할 수 있도록합니다. 특히 디자이너가 복잡성을 구현하고 관리하는 데 도움이 될 수 있습니다. 응용 프로그램의 크기와 기능이 증가함에 따라 응용 프로그램을 별도의 부분 ( "구성 요소", "모듈"또는 "하위 시스템")으로 분리하려면 모듈화가 필요합니다. 그런 다음 이러한 분리 된 각 부분이 모듈 식 아키텍처의 요소가됩니다. 이러한 방식으로 잘 정의 된 인터페이스를 사용하여 각 구성 요소를 격리하고 액세스 할 수 있습니다. 또한 모듈 식 프로그래밍은 펌웨어의 디버깅, 테스트 및 유지 관리를 단순화하면서 펌웨어의 가독성을 향상시킬 수 있습니다.

한 사람이 독립적으로 프로젝트를 개발하더라도 코드 디버깅, 가독성 및 이식성 측면에서 전체 전략의 모범 사례입니다. 코드가 잘 설계되어 있으면 다른 프로젝트에도 쉽게 적용 할 수 있습니다. 또한 모듈은 이전 프로젝트에서 테스트 및 검증되었으며 새로운 프로젝트에서 다시 사용하면 결함 위험이 크게 감소합니다. 따라서 프로젝트를 수행 할 때마다이 전략을 사용하여 모듈 "바퀴"구성 요소를 지속적으로 축적하십시오. 경험의 성장에 따라 축적 된 "바퀴"가 점점 더 좋아질 것입니다. 그래서 그 장점은 분명합니다. 그렇지 않으면 모든 프로젝트는 긴 개발 시간은 말할 것도없고 개발 수준이 향상되지 않고 반복적 인 작업이 지루할 것입니다. 예를 들어, 이전 기사에서 언급 한 비 휘발성 스토리지 관리 하위 시스템은 잘 설계된 경우 신뢰할 수 있고 휴대 가능한 바퀴가됩니다. 이 구절을 깊이 이해하고 감사없이 가져 가십시오!

펌웨어 모듈 원리

펌웨어 개발에서 모듈 식 프로그래밍의 기본 개념은 펌웨어 모듈을 만드는 것입니다. 개념적으로 모듈은 관심사의 분리를 나타냅니다 . 컴퓨터 과학에서 관심사 분리 는 컴퓨터 프로그램을 거의 겹치지 않는 고유 한 기능으로 분해하는 과정입니다. 초점은 프로그램의 초점 또는 기능이며 기능 또는 동작과 동의어입니다. 관심사 분리 의 개발은 전통적으로 모듈화 및 캡슐화를 통해 달성되었으며, 이는 실제로 디커플링의 아이디어입니다.

펌웨어 모듈은 여러 유형으로 나눌 수 있습니다.

  • 많은 상위 레벨 사용자 모듈과 관련된 코드는 별도의 펌웨어 모듈로 구현됩니다. 기본 하드웨어와 관련된 일반적인 추상 구현 . 예를 들어, hal_adc.c는 ADC 사용자 모듈의 펌웨어 모듈이고 hal_timer.c는 Timer 사용자 모듈의 펌웨어 모듈입니다.

  • 특정 순수 소프트웨어 알고리즘에 대한 코드는 별도의 펌웨어 모듈로 구현됩니다. 예를 들어, alg_filter.c는 소프트웨어 필터 (예 : 중앙값 필터, 평균 필터 또는 가중 평균 필터, IIR / FIR 필터)를 실행하는 펌웨어 모듈입니다.

  • 특정 애플리케이션의 코드는 별도의 펌웨어 모듈로 구현됩니다. 예를 들어, app_battery.c는 배터리 충전기 애플리케이션의 펌웨어 모듈입니다. 특정 도구의 코드는 별도의 펌웨어 모듈로 구현됩니다. 예를 들어 debug_print.c는 로그 인쇄 기능을 구현하는 데 사용되는 펌웨어 모듈입니다.

  • ......

모듈 식 설계를 추정하기위한 몇 가지 규칙을 구현합니다.

  • 모든 모듈 관련 기능은 높은 응집력 을 나타내는 단일 소스 파일로 통합되어야합니다 .

  • 모듈은 모듈의 모든 리소스 (하드웨어 종속성 / 매크로 / 상수 / 변수 / 기능)를 선언하는 헤더 파일을 제공합니다. struct를 사용하여 밀접하게 관련된 변수를 집중화하고 캡슐화하십시오.

  • 모듈의 모든 자체 검사 기능을 실현하기 위해 소스 파일에 자체 검사 코드 부분을 포함합니다.

  • 펌웨어 모듈의 인터페이스는 신중하게 설계하고 정의해야합니다.

  • 펌웨어는 하드웨어에 따라 다르기 때문에 하드웨어의 종속성은 소스 파일 헤더에 명확하게 언급되어야합니다. 예를 들어 매크로를 사용하여 하드웨어 종속성을 정의로 전송하거나 함수를 사용하여 기본 작업을 캡슐화합니다. 새로운 아키텍처 시스템에서는 구현의이 부분 만 이식하면 사용할 수 있습니다.

  • 일반적으로 펌웨어 모듈은 다른 프로젝트의 다른 팀 구성원이 사용할 수 있습니다. 관리 변경, 결함 수리가 포함될 수 있으며 소유자는 모듈을 유지해야합니다. 소스 파일 헤더에는 "작성자"및 "버전"정보가 포함되어야합니다.

  • 펌웨어는 어느 정도 컴파일러에 따라 다릅니다. 소스 파일의 헤더는 컴파일러 또는 IDE 관련 정보를 지정하기 위해 검증이 수행 된 개발 환경을 기반으로 선언해야합니다.

모듈 식 설계는 약간의 호출 오버 헤드를 유발하고 펌웨어의 크기를 증가시킬 수 있습니다. 실제 구현에서는 고려 사항을 절충하십시오. 과도하게 변조하지 마십시오. 따라서 높은 응집력과 낮은 결합 구현 전략을 채택하는 것이 좋습니다. 이전 기사에서 인공 호흡기 PB560의 디자인에 대해 이야기했습니다. 코드를 읽은 후 코드 디자인을 해석하려고했지만 읽은 후 디자인이 너무 모듈화되어 높은 응집력이라는 생각을 깨닫지 못합니다. 소스 코드의 많은 소스 파일은 문제 유형의 추상적 인 실현에 초점을 맞춘 다음 코드 해석을 포기하는 대신 함수 만 구현합니다.

모듈을 분할하는 방법?

엔지니어링 개발은 수요 중심이어야합니다. 첫 번째는보다 합리적인 프레임 워크를 설계하기 전에 요구 사항을 더 명확하게 이해하는 것입니다. 우리는 무엇을 성취해야합니까? 전체적인 디자인 프로세스 전략은 대략 아래 그림과 같습니다. (저는 사람들을 더 직관적으로 만들 수있는 드로잉을 선호합니다)

스스로에게 물어볼 첫 번째 질문은 :이 프로젝트의 주요 기능은 무엇입니까? 이것은 어디에서 왔습니까? 실제 제품 개발이라면 시장 수요에서 나올 수도 있고, DIY 프로젝트라면 확실히 일반적인 아이디어가 떠오르겠습니까? 요컨대, 어디에서 왔든 수요가 먼저 분류되어야합니다. 그렇다면 일반적인 의미에서 요구 사항은 무엇입니까?

  • 스위치 입력, ADC 샘플링, I2C / SPI 통신 등과 같은 하드웨어 IO 인터페이스 요구 사항은 무엇입니까?

  • 센서에서 데이터를 수집하고 가열 장치를 제어하는 ​​것과 같은 비즈니스 로직 요구 사항은 무엇입니까? 이것은 높은 응집력 요구 사항입니다.

  • 제품에서 필터링해야하는 신호, 주파수 도메인에서 분석해야하는 신호 등과 같이 알고리즘과 관련된 기술적 요구 사항은 무엇입니까?

  • 외부 통신 프로토콜 요구 사항이 있습니까?

  • 이력에 저장해야하는 비즈니스 데이터가 있는지 또는 전원을 끈 후 장비 매개 변수를 저장해야하는지 여부

  • 로그 인쇄 요구 사항이 있습니까?

  • ........

  • 너무 많습니다.

펌웨어 모듈의 원칙과 관련 지침 원칙을 결합하면 관련성이 높은 요구 사항이 일련의 모듈 로 추상적으로 구현됩니다 .이 일련의 모듈이 서로 협력하여 특정 비즈니스 요구 사항을 달성 한 후 이러한 모듈은 서브 시스템 . 여러 하위 시스템이 조정되어 main.c의 일정에 따라 제품의 전체 기능을 완료합니다.

스케줄링 통합 방법

RTOS를 사용하지 않는 일부 애플리케이션의 경우 다음 프레임 워크를 사용할 수 있습니다.

void main(void)
{
   /*各模块初始化*/
   init_module_1();
   init_module_2();   
   ....
   while(1)
   {
       /*实现一个定时调度策略*/
       if(timer50ms)
       {
           timer50ms = 0;
           app_module_1();
       }
       if(timer100ms)
       {
           timer100ms = 0;
           app_module_2();
       }
       
       /*异步请求处理,如中断后台处理*/
       if(flag1)
       {
           communication_handler();
       }
       .....
   }
}

RTOS 기반 통합 구현의 예 :

void task1(void)
{
    /*处理子系统相关的初始化*/
    init_task1();
    while(1)
    {
       /*应用相关调用*/
       task1_mainbody();
       ....
    }
}
....
void taskn(void)
{
    /*处理子系统相关的初始化*/
    init_taskn();
    while(1)
    {
       /*应用相关调用*/
       taskn_mainbody();
       ....
    }
}

void main(void)
{
    /*一些基本硬件相关初始化,比如IO,时钟,OS tick定时器等*/
    init_hal();
    ......
    
    /*一些基本RTOS初始化*/
    init_os();
    
    /*任务创建*/
    os_creat("task1",task1,栈设置,优先级,...);
    ......
    os_creat("taskn",taskn,栈设置,优先级,...);
    
    /*启动OS调度器,交由OS调度管理应用任务*/
    os_start();
}

RTOS마다 함수 이름이 다르지만 일반적인 개념은 일반적으로 동일합니다.

결론적으로

이 기사 에서는 모듈 식 설계의 전체 구조가 필요한 이유,이를 수행하는 이점, 특정 지침, 실제로 달성하는 방법, 높은 응집력 및 낮은 결합 을 달성하는 방법에 이르기까지 개인적인 경험과 아이디어 제공합니다. . 동시에 베어 메탈 프로그램의 전체 프레임 워크와 기본적으로 대부분의 프레임 워크 아이디어를 해결할 수있는 RTOS 기반 통합 프레임 워크에 대해 두 개의 데모가 만들어졌습니다. 이전 기사에서 개인이 권장 한 몇 가지 원칙은 굵게 요약되어 있습니다.

  • 모든 모듈 관련 기능은 높은 응집력을 나타내는 단일 소스 파일로 통합되어야합니다.

  • 모듈은 모듈의 모든 리소스 (하드웨어 종속성 / 매크로 / 상수 / 변수 / 기능)를 선언하는 헤더 파일을 제공합니다. struct를 사용하여 밀접하게 관련된 변수를 집중화하고 캡슐화하십시오.

  • 모듈의 모든 자체 검사 기능을 실현하기 위해 소스 파일에 자체 검사 코드 부분을 포함합니다.

  • 펌웨어 모듈의 인터페이스는 신중하게 설계하고 정의해야합니다.

  • 펌웨어는 하드웨어에 따라 다르기 때문에 하드웨어의 종속성은 소스 파일 헤더에 명확하게 언급되어야합니다. 예를 들어 매크로를 사용하여 하드웨어 종속성을 정의로 전송하거나 함수를 사용하여 기본 작업을 캡슐화합니다. 새로운 아키텍처 시스템에서는 구현의이 부분 만 이식하면 사용할 수 있습니다.

  • 일반적으로 펌웨어 모듈은 다른 프로젝트의 다른 팀 구성원이 사용할 수 있습니다. 관리 변경, 결함 수리가 포함될 수 있으며 소유자는 모듈을 유지해야합니다. 소스 파일 헤더에는 "작성자"및 "버전"정보가 포함되어야합니다.

  • 펌웨어는 어느 정도 컴파일러에 따라 다릅니다. 소스 파일의 헤더는 컴파일러 또는 IDE 관련 정보를 지정하기 위해 검증이 수행 된 개발 환경을 기반으로 선언해야합니다.

디자인 우선 개발 모델 을 채택 할 것을 강력히 권장하며 , 점진적으로 디버깅하고 생각하는 곳에 작성하는 것이 더 금기시됩니다. 물론 초보자의 경우 후자 모드를 점진적으로 반복하거나 상대적으로 빠르게 경험을 얻을 수 있습니다. 물론 선택은 전적으로 개인적인 소원에 달려 있습니다.

깊이 읽고주의 깊게 경험한다면 디자인 아이디어에서 통찰력을 얻고 개선해야한다고 생각합니다. 내가 당신을 도울 수 있다면, 나는 매우 안심이되고, 너무 많은 단어를 코딩하기 위해 열심히 노력했습니다. 물론 그 기사가 귀중하다고 생각 되시면 제가 읽도록 도와 주시거나 공유 해주세요. 물론 MCU 개발의 신에게는 더 많은 친구들이 볼 수 있도록하자. 기사의 견해는 다소 피상적으로 보인다. 감사는 원하는대로하세요.

추천

출처blog.csdn.net/u012846795/article/details/108544332