Showing posts with label syscall. Show all posts
Showing posts with label syscall. Show all posts

Sunday, June 17, 2018

implement system call in stm8 via trap instruction.

There is 'trap' instruction in stm8 mcu.
This instruction has (maybe) same purpose with svc instruction in ARM.

The purpose is perform some function without awareness of the function pointer.
(Anyway, in the APU level, the svc instruction has more mission (ie. protect the process memory space), this article is only for low level mcu)


Below is the 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);
  }
}
 ===========================

the code enters system call via trap instruction.
and to pass the operation code, it uses XL register.

This code is checked in IAR, but has some special configurations.
the configuration is 'optimize off(none)'.

Because if optimizing is on, the compiler remove some code include that needed system call.

Finally,
To perfect implementation, we need to known 'C & assembly mixing'
And next time, I will introduce it if possible.

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방법에 대한 표준을 알 필요가 있고, 이 부분은 (가능하다면...) 다음 글에 소개할 예정이다.
(아직 필자도 모름니다. ㅡ.ㅡ;;)