인터럽트로드가 심한 경우 I2C 읽기 / 쓰기 오류


10

내 시스템에서 I2C를 사용하고 있으며 다른 소스의 인터럽트로드가 많으면 I2C 통신이 쉽게 중단된다는 것을 알고 있습니다. I2C에 대한 예상 동작입니까? 인터럽트로드에도 불구하고 예상했지만 I2C는 시간이 중요한 인터페이스가 아니기 때문에 여전히 괜찮습니다. 시계에는 데이터가 제공됩니다.

최신 정보:

프로세서는 STM32입니다. 인터럽트는 ADC로 인한 것이므로 읽기 이벤트 중에 인터럽트를 비활성화 할 수 없으므로 i2c 통신을보다 안정적으로 만들 수있는 솔루션을 찾아야합니다. STM32는 마스터이고 슬레이브는 다른 장치 (가속도계)입니다.

업데이트 2 :

작은 플라잉 케이블을 사용하여 로직 분석기를 시계에 연결하면 문제가 사라집니다. 흥미롭게도 인터럽트로드가없고, 읽기 쓰기가 잘 작동하며, 인터럽트로드가있을 때는 그렇지 않습니다. 그러나 프로브를 클럭에 연결하면 인터럽트 쓰기에서도 읽기 쓰기가 작동합니다. 어딘가에 정전 용량 문제가 있다고 생각합니다.


1
귀하의 질문은 시스템 디자인에 달려 있기 때문에 매우 일반적입니다. I2C 처리 방법은 실제로 버스의 장치에 따라 다릅니다. 당신은 그들을 무시하고 나중에 올 수 있습니까? FPGA에서는 로직을 설계하여 많은 것을 처리하고이를 피할 수 있습니다. 다시, 우리는 마이크로 컨트롤러와 다른 것들에 대한 더 많은 정보가 필요합니다. 일반적으로 여기에서 좋은 해결책은 RTOS를 사용하고 작업을 올바르게 설계하는 것입니다.
구스타보 Litovsky

찾아야 할 두 가지, 풀업 또는 i2c 마스터 및 슬레이브 전원의 전압 처짐 또는 EMI 또는 정전 용량 문제. 인터럽트로드에 관해서는, 마스터가 인터럽트를 처리하기 위해 멈추고 있다는 것을 의미합니까? 일부 칩은 무한한 클럭 스트레칭을 허용하지 않습니다.
통행인

@GustavoLitovsky는 맞지만 CPU 사이클의 80 %가 ADC 인터럽트를 처리하고 있으며 비 ISR 창에서 읽기 사이클을 수행 할 시간이 충분하지 않습니다. 따라서 OS 시스템을 얼마나 잘 디자인하든 읽기가 중단됩니다.
Ktc

@Passerby 당신이 옳을 수도 있습니다. 로직 분석기의 프로브를 클럭 라인에 연결하면 문제가 사라졌습니다.
Ktc

풀업의 현재 값은 얼마입니까? 다른 값으로 변경해 보셨습니까? (첫 번째 추측으로 10k 또는 4k7 또는 2k를 시도하십시오)
Tom L.

답변:


9

이것은 소프트웨어 문제입니다. 인터럽트 서비스에 너무 많은 시간을 소비하고 있으며 I2C 루틴이이를 처리 할 수 ​​없습니다 (그렇지 않은 두 가지 사항). 나는 몇 가지 비슷한 상황을 겪었습니다.

첫째 : 인터럽트에서 가능한 한 적은 작업을 수행하고 데이터를 읽고 저장하며 ISR 외부에서 수행 할 수있는 처리를 수행하지 않으며 수학은 많은 CPU 사이클을 취할 수 있으며 CPU는 다른 작업을 수행 할 수 없습니다 그 인터럽트 중에.

둘째 : 물건을 자동화하기 위해 DMA를 조사하므로 인터럽트는 거의 배경 자동화 프로세스가됩니다.

셋째 : I2C가 중요하다면 THAT도 인터럽트에 넣지 만 우선 순위를 정하십시오.

넷째 : I2C 루틴이 실패한 이유를 해결하고, I2C 자체는 매우 간헐적 인 타이밍, 일시 정지 및 대기 등을 견딜 수 있으므로 루틴이이를 허용하도록 수정해야 할 수도 있습니다.

