DSP등을 사용하면서 UART데이터를 보내려고 할 때, 이를 위한 전용의 함수를 만들어서 사용하곤 한다.
예를들면
typedef volatile struct SCI_REGS RSCI, *PRSCI;
void sci_xmit(const PRSCI pChannel, const unsigned char b);
void ArrayTransmit(const PRSCI pChannel, const unsigned char* Array, const unsigned int length);
void sci_xmit(const PRSCI pChannel, const unsigned char b){
while(pChannel->SCICTL2.bit.TXEMPTY == 0){}
pChannel->SCITXBUF.all=b;
}
void ArrayTransmit(const PRSCI pChannel, const unsigned char* Array, const unsigned int length){
unsigned int i=0;
for(i=0; i<length;i++){
while(pChannel->SCICTL2.bit.TXEMPTY == 0){}
pChannel->SCITXBUF.all=Array[i];
}
}
위 코드는 내가 DSP 28335나 28377 에서 시리얼데이터를 보낼 때 사용하는 함수이다.
위와 같이 사용하면 SCI관련 레지스터의 포인터를 보내는 것으로 어떤 SCI 채널에서든 사용할 수 있다.
그런데 사용 도중 문제가 발생하였다. A와 B센서를 사용하고 이와 통신할 때, 처음에는 함수가 잘 동작하였었는데 프로젝트의 규모가 커지고 코드가 많아짐에 따라 B센서에 데이터가 잘 보내지지 않는 것이다.
당시 전송을 위해서 아래와 같은 코드를 사용했다.
BOOL Write(const PRSCI pChannel, const BYTE* data, const DWORD dataLength){
if(!data || dataLength <=0)
return FALSE;
if(pChannel == 0)
return FALSE;
const DWORD EOI = dataLength/2;
BYTE TXData = 0;
DWORD i = 0;
for(i=0; i<EOI; i++){
TXData = data[i];
sci_xmit(pChannel, (TXData&0x00ff));
sci_xmit(pChannel, ((TXData&0xff00)>>8));
}
return TRUE;
}
DSP에서는 자료형의 최소단위가 2byte였는데, 문자열을 보내는것이 아니라 byte데이터를 보내야 했기 때문에 2byte데이터에 대해서 위처럼 bit shift를 활용해야 했었다. 데이터가 정상적으로 센서에 전송이 되면 센서는 응답을 보내는데 당시 DSP의 수신기능에는 전혀 문제가 없었다.
이것저것 시험해본 결과 깨닫게 된 것은 데이터 전송에 있어서 함수호출방식을 사용했다는 것에 문제가 있다는 것이다. 저 sci_xmit함수를 한번 호출하는데 적어도 다음과 같은 과정을 거칠것이다.
1. 함수의 주소를 참조하여 함수를 호출한다.
2. 두개의 인수 pChannel과 데이터를 넣어준다.
3. 호출된 함수 sci_xmit에서 두 인수가 복사된다.
4. while에서 전송용 버퍼가 비워질 때 까지 기다린다.
5. 전송하고 return한다.
프로젝트 규모가 작았을 때는 센서 B에서 문제없이 응답이 돌아왔었는데 프로젝트가 커지더니 응답이 돌아오지 않았다. 디버깅모드에서 전송 행위는 정상적으로 이루어졌다고 보였었다.
여러가지 방법을 시도하다가 sci_xmit의 while문(버퍼가 비워질 때 까지 대기하기 위한)을 제거해 보았다. 그랬더니 센서 B로부터 응답이 돌아왔다. 정상적으로 동작한 것이다.
나로써는 프로젝트의 규모가 커졌다고는 하나 고작 16byte데이터를 보내는데 함수호출방식을 사용한다고 DSP 내부적으로 어떤 문제가 발생할 수 있는지 모르겠다.
센서 B와 통신이 정상화 되었더니 이번에는 센서 A로부터 응답이 없다.
센서 A는 B와는 전혀 다른 센서였는데, 명령 커맨드를 보내주면 이후에 요청한 정보를 계속 전송해 준다. 따라서 명령 커맨드가 제대로 전송되지 않았다고 보았다.
실제로 제거했던 while문을 다시 넣었더니 동작하는 것이다. 이 점에 있어서는 DSP의 문제라기 보다는 센서 A가 데이터를 수신할 때 어느정도의 텀이 필요한것이 아닌가 생각되었다.
결국 센서 A와 센서 B에 대하여 다른 전송 함수를 사용할 수 밖에 없었다.
--------------------------------------------------------------------------------------
센서 B와 관련해서는 함수호출방식을 아예 배제하기 위해서 Write 함수의 빨간 코드 부분을 아래와 같이 바꾸었다.
for(i=0; i<EOI; i++){
TXData = data[i];
pChannel->SCITXBUF.all=(TXData&0x00ff);
pChannel->SCITXBUF.all=((TXData&0xff00)>>8);
}
만약 C++로 개발중이었다면 가볍게 인라인 함수로 함수화 했을텐데 아쉬운 부분이다.