Arduino의 QP 상태 프레임 워크를 이식 한 사람이 있습니까?


12

데이터 로깅 프로젝트에 대한 가능한 접근 방식을 검토하면서 "C / C ++의 실용적인 UML 상태 차트"라는 책이 Arduino와의보다 심각한 작업에 매우 흥미 롭다는 것을 알게되었습니다. QP는 임베디드 시스템을위한 초경량, 오픈 소스, 상태 머신 기반 프레임 워크 제품군으로, http://www.state-machine.com/ 에서 프레임 워크 (GNU GPL2)를위한 코드와 포트를 배포합니다 . WinAVR / Gnu C ++ 도구 세트를 사용하는 AVR 및 AVR mega 용 포트.

칩별 헤더가 적합하지만 보드 BSP 파일을 작성했거나 이러한 프레임 워크에 대한 경험이 있습니까? 나는 단지 책을 시작하고 있기 때문에 어떤 의견이라도 대단히 감사합니다.


QP 상태 문자 언급에 대해 +1을 제공하는 것에 대한 Jason S의 의견에 +1. 아, 스타와 +1 주제 하나 ... 그루비 소리를 내고 답변을 기대합니다 : P (스팸이 유감 스럽습니다. 오늘 웃기는 기분으로;))
cyphunk

답변:


4

나는 전염병과 같은 이런 종류의 것을 피할 것입니다.

내가 경험 한 "심각한"저수준 소프트웨어는 다음과 같은 형태의 상태 머신입니다.

#include <stdio.h>

typedef enum
{
    STATE_INIT,     // Description
    STATE_RUNNING,  // Description
    STATE_COMPLETE  // Description
} state_t;

int main(void)
{
    state_t state = STATE_INIT; // setup the initial state

    while(1)
    {
        os_run(); // call the OS services (poll the UART, check buttons, etc.)

        switch(state)
        {
            case STATE_INIT:
                state = STATE_RUNNING;
                puts("init");
                break;
            case STATE_RUNNING:
                state = STATE_COMPLETE;
                puts("running");
                break;
            case STATE_COMPLETE:
                puts("complete");
                break;
        }
    }
    return 0;
}

C / C ++에는 다른 좋은 접근 방법이 많이 있지만 가장 좋아하는 방법은 아닙니다.

QP와 같은 도구의 큰 문제는 원하지 않는 일을하는 것이 매우 어렵다는 것입니다. 코드를 수동으로 바이올린을 선택하면 특별한 경우를 영원히 유지해야합니다.

UML 상태 차트는 문서화, 교육 및 분석을위한 환상적인 도구입니다. 그러나 실제 프로그래밍에는 적합하지 않습니다.


1
코드가 독점적 인 경우 QP의 라이센스 비용을 잊지 마십시오.
mjh2007

1
상태 머신 코드의 사소한 개선 : 종종 상태 변경을 대기하고 switch 문 바로 앞의 실제 상태 만 변경하는 안정성에 도움이됩니다. 이렇게하면 STATE_COMPLETE로 변경되었다고 생각한 직후 상태가 STATE_INIT로 변경되는 인터럽트에 대해 걱정할 필요가 없습니다.
AngryEE

3

저는 GPL 라이센스 때문에 개인적으로 QP 프레임 워크 / 라이브러리를 사용하지 않았습니다. 당시에는 고용주가 QP를 사용하여 HSM (계층 상태 머신)을 실험 할 수 있도록 반죽을 기침 할 준비가되지 않았다고 생각했습니다. Joby의 예제와 같이 수백 줄의 코드를 사용했지만 1000 배가 된 끔찍한 상태 머신을 리팩토링 할 때 QP와 비슷한 자체 구현해야했습니다. 유지하기가 끔찍한 고통이었습니다. 나는 다른 것을 깨뜨리는 것을 두려워하여 새로운 것을 추가하려고하는 것을 두려워했습니다.

코드를 HSM으로 다시 디자인하여 시스템의 작동 방식에 대해 개인적으로 훨씬 더 이해가되었습니다. 내가 상상했던 것보다 훨씬 잘 작동했습니다. 수정하고 유지하는 것이 훨씬 쉬웠으며 꿈을 꾸었습니다. 시스템의 예기치 않은 동작으로 인해 상태 시스템을 거의 다시 실행해야했습니다. 내가 만든 프레임 워크로 수정하는 것이 훨씬 쉬웠으며 QP에서도 그렇게 쉬웠을 것입니다. 내가 구축 한 프레임 워크는 널리 보급되어 코드베이스 내부의 다른 복잡한 상태 시스템으로 확산되었습니다.

나는 친구가 잘 작동하는 로봇에서 Java를 사용하여 양자 프레임 워크를 구현하도록했습니다. 특정 입력을 기반으로 한 로봇의 의사 결정 알고리즘의 일부였습니다. 로봇의 상태에 따라 결정을 내릴 때 자연스럽게 적합했습니다.

QP의 아름다움을 이해하는 것은 프로세서에 최적화 된 상태 머신 설계를위한 프레임 워크를 준비하고 비효율적 인 상용구 코드를 내뿜는 CASE 툴에 의존 할 필요가 없다는 것입니다. 그러나 디자인을 설명하는 복잡한 상태 머신 세트를 구현 한 경우에만 QP를 사용합니다.

당신이 가진 모든 것이 Joby의 예와 같이 단순한 것이라면, 그가 설명한 것처럼 그렇게하십시오. 그러나 상태가 다른 조건으로 싸여있는 모든 종류의 "if else"문으로 상태 머신이 커지고 커지면 QP와 같은 것을 시도하여 HSM으로 나누는 것이 좋습니다.


1

Joby의 예제에서 매우 큰 상태 머신을 구현하는 더 확실한 방법은 case 문을 함수 포인터 배열로 바꾸는 것입니다. 그런 다음 함수 내에서 특정 상태에 대한 모든 코드를 분리 할 수 ​​있습니다. 이런 식으로 구현하려면 훨씬 적은 프로그램 메모리가 필요하다는 것을 알았습니다.


1

case 문을 함수 포인터 배열로 교체

QP 작업 방식은 다음과 같습니다. 상태 표현은 함수 포인터 (현재 상태에 대한 함수) 일뿐입니다. C ++에서는 멤버 함수에 대한 포인터 일 수 있지만 기본적으로 동일합니다. 현재 상태 함수는 이벤트 및 일부 의사 이벤트 (항목, 종료)와 함께 호출되며, 그 중 하나는 항상 처리되지 않으며 중첩 된 전환을 수행 할 때 상태 중첩을 결정하는 데 사용됩니다 (QP는 계층 적 상태 시스템을 지원함).

Miro Samek는 곧 Arduino를 대상으로하는 항구를 운영 할 것이라고 말했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.