본문 바로가기
코스웨어/13년 스마트컨트롤러

20130930 정리(RFID, context switching )

by 알 수 없는 사용자 2013. 10. 1.
728x90
반응형

__________RFID & UNIX____________________________________________________________________________

 

 RFID 리더기에 HOST명령 전송 (Protocols for Reader Control) 

 

 

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/signal.h>


#define SPEED B38400
#define SPORT "/dev/ttyS1"  //Serial Port2

unsigned short CRC16(unsigned char *, unsigned int);
void Handle_Serial_Sig(int);

volatile int iBreak = 0;

 

int main()
{


 char cBuff[255];                       // 수신용 버퍼
 int iDev = 0;                             // 장치 데스크립션
 int iRet = 0;                             // 반환값

 int iCnt;

 struct termios stOldState;         // 기존 Serial Port 상태 정보
 struct termios stNewState;        // 새로운 Serial Port 상태 정보
 struct sigaction stSigAct;         // 시그널 액션 설정

 

 unsigned char Buff[255] = {

            
         0x05, // Get Software Version
         0x00,
         0x65,
       
         
     /* 
         0x06, // Baud Rate Detection
         0x00,
         0x52,
         0x00,
   */

         
    /*  0x0D, // Set Output
         0x00,
         0x71,
         0x00,
         0x30,
         0x00,
         0x00,
         0x00,
         0x0A,
         0x00,
         0x00,
       */

      

        /*
         0x0D, // Set Output2
         0x00,
         0x71,
         0x00,
         0x3F,
         0x00,
         0x07,
         0x00,
         0x0A,
         0x00,
         0x00,
       */


  
         0xFF,
         0xFF
 

};

 iDev = open(SPORT, O_RDWR | O_NOCTTY | O_NONBLOCK);// Serial Port Open

 

 if( 0 > iDev)                       //시리얼 포트 Open Error
 {
        perror(SPORT);
        exit(-100);
 
 }
 
 //시리얼 포트 설정 전에 시그널 핸들러 등록
 
 bzero(&stSigAct, sizeof(stSigAct));
 stSigAct.sa_handler = Handle_Serial_Sig;
 sigaction(SIGIO, &stSigAct, NULL);

 //SIGIO signal 을 수신하도록 설정
 fcntl(iDev, F_SETOWN, getpid());//iDev(시리얼 포트) 소유자를 현재 프로세스로 바꿈
 // SIGIO 발생은 소유자에게 알려지기 때문에...

 // file descriptor를 비동기로 설정
 fcntl(iDev, F_SETFL, FASYNC);

 
 tcgetattr(iDev, &stOldState);  // 현재 Serial Port 상태 저장 (백업해둠) 
 
 bzero(&stNewState, sizeof(stNewState)); // 구조체 초기화
 

 stNewState.c_cflag = SPEED | CRTSCTS | CS8 | CLOCAL | CREAD | PARENB// 짝수패리티

 

 stNewState.c_iflag = IGNPAR | ICRNL ;
 stNewState.c_oflag = 0;                                 // 수신된 데이터를 그대로 출력

 //stNewState.c_lflag = ICANON;                        // Canonical 통신 기법 사용

 

 stNewState.c_lflag = 0 ;                        // Non-Canonical 통신 기법 사용 
 
 stNewState.c_cc[VMIN] = 1;                         // read시 리턴되기 위한 최소 문자 개수 지정
 stNewState.c_cc[VTIME] = 0;

 tcflush (iDev, TCIFLUSH);                            // 시리얼 포트수신 큐 초기화
 tcsetattr(iDev, TCSANOW, &stNewState);        //시리얼 포트에 새 속성 적용


 *((unsigned short *)(&Buff[Buff[0]-2])) = CRC16(Buff, Buff[0]-2);

 //원래 데이터에 체크섬 계산된값을 넣음

 

 
 write(iDev, Buff, Buff[0]); // 패킷전송
 

 read(iDev, Buff, sizeof(Buff)); //명령전송후 리턴되는 값 수신


 Buff[0] = 13;

 
 for(iCnt = 0; iCnt < t; ++iCnt)
 {
      printf("%02X\n", Buff[iCnt]); 
 }
 

ucTemp = Buff[4];
 Buff[4] = Buff[5];
 Buff[5] = ucTemp; // Big endian이라서 스왑해줌 
 
 printf("SW-REV  : %d\n", *((unsigned short *)(&Buff[4])) );
 printf("D-REV  : %d\n", Buff[6] );
 printf("HW-TYPE : %d\n", Buff[7] );
 

printf("SW-TYPE : ");
 switch( *((unsigned short *)(&Buff[8])) )
 {
 

 case 30:
   printf("ID ISC.M01\n");
   break;

 

 case 31:
   printf("ID ISC.M02\n");
   break;

 

 case 71:
   printf("ID ISC.PRH100.U (USB-Version)\n");
   break;

 

 case 72:
   printf("ID ISC.PRH100\n");
   break;

 

 case 73:
   printf("ID ISC.MR100.U (USB-Version)\n");
   break;

 

 case 74:
   printf("ID ISC.MR100 / .PR100\n");
   break;

 

 case 75:
   printf("ID ISC.MR200-A / -E\n");
   break;

 

 case 40:
   printf("ID ISC.LR100\n");
   break;

 

 case 41:
   printf("ID ISC.LR200\n");
   break;

 

 case 91:
   printf("ID ISC.LRU1000\n");
   break;

 

 case 80:
   printf("ID CPR.M0\n");
   break;

 

 case 81: 
   printf("ID CPR.02\n");
   break;

 

 case 84:
   printf("ID CPR.M03 (586/#)\n");
   break;

 

 default:
   printf("unknown\n");
    

}
 


 ucTemp = Buff[9];
 Buff[9] = Buff[10];
 Buff[10] = ucTemp; // Big endian이라서 스왑해줌 
 
 printf("TR-TYPE : ");

 if( 0 != ((*((unsigned short *)(&Buff[9]))) & 0x0001) )
 {
      printf("[I-Code 1] ");
 }
 if( 0 != ((*((unsigned short *)(&Buff[9]))) & 0x0002) )
 {
      printf("[Tag-it HF] ");
 }
 if( 0 != ((*((unsigned short *)(&Buff[9]))) & 0x0008) )
 {
      printf("[ISO 15693] ");
 }
 if( 0 != ((*((unsigned short *)(&Buff[9]))) & 0x0040) )
 {
      printf("[I-Code EPC] ");
 }
 if( 0 != ((*((unsigned short *)(&Buff[9]))) & 0x0080) )
 {
      printf("[I-Code UID] ");
 }
  putchar('\n');

 
 tcsetattr(iDev, TCSANOW, &stOldState); // 시리얼 포트의 원래 속성 복귀
 close(iDev); // 시리얼 포트 닫음

 
 return 0;

}

 