다섯 번째 : 인터럽트를 "체인"할 수 있는지 확인하십시오. ADC 판독을보다 효율적으로 처리하거나 인터럽트하기 전에 더 많은 작업을 수행하는 다른 모드로 ADC를 배치 할 수 있습니다 (EG는 모든 판독 값을 사용할 수있을 때까지 기다립니다. 그런 다음 8 개의 개별 ADC 채널 읽기에 대해 8 개의 개별 인터럽트가 아닌 한 번의 히트로 모두를 읽습니다).

여섯 번째 : 보드의 오실로스코프 또는 로직 분석기와 여분의 IO 핀을 사용하여 각 코드 비트에서 소비 한 시간을 추적하여 속도를 높일 수 있는지 확인하십시오. (기능 / ISR을 입력 할 때 핀을 높게 설정하고 종료시 다시 낮게 설정하십시오).

일곱째 : ADC를 너무 많이 읽어야하는지 결정하고 느리게 진행하면 상황이 악화 될까요? 반 직관적이지만 때로는 느리게 실행하면 실제로 신호를 평균화하고 스파이크 / 과도 현상을 줄여 문제를 일으키거나 제거하기 위해 추가 처리가 필요할 수 있습니다. 모터 제어 PID 루틴을 1/4의 속도로 간단히 실행하여 프로세스에서 CPU 시간을 절약함으로써 모터 제어 PID 루틴을 개선했습니다.


제안 해 주셔서 감사합니다. 문제는 어떻게 든 하드웨어를 가리 킵니다.
Ktc

4

다른 것들로 바쁜 버스 노예는 통신이 끝날 때까지 시간을 벌기 위해 시계를 늘릴 수 있습니다. ACK / NACK 클럭 펄스를 즉시 보내지 않고 응답 할 준비가 될 때까지 통신을 중간 상태로 유지합니다.

이러한 상황을 처리하는 데는 적절한 방법으로 시계 스트레칭이 있습니다. 확장되지 않고 다른 나쁜 일 (버스 중단 / 재시작, 유효한 주소 또는 명령 등을 NACK하는 장치)이 문제가 될 수 있으며 마스터 항목에 정렬을 유지하기 위해 추가 부담이 발생합니다 (명령을 반복해야 함) , NACK 등을 추적)


당신 말이 맞지만 문제는 호스트입니다. 주인은 노예가 아닌 다른 것들로 바쁘다. 그래서 시계 스트레칭을 할 수 있는지 확실하지 않습니다.
Ktc

온보드 I2C 하드웨어를 사용하거나 GPIO 라인에서 프로토콜을 비트 뱅킹합니까? 표준에 정의 된 특정 I2C 시간 초과 간격이 없으므로 슬레이브는 마스터가 패킷을 완료 할 때까지 무기한 대기해야합니다.
Adam Lawrence

STM32 IC2 API를 사용합니다. 커패시턴스 문제처럼 보이는 업데이트를 참조하십시오.
Ktc

1

