2012-04-26 2 views
0

저는 실행중인 몇 가지 작업에 몇 가지 문제가있었습니다. 세 가지 작업이 있습니다. 하나는 LCD 업데이트 작업이고 나머지 두 가지는 모터 드라이버 작업입니다. 또한 모터 드라이버 작업에 메시지를 게시하는 두 개의 ISR이 있습니다. 지금까지 안전하게 포인터를 전달하는 것과 같은, 내가 구조체 만드는 방법에 대해 생각했다 :RTOS - 구조체를 할당하고 대기열을 통해 전달합니다.

typedef struct message{ 
    enum BUTTON_1 = 0, BUTTON_2 = 1, NO_BUTTON = 3; //button ISR to increase motor drive 
    int timestamp; //A timestamp for the RPM of the motors 
    } 

지금 공유 메모리에 문제가에서 온다, 그래서 나는 생각했다 :

struct message* update_msg = (struct message*)malloc(sizeof(struct message)); //from here I dont know how to creat an object that fills the space allocated. 

내가 다음에 포인터를 보낼 것입니다 큐를 통해 구조체 :

OSTASKQPOST((void *)(st_size) 
    .... 
) 

마지막 작업 후 끝에서 메시지를 가져오고, 내가 메모리 할당을 해제해야 그것이 무엇 멤버 변수를 필요로한다.

free(st_size) 

이럴 가능성이 있습니까?

답변

2

이것은 스레드 간 데이터 통신을위한 'Inter-Thread Comms 101'방법입니다. 그것은 잘 작동합니다. 32 비트 폭의 대기열을 가정하면 구조체 주소 또는 객체 인스턴스를 게시하면 메시지 크기가 커짐에 따라 (값별로 데이터를 직접 게시하는 것보다) 매우 빨리 이기기 시작합니다.

다른 메커니즘이 있습니다. RAM이 제한되어 있고 메모리 공간이 속도보다 더 중요한 내 ARM 임베디드 프로젝트에서 255 개의 전역 메시지 인스턴스 배열을 풀로 사용하는 경향이 있습니다 ('유효하지 않은 인덱스'에 대해 255 개의 값을 예약하는 것이 유용합니다). . 즉, 각 메시지는 단 한 바이트 만 참조 할 수 있으며 각 메시지의 두 바이트는 목록과의 연결을 허용합니다. 연결된리스트 헤드 바이트, 뮤텍스 및 세마포어는 스레드 간 통신을위한 블로킹 대기열을 만듭니다. 추가 저장 공간이 필요하지 않습니다. 모든 메시지는 시작할 때 '풀'대기열에 연결되고 팝 (popped)되고 스레드간에 대기되며 응용 프로그램 스레드에 의해 풀로 다시 릴리스됩니다.

하드웨어에서 데이터를받는 ISR은 malloc을 호출하거나, 뮤텍스를 얻거나, 메시지 인덱스에 대한 세마포를 기다릴 수 없습니다. 나는 잠금이없는 또 다른 큐 클래스를 사용하고, 바이트 인덱스의 원형 큐만 사용한다. 나는 시작할 때 몇 가지 메시지를 보낸다. 인터럽트 처리기는이 'ISRpool'에서 메시지를 대기열에서 제거하고, 하드웨어를 채우고, int (비트 필드!)를 설정하고, ISR을 식별하고, 메시지 색인을 'ISRout'순환 대기열로 보내고, 세마포 신호를 보내고 OS. 세마포어를 기다리는 스레드는 깨어나서 ISRout에 데이터가 있음을 알고 그것을 팝하고 ISR의 메시지를 처리하는 스레드에 큐를 대기시킵니다. 또한 'ISRhandler'스레드는 메시지가있는 ISRpool을 '토핑 (up up)'하여 데이터가 도착할 때 ISR에 항상 메시지가 준비되도록합니다. 이 간단하고 공유 된 'ISRpool'시스템은 인터럽트가 우선 순위가 높은 인터럽트를 다시 활성화하지 않는 경우에만 작동합니다!

비슷한 방식으로 tx ISR에 대한 메시지가 ISR의 픽업을 위해 순환 대기열로 푸시됩니다 (인터럽트가 잠시 중단되어 하드웨어가 유휴 상태이고 하드웨어 FIFO가 '초벌링'을 시작해야 tx tx 다시 중단). '사용 된'tx 메시지는 rx ISRpool에 덤프됩니다. 입력으로 재사용 될 수 있습니다.

풀링 체계에는 몇 가지 장점이 있지만 즉시 명백하지 않습니다. 하나는 'malloc 없음, 자유 없음'입니다. 메시지는 확실히 유출 될 수 있지만 신속하게 알 수 있습니다. '모니터/디버거'에 의해 실행되는 UART의 터미널 프롬프트는 '223>'입니다. 번호는 풀 수준입니다. 이 숫자가 내려 가고 다시 올라 오지 않으면 내가 누출 된 걸 압니다. 이것은 Valgrind에서 앱을 실행할 수 없을 때 매우 중요합니다.

관련 문제