void Handle_Serial_Sig(int Arg)
{
      printf("Receive SIGIO Signal\n");
      iBreak = 1;
}

 

#define  CRC_POLYNOM    0x8408
#define  CRC_PRESET       0xFFFF

 

unsigned short CRC16(unsigned char *DATA, unsigned int cnt)

{

 unsigned short crc = CRC_PRESET;
 unsigned int i;
 unsigned int j;
 
 /* cnt = number of protocol bytes without CRC */
 for (i = 0; i < cnt; i++)     
 {

  crc ^= DATA[i];
  for (j = 0; j < 8; j++)
  {
       if (crc & 0x0001)    
       crc = (crc >> 1) ^ CRC_POLYNOM;
       else
       crc = (crc >> 1);
  }

 }
 return crc;

}

 

                                   <Get Software Version>

SW-REV   : Revision status of the firmware.
D-REV     : Revision status of the development firmware. D-REV is set to ‘0’ in customized firmware revisions.
HW-Type  : Displays options which are supported by the Reader Hardware
SW-TYPE : Displays the type / model of the Reader

             

 

 

 

 

 

 

☞ control byte [0x71] Set Output는 리더기의 LED와 비프음의 출력을 제어함

 

 

 

 

OS는 LED와 부저의 동작모드를 설정함

    b00 : 변화없음

    b01 : ON

    b10 : OFF

    b11 : FLASH(깜빡임,켜졌다 꺼졌다를 반복)

 

 

 

 

