Recv인터럽트 에러

W5500을 사용중이며 초기설정은 아래와 같으며 수신인터럽트를 사용 합니다.

SIMR : 0x20 (Socket5)
SnIMR : 0x04 (Recv)

인터럽트 발생시 레지스터는 아래와 같습니다.

SIR : 0x20 (Socket5)
SnIR : 0x04(Recv)

인터럽트 발생시 데이터를 recvfrom 함수로 수신한 뒤

setSN_IR 함수로 Recv인터럽트를 클리어해주고 있습니다.

그런데 Recv루틴이 수초간 동작하다가 데이터 수신이 안되길래 레지스터값을 조회하면
SIR : 0x00
SnIR : 0x00 이고
인터럽트핀도 High 상태입니다.
레지스터값만 봤을때는 인터럽트를 발생시킬 준비가 된 걸로 보여집니다.

혹시 인터럽트모드에선 send소켓을 별도로 사용해주어야하나요?
왜 데이터 수신이 멈추는지, 현상황에서 디버깅해볼 방법은 무엇인지, 그리고 이에대한 해결책을 알려주시면 감사하겠습니다.

안녕하세요.

일단 W5500의 경우 인터럽트가 2개로 나뉘어 있습니다.

하나는 인터럽트 상태를 읽는 IR과, 소켓 인터럽트에 사용되는 SIR이 있습니다.

SIR의 경우, 데이터시트를 참조하시면 S0_INT, S1_INT 등등이 보이는 것을 확인하실 수 있습니다.

즉, 소켓 1개당 1개의 소켓 인터럽트를 사용할 수 있다는 말입니다.

그러면 W5500의 소켓 인터럽트를 사용하기 위해서는 상대방 peer로 부터 데이터를 수신하면 소켓 인터럽트가 “1” 로 설정됩니다.

근데, W5500의 소켓 인터럽트의 경우, 자동적으로 클리어 시켜주지 않습니다. 따라서 사용자가 SIR을 별도로 Clear를 해줘야 합니다.

일단 기본적으로 W5500 loopback 코드를 먼저 돌려보시고, 이를 기반으로 제작하시는 것을 추천드립니다.

W5500 loopback 코드는 아래 링크의 application / loopback 코드를 이용해서 구현해보시면 됩니다.

github.com/Wiznet/ioLibrary_Driver

보통 이렇게 레지스터 값이 00으로 세팅 되는 경우에는, 저희도 정확하게 예측하기는 어렵습니다.

따라서 위 링크의 loopback 코드를 이용하여 테스트 확인 부탁드립니다.

감사합니다.

담당자님. 이미 loopback 샘플코드로 polling함수 구현하였고,
UDP 데이터 수신이 정상적으로 이루어지는 부분 확인하고 인터럽트로 구현중입니다.

그리고 이 글은 이미 답변해주신내용들 모두 반영하여 테스트해본 후 문의한 것임을 강조드립니다.
다시한번 말씀드리자면 recvfrom 함수로 UDP데이터 수신하고 setSN_IR 함수로 클리어하는 루틴을 작성하였습니다.(이미 질문내용에 포함되어있음)

현시점에서 추가문의드릴 질문은 2가지입니다.

  1. recvfrom함수 호출과 setSN_IR함수 호출하는 코드 사이에 추가로 W5500의 레지스터값을 조작하는 루틴이 필요한지.
    (예를들어 recvfrom으로 100바이트 수신 후 W5500의 Rx버퍼에 100바이트를 지워주는 함수?)

  2. RX_RSR레지스터를 디버깅한 결과 레지스터값이 천천히 증가하다가 설정한 RX버퍼사이즈(1K)를 초과하며 오버플로우가 발생하는것으로
    보이는 증상이 관찰되었습니다. 이와 관련하여 솔루션이 있는지.

위 내용에 대하여 검토후 답변부탁드립니다.

안녕하세요 위즈네트 방보현 연구원입니다.

말씀하신데로 수신된 데이터를 버퍼에 계속 쌓여 오버플로우로 시스템이 멈추는 것 같습니다.

데이터를 리시브하는 부분의 코드를 보내주시면 도움이 될 것 같습니다.

e-mail: peter@wiznet.io

감사합니다.