STM32의 기능에 따라 (내가 사용한 적이없는) 다음 방법 중 하나를 시도 할 수 있습니다. 수행하려는 작업에 대한 자세한 정보를 제공 할 수 있고 각 인터럽트가 현재 필요한 형식으로 필요한 이유에 대한 설득력있는 주장이있는 경우보다 구체적인 답변을 생각할 수 있습니다. 그러나 특히 귀하의 경우, I2C는 충분히 작성된 인터럽트 루틴에 문제가되지 않을 정도로 느립니다.

  • 무엇이든 인터럽트는 일반적으로 비활성화 할 수 있습니다. 일반적인 컨트롤러에는 최대 1 개 또는 2 개의 비 Maskable 인터럽트가 있으며 그 중 하나는 재설정됩니다. 인터럽트 구동 방식의 무언가 (귀하의 경우 ADC 또는 I2C) 가 필요 하지 않은 경우 해당 주변 장치 코드를 인터럽트를 사용하지 않는 것으로 바꾸고 인터럽트를 비활성화하십시오.

  • 인터럽트 핸들러는 길지 않아야합니다. 인터럽트 벡터 자체에서 가능한 한 적게하십시오. 인터럽트에 대한 극단적 인 최소한의 접근 방식은 인터럽트 핸들러 루틴 내에서 플래그를 설정하는 것입니다. 예를 들어, 메인 루프는 거기에서 모든 무거운 작업을 수행합니다. 특정 애플리케이션 및 펌웨어 아키텍처에 필요한 것은 간단하지 않을 수 있습니다. 그러나 실제로 인터럽트 내에서 얼마나 많은 작업을 수행해야하는지 확인하는 것이 좋습니다.

  • 주변 장치 DMA가있는 경우 각 바이트에서 인터럽트하는 대신 사용하십시오. 일반적으로 I2C와 달리 ADC를 DMA에 배치하는 것이 더 쉽지만 칩마다 구현 방식이 다릅니다. DMA와의 I2C 교환을 깔끔하게 차단할 수있는 방법이 있다면 놀라지 않을 것입니다. DMA를 사용하면 인터럽트 수를 줄이고 프로세서 코어가 모든 단일 데이터 블록을 처리하지 않아도됩니다.

  • 데이터 손상이 발생하는 특정 인스턴스와 데이터 손상이 발생하는 메커니즘을 식별하십시오. 이 작업은 훨씬 어렵지만 최신 오실로스코프 / 논리 분석기를 창의적으로 사용하면 일부 문제를 볼 수 있습니다. 특히 문제가 메모리가 아닌 타이밍과 관련이 있는지 확인하십시오 (끔찍한 코드와 자유 컴파일러의 조합으로 가능합니다)

편집 : 질문에 대한 귀하의 의견 에서이 문제의 인스턴스에 관한 특정 참고 사항 :

  • ADC를 읽는 데 80 % CPU를 사용하는 것은 일반적으로 가치가 없습니다. 데이터를 수집하거나 저장할 수없는 경우 데이터 수집은 쓸모가 없습니다.
  • 아무리 많은 양의 데이터를 (유용하게) 수집하더라도 ADC 인터럽트는 데이터를 잃을 정도로 오랫동안 I2C 주변 장치를 완전히 억제 할 수있을 정도로 길지 않아야합니다. I2C는 최대 100 / 400KHz에서 실행됩니다. I2C의 클럭 지터보다 더 심각한 것으로 보일 정도로 충분히 오랫동안 인터럽트하려면 정말로 긴 인터럽트가 필요합니다.

감사. 우리 시스템에는 이러한 유형의 복잡하고 긴 ISR이 필요합니다. 그것은 긴 이야기입니다. 그럼에도 불구하고 I2C는이 인터럽트로드에서도 유지되어야하며 그렇지 않습니다. 하드웨어에 문제가있는 것 같습니다. 업데이트를 참조하십시오.
Ktc

내 경험상 그 가치가 매우 높은 ISR을 요구하는 대부분의 유스 케이스는 실제로 RTOS가 필요한 케이스입니다. 그리고 네, 최신 편집마다 하드웨어 문제처럼 보입니다. 로직 애널라이저가 있던 라인에 작은 커패시터를 넣으면 괜찮을 것입니다. 그러나 이것이 왜 필요한지는 대답하기가 다소 어렵습니다. I2C 풀업 저항 (버스 커패시턴스에 비해 너무 낮을 수 있음)을 확인하고 사용중인 I2C 버퍼 / 리피터의 데이터 시트를 확인합니다.
Chintalagiri Shashank

0

주어진 시스템에서 클럭과 데이터 버스에 노이즈가 유입 될 수 있습니다. 로직 애널라이저가 문제를 제거한다는 사실이 이것을 보여줍니다. 실용적이고 빠른 구현을 위해서는 관찰 한 신호를 따르십시오. 비슷한 관찰을 기반으로 400kbits / sec 구현의 i2c 버스에서 12pf와 병렬로 연결된 2M을 클록 및 데이터 포인트에서 접지로 연결하여 문제가 해결 된 것을 발견했습니다. 특정 i2c 통신에 필요한 관심 대역 밖의 노이즈를 제거 / 필터링합니다. 시도하고 조언하십시오.

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