Sunday, June 17, 2018

stm8 에서 trap으로 system call 구현하는 방법(1)

stm8 mcu에는 trap이라는 instruction이 있다.
이 command는 ARM에서 svc instruction과 (아마도) 같은 목적을 위해 제공되는 것이다.

그 목적은 main task 상에서 단순 function call이 아닌 방법으로 (즉, function의 위치를 몰라도..) 특정 기능을 수행하는 것이다.

(Process space를 보호해주는 OS상에서의 svc는 좀 더 다른 목적(?)이 있지만, 이 글은 MMU가 없는 mcu level에 국한한다.)


아래는 관련 code이다.
======================
#include
#include

#define BIT(x)  (1<<(x))
#define ON      (0x11)
#define OFF     (0x22)

//INTERRUPT_HANDLER_TRAP(TRAP_IRQHandler)
#pragma vector = 1
 __interrupt void (trap_handler) (void)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
  char param = 0x11;

  asm("ld a, xl");
  
  switch(param)
  {
  case ON:
    PB_ODR |= BIT(5);
    break;
  case OFF:
    PB_ODR &= ~BIT(5);
    break;
  default:
    break;
  }
}

void delay(unsigned int n)
{
    while (n-- > 0);
}

void sys_call(char id)
{
  asm("ld xl, a");
  __trap();
}

//main entry point
int main( void )
{
  PB_ODR = 0; //Turn off all pins
  PB_DDR = BIT(5);
  PB_CR1 = BIT(5);

//  __enable_interrupt();
  while (1)
  {
    delay(30000);
    sys_call(ON);
    delay(30000);
    sys_call(OFF);
  }
}

/**

*/
===========================

trap instruction을 사용하여 system call로 진입을 하였고,
system call에서 해야할 일을 전달하기 위해서 xl register를 이용하였다.

이 코드는 iar에서 확인되었으나, 조금 특이한 설정이 필요하다.
optimize는 off(none)으로 해야 정상동작이 되는 코드이다.

optimize에 의해서 필요없다고 보여지는 code들이 모두 제거되기 때문인데,
이는 C compiler가 asm으로 실행될 내용에 대해 이해하지 못하기 때문에 일어나는 일이다.

그래서,
정확한 구현을 하기 위해서는 C와 assembly의 mixing방법에 대한 표준을 알 필요가 있고, 이 부분은 (가능하다면...) 다음 글에 소개할 예정이다.
(아직 필자도 모름니다. ㅡ.ㅡ;;)


No comments: