2012-02-08 5 views
6

디버깅하려고 할 때 코드가 사라지는 이상한 버그가 있습니다. 내 타이머 인터럽트에서 중단 점을 설정할 때 Schrödinger 버그가 사라짐

나는 이런 식으로 뭔가가 (항상 시스템 시세를 실행) : 내 메인 루프에

if (a && lot && of && conditions) 
{ 
    some_global_flag = 1;     // breakpoint 2 
} 

을 나는 메인 루프에서이 조건을 때 호출되지 않습니다

if (some_global_flag) 
{ 
    some_global_flag = 0; 
    do_something_very_important(); // breakpoint 1 
} 

이 타이머의 조건이 충족되었다고 생각합니다. 조건은 외부 (포트 핀, ADC 결과 등)입니다. 먼저 위치 1에 중단 점을 넣습니다. 결코 중단되지 않습니다.

이를 확인하기 위해 중단 점 nr을 넣습니다. 2 줄에 some_global_flag = 1;,이 경우 코드 작동합니다 : 조건이 모두 참일 때 트리거됩니다.

업데이트 1 :

if (a && lot && of && conditions) 
{ 
    some_global_flag = 1;     // breakpoint 2 
} 


if (some_global_flag) 
{ 
    #asm("NOP"); // breakpoint 3 
} 
:

일부 타이밍 조건이 담당하고, 타이머의 if 디버깅하지 않고 실행하면 입력되지 않습니다 여부를 연구하기 위해, 나는 내 타이머에 다음을 추가

플래그는 코드의 다른 곳에서는 사용되지 않습니다. 그것은 RAM에 있으며 RAM은 처음에 0으로 지워집니다.

이제 모든 중단 점을 사용하지 않도록 설정하거나 주에서 중단 점 1 만 사용하도록 설정하면 코드가 제대로 작동하지 않고 함수가 실행되지 않습니다. 그러나 NOP에서 중단 점 3 만 활성화하면 코드가 작동합니다! 중단 점이 트리거되고 계속 된 후 함수가 실행됩니다.

타이머 인터럽트의 시작 부분에 "SEI"에 의해, 인터럽트였다 업데이트 2

(그것은 가시 가청 출력을 가지고, 그래서 실행하는 경우는 명백하다). 나는 그 라인을 삭제했으나 그 행동은 눈에 띄는 방식으로 바뀌지 않았다.

업데이트 3 : 어떤 외부 메모리를 사용하지 않는

. 플래시의 한계에 매우 가깝기 때문에 컴파일러에서 최대 크기 최적화가 있습니다.

컴파일러 (CodeVision)가 책임 져야합니까? 아니면 제가 잘못 했습니까?

+0

중단 점을 설정하는 대신 로깅을 추가 할 수있는 방법이 있습니까? 나는 보통 그것을 제안하는 것을 망설이지 만,이 경우에는 시스템에 덜 어지럽 힐 수 있습니다. 특히, 내가 기록 할 것은 타이머 인터럽트 코드를 통과 할 때마다 조건의 상태입니다. –

+1

some_global_flag는 어떻게 정의됩니까? 'volatile int some_global_flag'을 사용하고 있습니까? – DipSwitch

+0

외부 메모리를 사용하고 있습니까? 아니면 내부 SRAM입니까? 정확히 어떤 칩을 사용하고 있습니까? – DipSwitch

답변

3

이상하게 보일 수 있지만 결국 입력 라인 중 하나에서 강한 과도 전류가 발생 함이 판명되었습니다 (시스템에 전력을 공급하지만 ADC 측정 또한 조건으로 사용됨).

시스템은 주기적으로 정전이 발생할 수 있으며 중요한 임시 데이터는 내부 SRAM의 일부로 유지됩니다. 내부 SRAM은 시동 후 청소되지 않고 데이터를 유지하도록 설계되었습니다 (10 분 이상) CPU가 절전 상태 일 때 작은 콘덴서를 사용하십시오.

시스템의이 부분을 테스트하여 완벽하게 작동했기 때문에 나는 질문에서 이것을 게시하지 않았습니다. 그래서 나는 당신을 벗어나고 싶지 않았습니다.

결국 알게 된 것은 새로운 기능이 매우 강력한 과도기를 생성하는 환경에서 사용되었고 내 질문에서 조건 중 하나는 " 영원한 RAM을 ", 그리고 마지막으로 중단 점을 사용하여 그 과도의 효과에서 날 구해줬습니다.

마지막으로 문제는 타이밍 조정으로 해결되었습니다.

편집 : 문제의 위치를 ​​찾는데 도움이되는 것은 "영구 RAM"영역에 가장 중요한 변수의 값을 기록했고 그 중 일부가 손상된 것을 볼 수있었습니다.

+2