OSF(Out State Flash)는 OS에서 FLASH로 설정된것의 동작 주파수를 설정함 

    b00 : 8Hz(1초에 8번)

    b01 : 4Hz(1초에 4번)

    b10 : 2Hz(1초에 2번)

    b11 : 1Hz(1초에 1번)

 

 

 

OS-Time는 LED와 Beeper의 동작시간을 설정함

 0x0001       =>       1 x 100ms   

    .

    .

    .

 0xFFFE      =>       65534 x 100ms  (1:48:13h) 

 0xFFFF      =>       계속 동작 

              

 

 set Output 패킷 예.

    /*  0x0D, // beeper만 Flash 형태로 동작
         0x00,
         0x71,
         0x00,
         0x30,
         0x00,
         0x00,
         0x00,
         0x0A,
         0x00,
         0x00,
       */

      

        /*
         0x0D, // 두 LED와 Beeper가 모두 Flash 형태, 다른 속도로 동작
         0x00,
         0x71,
         0x00,
         0x3F,
         0x00,
         0x07,
         0x00,
         0x0A,
         0x00,
         0x00,
       */


  
         0xFF,
         0xFF

 

 

_________________________________________________________________________________________________

 

 

 

 

 

 

 

 

 

 

 

_____ASM & context switching_____________________________________________________

 

 실행파일의 code섹션, data 섹션 메모리에 적재하기

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<CM 프로그램>

 

<MY 프로그램>

☆ 두 프로그램이 LOAD 한 섹션값이 같음을 알수 있음

 

 

 

------------------------------------------------------------------------------------------------------------

 

 

 

 

 

※ 기타 함수는 생략...

 

 

※ Clear_mem()는 실행파일의 섹션을 올리고 실행하기위해 할당해 놓은 메모리 전체를 0으로 초기화하는 함수

 

 

※ go()는 새로운 context 구조체 변수(stNewReg)를 새로 하나더 만들어 EAX 멤버에 stOldReg의 주소를

   EIP 멤버에 ucpCode(할당해 놓은 코드영역)주소값을 ESP멤버에 ucpStack(할당해 놓은 스택영역)주소를

   넣고 LDST()를 호출한다.

 

    LDST()는 stNewReg에 셋팅된 값으로 레지스터 값들을 바꾸기 때문에 return address가 ucp코드 즉,

    ucpCode에 적재되어 있는 프로그램을 수행한다.

 

   ucpCode에 적재된 프로그램은 INIT(어셈블리어 소스)에 의해 컴파일 링크된 실행파일(t1.exe)이기 때문에

   t1.c의 test()를 수행한뒤 자동으로 LDST(&stOldReg)를 호출해준다.

 

   그러면 자동으로 main에 STST(&stOldReg)를 호출한 뒤의 위치로 점프되고 레지스터 상태도 바뀌게 되기

   때문에 kernel panic이 뜨지 않고 이전상태로 되돌아감.

         

 

 

 init

 

 

 

 

 

 

 

 t1.c

char flstz[] = "1111222233334444";
int sum=0x78563412;

 

test ()
{
     int i = 0x12345678;
     int j = 0x78563412;
     int k = 0x77777777;
 
     sum = 0x12345678;
     for (i = 0; i < sizeof(flstz)-1; i++)
     {
          flstz[i] = 'a';
     }
}

 

 

 

 

 

 컴파일 & 링크 방법

 

 

 

 

 

 

 

 실행결과

 

※go()를 실행하여 test()함수가 실행된뒤의 DATA영역과 STACK 영역의 값이 출력되어있다.

   위에서 적재되었을때와 값이 바뀐것을 확인할수 있음

 

 

 

 

 

 

 

 

init.asm 

monitor2.asm 

monitor_c.c 

monitor_c.exe 

t1.c 

t1.exe

_____________________________________________________________________________

 

728x90