티스토리 뷰

반응형

앞선 글에서 전력관리를 위해 System On Sleep과 System Off Sleep에 들어가는 방법을 설명하고 어떠한 차이가 있는지 설명하였는데요, 다만 System Off Sleep에 들어간 뒤 Wakeup 될때 Reset과 같은 형태로 되다보니 Sleep 후 깨어났을때 리셋인지, SW Reset 요청에 의해서인지 구분하기가 어렵습니다.

https://hero-space.tistory.com/85

 

전력관리를 위한 System Off/On 슬립 기능 구현

오늘은 디바이스 개발 할 때 중요한 분야인 파워세이브 관련한 내용에 대해서 이야기하도록 하겠습니다. 양산 과정에서 가장 중요한 부분이 이러한 전력관리 부분인데요. 특히 배터리로 동작하

hero-space.tistory.com

이를 극복하기 위해 nRF SDK 중 Retained Register라 불리는 것이 있는데 어떤 것이고 어떻게 사용할 수 있는지 살펴보도록 하겠습니다.

위 표를 보면 오른쪽 두번에 표시되어 있는 Rtained Register는 watchdog, pin brownout, power on reset 과 같은 조금 강력한 형태의 Reset에서는 유지되지 않으나, Soft reset이나 wakeup from system OFF 의 reset의 경우는 유지 할 수 있습니다. 이를 활용해서 SW Reset 할 경우와 System Off Sleep 후 Wakeup 할때를 구분할 수 있도록 해보겠습니다.

void get_reset_status(uint32_t *p_status)
{
    uint32_t status = 0;

    if (nrf_sdh_is_enabled() == true)
    {
      sd_power_gpregret_get(1, &status);
      *p_status = status;
    }
    else
    {
      *p_status = NRF_POWER->GPREGRET2;
    }
}

void set_reset_status(uint32_t status)
{
  if(nrf_sdh_is_enabled() == true)
  {
      sd_power_gpregret_set(1, status);
  }
  else
  {      
      NRF_POWER->GPREGRET2 = status;
  }
}

reset에 대한 status를 위와 같이 구현해보았습니다. GPREGRET2 레지스터에 직접 저장할 수도 있지만 softdevice를 사용하는 경우 sd_power_gpregret_get 과 sd_power_gpregret_set 을 사용하여 활용할 수 있습니다.

void init_reset_status(void)
{
    uint32_t mode = 0;

    if (nrf_sdh_is_enabled() == true)
    {
      sd_power_gpregret_get(1, &mode);
      g_reset_status = mode;
      sd_power_gpregret_clr(1, 0xffffffff);
    }
    else
    {
      g_reset_status = NRF_POWER->GPREGRET2;
      NRF_POWER->GPREGRET2 = 0;
    }
}

부팅 시 init_reset_status를 g_reset_status에 저장하도록 해서 이후 자신이 구현한 플로우에서 활용할 수 있도록 합니다. 마찬 가지로 softdevice 를 사용하는 경우 sd_gpregret_get을 통해서 저장했던 값을 읽어오게 하고 있습니다. 제가 활용할 부분은 지금 메인 함수의 시작이 슬립 후 웨이크업에 의한 것인지, 단순히 SW Reset을 통해서 인지를 확인해서 db 값을 어떻게 접근할지 고려할 예정입니다. 차후 db를 이용하는 부분에서 어떻게 하는지 db 사용방법을 설명하면서 retained register를 활용하는 부분도 추가로 설명해보도록 하겠습니다.

반응형
댓글