2016-11-02 2 views
0

Keil의 CMSIS-RTOS Tutorial을 팔로우 중입니다.osKernalSysTick()의 ​​랩 어라운드가 필요합니까?

섹션 : 이것은 서브 - 밀리 세컨드의 지연을 넣어 이하의 방법을 제공하는 서브 밀리는

osKernelSysTick (
int32_t tick,delayPeriod; 
tick = osKernelSysTick(); // get start value of the Kernel system tick 
// Then we can scale a period in microseconds to a SysTick count value 
delayPeriod = osKernelTickMicroSec(100)); 
// This then allows us to create a delay for the the required period. 
do { // Delay for 100 microseconds 
} while ((osKernelSysTick() - tick) < delayPeriod); 

)는 롤링 32 비트 카운터의 값을 반환 지연; 이 구현은 그 값의 랩 어라운드를 제공하지 않습니다.

랩 어라운드가 발생하면 의도 한 지연이 발생하지 않습니다. Keil의 공식 문서에 버그가 있습니까? 아니면 뭔가 빠졌습니까?

+1

_ "이 구현은 그 값의 랩 어라운드에 맞지 않습니다."_ 확실합니까? 2의 보수 산술을 염두에두고 랩 어라운드 케이스의 수학을 연습 해보십시오. – Notlikethat

+0

@Muhammad - 문제를 복잡하게 만들려면 옵티마이 저가 최적화를 수행하고 위에서 정의되지 않은 동작을 제거하는 것에 대해 걱정해야합니다. 'uint32_t '를 사용하면 많은 문제를 피할 수있었습니다. 또한 [Signed Overflow]에 대한 Ian Lance Taylor의 블로그 (http://www.airs.com/blog/archives/120)를 참조하십시오. 그리고 * signed integer overflow *는 정의되지 않은 동작이지만 * unsigned integer wrap *은 잘 정의 된 동작입니다. – jww

+0

함수 프로토 타입은'uint32_t osKernelSysTick (void)'입니다. 부호없는 값을 반환합니다. 변수'ticks '유형을 변경해야합니다. – Gerhard

답변

3

산술이 수행되는 방식 때문에 보여주는 구현은 둘러 감기를 처리하지 못합니다.

do { // Delay for 100 microseconds 
} while ((osKernelSysTick() - tick) < delayPeriod); 

타이머 랩시 산술 오버플로가 발생할 수 있습니다.

unsigned 변수를 사용하고 의 변수를 필요한 기간과 비교하기 전에 전에 비교하면 피할 수 있습니다. 부호없는 변수는 C 표준에 의해 랩핑이 보장됩니다.

uint32_t tick, delayPeriod, elapsed;   // unsigned 
tick = osKernelSysTick(); 
delayPeriod = osKernelTickMicroSec(100)); 

do { 
    elapsed = osKernelSysTick() - tick;   // separate arithmetic wraps cleanly 
} while (elapsed < delayPeriod); 

참고이 기능은 어쨌든 uint32_t osKernelSysTick로 정의하기 때문에 원래의 예는 서명 유형을 사용하여 잘못된입니다.

+1

구현 정의 (_not_ undefined) 동작에 약간 문제가 있습니까? 물론, 언어 변호사의 관점에서 보았을 때 약간 엉성한 것일 수도 있지만, "휴대용 임베디드 코드"가 존재한다면 그것은 모순입니다. [이 코드가 구현 된 구현] (http://www.keil.com/support/man/docs/armcc/armcc_chr1359125009767.htm)은 2의 보수를 보장합니다 (대상 플랫폼에 대한 다른 구현과 마찬가지로). 따라서 초기 'INT_MAX'보다 큰 값을'tick'에 할당하는 것은 예측 가능합니다. 이후 모든 것이 워시에서 빠져 나옵니다 ... – Notlikethat

+0

명시 적 중간 변수가 필요 없습니다. 왜냐하면 모든 것이 모두'int'로 이미 표현 되었기 때문입니다. 일반적인 산술 변환을 통해 서명되지 않은 상태로 자동 승격됩니다. – Notlikethat

+0

@ 분리가 산술 오버플로와 비교 간의 혼동을 방지합니다. 그리고 이미 설명했듯이 오버플로가 정의되지 않았기 때문에'int'는 잘못된 유형입니다. –