이것은 실제로 이런 종류의 문제에 대한 일반적인 이유입니다. 디버깅은 어떤 식 으로든 타이밍을 혼란스럽게하는 경향이 있으며, 타이밍 문제에 민감한 상황에 있다면 디버깅이 확실히 영향을 미칠 수 있습니다. 디버깅이 영향을 미치는 데는 의미있는 정보가별로 없습니다 (부분적으로는 디버깅이 타이밍에 어떤 영향을 미치는지 알려주지 않기 때문입니다). –

+2

나는 당신이 발견 한 것뿐만 아니라 문제를 어떻게 진단했는지 설명하는이 대답에 약간을 더하는 것이 흥미로울 것이라고 생각한다. 또한 이것이 올바른 대답이라는 것을 알고 있으므로 완벽을 기하기 위해 그것을 받아 들여야합니다. :) –

+0

당신이 그걸 잘 해결 했어. 선한 것이 나왔습니다 : 당신은 당신의 세계적인 깃발에 휘발성을 더했습니다 (만약 당신이 그것을 추가하지 않았다면, 그것은 정말로 거기에 있어야합니다). – Gauthier

1

내가 틀릴 수도 있지만 여기에 문제가있는 보드에 연결하여 디버거를 사용하여 실행중인 하드웨어에서 프로그램을 디버깅 할 경우 실행시 마이크로 컨트롤러의 동작을 변경할 수 있다고 생각합니다. 첨부 .... 다른 그 위의 제안 휘발성 키워드는 내가 단서가 없습니다.

+0

나는 또한 행동에 변화가없는 '휘발성'으로 시도했다. – vsz

+0

이상한 점은 디버거가 사용될 때 ** 정확한 ** 기능이 달성된다는 것입니다. – vsz

4

이것은 아마도 일반적인 최적화/디버깅 버그 일 것입니다. some_global_flag이 휘발성으로 표시되어 있는지 확인하십시오. 이것은 int uint8 uint64가 될 수 있습니다.

volatile int some_global_flag 

이렇게하면 some_global_flag의 값이 무엇인지에 대한 가정을하지 않도록 컴파일러에 지시합니다. 컴파일러/최적화 기가 인터럽트 루틴에 대한 호출을 볼 수 없기 때문에이를 수행해야합니다. 따라서 some_global_flag가 항상 0 (초기 상태)이고 변경되지 않았다고 가정합니다.

죄송합니다 당신은 이미 그것을 시도 부분을 오해 ...

이 당신은 AVR-GCC와 코드를 컴파일하고 같은 동작이 있는지 확인하기 위해 시도 할 수

...

+0

나는 휘발성과 함께 그것을 시도, 행동에 변화가 발생하지 않습니다. – vsz

4

디버거가/할 수 프로세서가 실행되고 코드가 실행되는 방식을 바꿔야합니다.

나누고 정복하십시오. 작동 될 때까지 제거를 시작하십시오. 아무것도하지 않고 그 시작과 함께 타이머 인터럽트와 주 루프에 몇 줄의 코드를 추가합니다. do_something_very_important()는 깜박 거리거나 깜박 거리는 것처럼 간단합니다. 그게 작동하지 않으면 더 큰 애플 리케이션을 작동시키지 않을거야. 그게 작동하지 않으면 init 코드와 인터럽트에 더 많은 조건을 추가하기 시작하지만 설명 된 몇 줄 이상으로 메인 루프를 복잡하게 만들지는 않습니다. 실패 할 때까지 더 많은 코드를 다시 추가하여 인터럽트 처리기 조건을 늘립니다.

한 가지를 추가하고 제거하고 제거 할 수있는 경계에 이르면 컴파일러 문제인지 확인하기 위해 몇 가지 디스 어셈블리를 수행하십시오. 이것은 분명하지 않은 경우 다른 티켓을 보증 할 수 있습니다. "내가 추가 할 때 왜 내 AVR 인터럽트 처리기가 작동하지 않습니까?"

코드 줄 수를 줄이면 그래서 몇 가지 인터럽트 라인을 메인과 그냥 다른 사람들이 자신의 하드웨어에서 시도하고 아마도 그것을 병렬로 파악할 수 있도록 게시하십시오.

1

이것은 ARM 프로세서를 전제로 작성되었습니다.

중단 점 (RAM 또는 ROM bkpoint)을 사용하면 프로세서가 중단 점 (정지 모드 또는 모니터 모드)에서 실행 모드에서 디버그 모드로 전환하고 강제로 디버그 속도로 실행하거나 중단 핸들러를 실행하고 따라서 JTAG 기반 디버깅은 기본적으로 방해적인 디버깅입니다.

ARM (또는 다른 유형의 버스 계측기)의 ETM (내장형 Trace Macrocell)은 방해가되지 않도록 설계되었으며 실시간으로 지침과 데이터를 기록하여 실제 발생한 결과를 검사 할 수 있습니다.