rtc에 백업 레지스터라고 해서, software reset 걸려도 살아남는게 있다고 ai가 이야기 하길래 검색
rtc 활성화 하고나니 아래 초기화 코드가 추가되서 따라가서 보면 평범한(?) HAL_RTC_Init() 이 있고
/** * @brief RTC Initialization Function * @param None * @retval None */ static void MX_RTC_Init(void) {
/* USER CODE BEGIN RTC_Init 0 */
/* USER CODE END RTC_Init 0 */
/* USER CODE BEGIN RTC_Init 1 */
/* USER CODE END RTC_Init 1 */
/** Initialize RTC Only */ hrtc.Instance = RTC; hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND; hrtc.Init.OutPut = RTC_OUTPUTSOURCE_ALARM; if (HAL_RTC_Init(&hrtc) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN RTC_Init 2 */
/* USER CODE END RTC_Init 2 */
} |
HAL_RTC_MspInit()을 통해
stm32f1xx_hal_rtc.c
(+) To write to the RTC Backup Data registers, use the HAL_RTCEx_BKUPWrite() function. (+) To read the RTC Backup Data registers, use the HAL_RTCEx_BKUPRead() function.
/** * @brief Initializes the RTC peripheral * @param hrtc pointer to a RTC_HandleTypeDef structure that contains * the configuration information for RTC. * @retval HAL status */ HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc) { uint32_t prescaler = 0U; /* Check input parameters */ if (hrtc == NULL) { return HAL_ERROR; }
/* Check the parameters */ assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance)); assert_param(IS_RTC_CALIB_OUTPUT(hrtc->Init.OutPut)); assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv));
#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) #else if (hrtc->State == HAL_RTC_STATE_RESET) { /* Allocate lock resource and initialize it */ hrtc->Lock = HAL_UNLOCKED;
/* Initialize RTC MSP */ HAL_RTC_MspInit(hrtc); } }
/** * @brief Initializes the RTC MSP. * @param hrtc pointer to a RTC_HandleTypeDef structure that contains * the configuration information for RTC. * @retval None */ __weak void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc) { /* Prevent unused argument(s) compilation warning */ UNUSED(hrtc); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_RTC_MspInit could be implemented in the user file */ } |
백업 레지스터에 접근할수 있도록 풀어준다.
Core/Src/stm32f1xx_hal_msp.c
/** * @brief RTC MSP Initialization * This function configures the hardware resources used in this example * @param hrtc: RTC handle pointer * @retval None */ void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc) { if(hrtc->Instance==RTC) { /* USER CODE BEGIN RTC_MspInit 0 */
/* USER CODE END RTC_MspInit 0 */ HAL_PWR_EnableBkUpAccess(); /* Enable BKP CLK enable for backup registers */ __HAL_RCC_BKP_CLK_ENABLE(); /* Peripheral clock enable */ __HAL_RCC_RTC_ENABLE(); /* USER CODE BEGIN RTC_MspInit 1 */
/* USER CODE END RTC_MspInit 1 */
}
} |
CR_DBP_BB 라는 레지스터에 활성화 해주는것 코드 느낌. 무슨 레지스터인지 따라가긴 귀찮으니 패스
stm32f1xx_hal_pwr.c
/** * @brief Enables access to the backup domain (RTC registers, RTC * backup data registers ). * @note If the HSE divided by 128 is used as the RTC clock, the * Backup Domain Access should be kept enabled. * @retval None */ void HAL_PWR_EnableBkUpAccess(void) { /* Enable access to RTC and backup registers */ *(__IO uint32_t *) CR_DBP_BB = (uint32_t)ENABLE; }
/** * @brief Disables access to the backup domain (RTC registers, RTC * backup data registers). * @note If the HSE divided by 128 is used as the RTC clock, the * Backup Domain Access should be kept enabled. * @retval None */ void HAL_PWR_DisableBkUpAccess(void) { /* Disable access to RTC and backup registers */ *(__IO uint32_t *) CR_DBP_BB = (uint32_t)DISABLE; } |
아무튼 백업레지스터 접근이 허용되면
HAL_RTCEx_BKUPWrite() 를 통해 쓰고
HAL_RTCEx_BKUPRead() 를 통해 읽을 수 있다.
stm32f1xx_hal_rtc_ex.c
/** * @brief Writes a data in a specified RTC Backup data register. * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains * the configuration information for RTC. * @param BackupRegister: RTC Backup data Register number. * This parameter can be: RTC_BKP_DRx where x can be from 1 to 10 (or 42) to * specify the register (depending devices). * @param Data: Data to be written in the specified RTC Backup data register. * @retval None */ void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data) { uint32_t tmp = 0U;
/* Prevent unused argument(s) compilation warning */ UNUSED(hrtc);
/* Check the parameters */ assert_param(IS_RTC_BKP(BackupRegister));
tmp = (uint32_t)BKP_BASE; tmp += (BackupRegister * 4U);
*(__IO uint32_t *) tmp = (Data & BKP_DR1_D); }
/** * @brief Reads data from the specified RTC Backup data Register. * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains * the configuration information for RTC. * @param BackupRegister: RTC Backup data Register number. * This parameter can be: RTC_BKP_DRx where x can be from 1 to 10 (or 42) to * specify the register (depending devices). * @retval Read value */ uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister) { uint32_t backupregister = 0U; uint32_t pvalue = 0U;
/* Prevent unused argument(s) compilation warning */ UNUSED(hrtc);
/* Check the parameters */ assert_param(IS_RTC_BKP(BackupRegister));
backupregister = (uint32_t)BKP_BASE; backupregister += (BackupRegister * 4U);
pvalue = (*(__IO uint32_t *)(backupregister)) & BKP_DR1_D;
/* Read the specified register */ return pvalue; } |
F103의 경우 10개가 있나 보다. 그런데 BKP_DRn_D 마스크는 왜 전부 0xFFFF 으로 동일한걸까?
stm32f103xb.h
/******************************************************************************/ /* */ /* Backup registers */ /* */ /******************************************************************************/
/******************* Bit definition for BKP_DR1 register ********************/ #define BKP_DR1_D_Pos (0U) #define BKP_DR1_D_Msk (0xFFFFUL << BKP_DR1_D_Pos) /*!< 0x0000FFFF */ #define BKP_DR1_D BKP_DR1_D_Msk /*!< Backup data */
/******************* Bit definition for BKP_DR2 register ********************/ #define BKP_DR2_D_Pos (0U) #define BKP_DR2_D_Msk (0xFFFFUL << BKP_DR2_D_Pos) /*!< 0x0000FFFF */ #define BKP_DR2_D BKP_DR2_D_Msk /*!< Backup data */
/******************* Bit definition for BKP_DR3 register ********************/ #define BKP_DR3_D_Pos (0U) #define BKP_DR3_D_Msk (0xFFFFUL << BKP_DR3_D_Pos) /*!< 0x0000FFFF */ #define BKP_DR3_D BKP_DR3_D_Msk /*!< Backup data */
/******************* Bit definition for BKP_DR4 register ********************/ #define BKP_DR4_D_Pos (0U) #define BKP_DR4_D_Msk (0xFFFFUL << BKP_DR4_D_Pos) /*!< 0x0000FFFF */ #define BKP_DR4_D BKP_DR4_D_Msk /*!< Backup data */
/******************* Bit definition for BKP_DR5 register ********************/ #define BKP_DR5_D_Pos (0U) #define BKP_DR5_D_Msk (0xFFFFUL << BKP_DR5_D_Pos) /*!< 0x0000FFFF */ #define BKP_DR5_D BKP_DR5_D_Msk /*!< Backup data */
/******************* Bit definition for BKP_DR6 register ********************/ #define BKP_DR6_D_Pos (0U) #define BKP_DR6_D_Msk (0xFFFFUL << BKP_DR6_D_Pos) /*!< 0x0000FFFF */ #define BKP_DR6_D BKP_DR6_D_Msk /*!< Backup data */
/******************* Bit definition for BKP_DR7 register ********************/ #define BKP_DR7_D_Pos (0U) #define BKP_DR7_D_Msk (0xFFFFUL << BKP_DR7_D_Pos) /*!< 0x0000FFFF */ #define BKP_DR7_D BKP_DR7_D_Msk /*!< Backup data */
/******************* Bit definition for BKP_DR8 register ********************/ #define BKP_DR8_D_Pos (0U) #define BKP_DR8_D_Msk (0xFFFFUL << BKP_DR8_D_Pos) /*!< 0x0000FFFF */ #define BKP_DR8_D BKP_DR8_D_Msk /*!< Backup data */
/******************* Bit definition for BKP_DR9 register ********************/ #define BKP_DR9_D_Pos (0U) #define BKP_DR9_D_Msk (0xFFFFUL << BKP_DR9_D_Pos) /*!< 0x0000FFFF */ #define BKP_DR9_D BKP_DR9_D_Msk /*!< Backup data */
/******************* Bit definition for BKP_DR10 register *******************/ #define BKP_DR10_D_Pos (0U) #define BKP_DR10_D_Msk (0xFFFFUL << BKP_DR10_D_Pos) /*!< 0x0000FFFF */ #define BKP_DR10_D BKP_DR10_D_Msk /*!< Backup data */
#define RTC_BKP_NUMBER 10 |
[링크 : https://fuhehe.tistory.com/27]
1.9 Backup registers RTC_BKPxR, where x=0 to n backup registers (80 bytes), are reset when a tamper detection event occurs. These registers are powered-on by VBAT when VDD is switched off, so that they are not reset by a system reset, and their contents remain valid when the device operates in low-power mode. Note: The number “n” of backup registers depends on the product. Please refer to Table 15: Advanced RTC features. |
[링크 : https://www.st.com/resource/en/application_note/an3371-using-the-hardware-realtime-clock-rtc-in-stm32-f0-f2-f3-f4-and-l1-series-of-mcus-stmicroelectronics.pdf]
보안상 문제가 발생하면 그걸 TAMP 라는것 같은데, 아무튼 그 때는 백업 레지스터가 초기화 된다고 한다.
[링크 : https://www.st.com/resource/en/product_training/STM32MP1-Security-Tamper_TAMP.pdf]