EFM Gekko 컨트롤러 (http://energymicro.com/)를 사용하여 배터리 구동 소프트웨어를 개발하려고하고 있는데, 아무 쓸모가 없을 때 컨트롤러가 잠들기를 원합니다. WFI (Wait For Interrupt) 명령어는이 목적으로 사용됩니다. 인터럽트가 발생할 때까지 프로세서를 휴면 상태로 만듭니다.
어딘가에 무언가를 저장하여 수면을 취한 경우,로드 익스 클루 시브 / 스토어 익스 클루 시브 작업을 사용하여 다음과 같은 작업을 수행 할 수 있습니다.
// dont_sleep은 무언가가 발생할 때마다 2로로드됩니다. // 메인 루프가 적어도 한 번 순환하도록해야합니다. 인터럽트가 발생하면 // 다음 문장에서 2로 리셋되게하는 발생 // 그 후에 인터럽트가 발생한 것처럼 동작합니다. store_exclusive (load_exclusive (dont_sleep) >> 1); while (! dont_sleep) { // 다음 명령문과 store_exclusive 사이에 인터럽트가 발생하면 잠자 지 마십시오. load_exclusive (SLEEP_TRIGGER); if (! dont_sleep) store_exclusive (SLEEP_TRIGGER); }
load_exclusive와 store_exclusive 조작 사이에 인터럽트가 발생하면 store_exclusive를 건너 뛰어 루프를 한 번 더 시스템이 실행하게됩니다 (인터럽트가 dont_sleep을 설정했는지 확인). 불행히도 Gekko는 쓰기 주소 대신 WFI 명령어를 사용하여 절전 모드를 트리거합니다. 같은 코드 작성
if (! dont_sleep) WFI ();
'if'와 'wfi'사이에 인터럽트가 발생하여 dont_sleep을 설정할 위험이 있지만 wfi는 계속 진행됩니다. 이를 방지하는 가장 좋은 패턴은 무엇입니까? PRIMASK를 1로 설정하여 WFI를 실행하기 직전에 인터럽트가 프로세서를 중단하지 못하게하고 바로 다음에 지우겠습니까? 아니면 더 나은 트릭이 있습니까?
편집하다
이벤트 비트가 궁금합니다. 일반적인 설명에 따르면 다중 프로세서 지원을위한 것이지만 다음과 같은 것이 작동하는지 궁금합니다.
if (dont_sleep) SEV (); / * WFE 지우기 이벤트 플래그를 따르지만 잠자기 상태가 아님 * / WFE ();
don't_sleep을 설정하는 모든 인터럽트는 SEV 명령도 실행해야하므로 "if"테스트 후에 인터럽트가 발생하면 WFE는 이벤트 플래그를 지우지 만 슬립 상태가되지는 않습니다. 좋은 패러다임처럼 들립니까?