1e41f4b71Sopenharmony_ci# RTC 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ci## Overview 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ciThe real-time clock (RTC) is a real-time clock device in the operating system. In the Hardware Driver Foundation (HDF), the RTC uses the independent service mode for API adaptation. In this mode, each device independently publishes a service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device, which increases memory usage. 7e41f4b71Sopenharmony_ci 8e41f4b71Sopenharmony_ci **Figure 1** Independent service mode 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ci  11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci## Available APIs 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci**RtcMethod**: 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci``` 19e41f4b71Sopenharmony_cistruct RtcMethod { 20e41f4b71Sopenharmony_ci int32_t (*ReadTime)(struct RtcHost *host, struct RtcTime *time); 21e41f4b71Sopenharmony_ci int32_t (*WriteTime)(struct RtcHost *host, const struct RtcTime *time); 22e41f4b71Sopenharmony_ci int32_t (*ReadAlarm)(struct RtcHost *host, enum RtcAlarmIndex alarmIndex, struct RtcTime *time); 23e41f4b71Sopenharmony_ci int32_t (*WriteAlarm)(struct RtcHost *host, enum RtcAlarmIndex alarmIndex, const struct RtcTime *time); 24e41f4b71Sopenharmony_ci int32_t (*RegisterAlarmCallback)(struct RtcHost *host, enum RtcAlarmIndex alarmIndex, RtcAlarmCallback cb); 25e41f4b71Sopenharmony_ci int32_t (*AlarmInterruptEnable)(struct RtcHost *host, enum RtcAlarmIndex alarmIndex, uint8_t enable); 26e41f4b71Sopenharmony_ci int32_t (*GetFreq)(struct RtcHost *host, uint32_t *freq); 27e41f4b71Sopenharmony_ci int32_t (*SetFreq)(struct RtcHost *host, uint32_t freq); 28e41f4b71Sopenharmony_ci int32_t (*Reset)(struct RtcHost *host); 29e41f4b71Sopenharmony_ci int32_t (*ReadReg)(struct RtcHost *host, uint8_t usrDefIndex, uint8_t *value); 30e41f4b71Sopenharmony_ci int32_t (*WriteReg)(struct RtcHost *host, uint8_t usrDefIndex, uint8_t value); 31e41f4b71Sopenharmony_ci}; 32e41f4b71Sopenharmony_ci``` 33e41f4b71Sopenharmony_ci 34e41f4b71Sopenharmony_ci **Table 1** Description of the callback functions in RtcMethod 35e41f4b71Sopenharmony_ci 36e41f4b71Sopenharmony_ci| Function| Input Parameter| Output Parameter| Return Value| Description| 37e41f4b71Sopenharmony_ci| -------- | -------- | -------- | -------- | -------- | 38e41f4b71Sopenharmony_ci| ReadTime | **host**: structure pointer to the RTC controller at the core layer.| **time**: structure pointer to the time read.| HDF_STATUS| Reads the RTC time.| 39e41f4b71Sopenharmony_ci| WriteTime | **host**: structure pointer to the RTC controller at the core layer.<br>**time**: structure pointer to the time to write.| –| HDF_STATUS| Writes the RTC time (including the year, month, day, day of week, hour, minute, second, and millisecond).| 40e41f4b71Sopenharmony_ci| ReadAlarm | **host**: structure pointer to the RTC controller at the core layer.<br>**alarmIndex**: RTC alarm index, which is an enumerated value.| **time**: structure pointer to the time read.| HDF_STATUS| Reads the RTC alarm time.| 41e41f4b71Sopenharmony_ci| WriteAlarm | **host**: structure pointer to the RTC controller at the core layer.<br>**alarmIndex**: RTC alarm index, which is an enumerated value.<br>**time**: structure pointer to the time to write.| –| HDF_STATUS| Writes the RTC alarm time.| 42e41f4b71Sopenharmony_ci| RegisterAlarmCallback | **host**: structure pointer to the RTC controller at the core layer.<br>**alarmIndex**: RTC alarm index, which is an enumerated value.<br>**cb**: pointer to the callback to register.| –| HDF_STATUS| Registers a callback to be invoked when an alarm is not generated at the specified time.| 43e41f4b71Sopenharmony_ci| AlarmInterruptEnable | **host**: structure pointer to the RTC controller at the core layer.<br>**alarmIndex**: RTC alarm index, which is an enumerated value.<br>**enable**: whether to enable interrupts for an RTC alarm. | –| HDF_STATUS| Enables or disables interrupts for an RTC alarm.| 44e41f4b71Sopenharmony_ci| GetFreq | **host**: structure pointer to the RTC controller at the core layer.| **freq**: pointer to the frequency obtained, which is of the uint32_t type.| HDF_STATUS| Obtains the frequency of the external crystal oscillator connected to the RTC driver.| 45e41f4b71Sopenharmony_ci| SetFreq | **host**: structure pointer to the RTC controller at the core layer.<br>**freq**: frequency to set, which is of the uint32_t type.| –| HDF_STATUS| Sets the frequency of the external crystal oscillator connected to the RTC driver.| 46e41f4b71Sopenharmony_ci| Reset | **host**: structure pointer to the RTC controller at the core layer.| –| HDF_STATUS| Resets the RTC.| 47e41f4b71Sopenharmony_ci| ReadReg | **host**: structure pointer to the RTC controller at the core layer.<br>**usrDefIndex**: index of a custom register.| **value**: pointer to the register value obtained, which is of the uint8_t type.| HDF_STATUS| Reads a custom RTC register. A register index corresponds to one byte of the register value.| 48e41f4b71Sopenharmony_ci| WriteReg | **host**: structure pointer to the RTC controller at the core layer.<br>**usrDefIndex**: index of a custom register.<br>**value**: register value to write, which is of the uint8_t type.| –| HDF_STATUS| Writes a custom RTC register. A register index corresponds to one byte of the register value.| 49e41f4b71Sopenharmony_ci 50e41f4b71Sopenharmony_ci 51e41f4b71Sopenharmony_ci## How to Develop 52e41f4b71Sopenharmony_ci 53e41f4b71Sopenharmony_ciThe RTC module adaptation involves the following steps: 54e41f4b71Sopenharmony_ci 55e41f4b71Sopenharmony_ci1. Instantiate the driver entry. 56e41f4b71Sopenharmony_ci - Instantiate the **HdfDriverEntry** structure. 57e41f4b71Sopenharmony_ci - Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF. 58e41f4b71Sopenharmony_ci 59e41f4b71Sopenharmony_ci2. Configure attribute files. 60e41f4b71Sopenharmony_ci - Add the **deviceNode** information to the **device_info.hcs** file. 61e41f4b71Sopenharmony_ci - (Optional) Add the **rtc_config.hcs** file. 62e41f4b71Sopenharmony_ci 63e41f4b71Sopenharmony_ci3. Instantiate the RTC controller object. 64e41f4b71Sopenharmony_ci - Initialize **RtcHost**. 65e41f4b71Sopenharmony_ci - Instantiate **RtcMethod** in the **RtcHost** object. 66e41f4b71Sopenharmony_ci >  **NOTE**<br> 67e41f4b71Sopenharmony_ci > For details about the functions in **RtcMethod**, see [Available APIs](#available-apis). 68e41f4b71Sopenharmony_ci 69e41f4b71Sopenharmony_ci4. Debug the driver. 70e41f4b71Sopenharmony_ci 71e41f4b71Sopenharmony_ci (Optional) For new drivers, verify the basic functions, such as the RTC status control and response to interrupts. 72e41f4b71Sopenharmony_ci 73e41f4b71Sopenharmony_ci 74e41f4b71Sopenharmony_ci## Development Example 75e41f4b71Sopenharmony_ci 76e41f4b71Sopenharmony_ciThe following uses **rtc_hi35xx.c** as an example to present the information required for implementing device functions. 77e41f4b71Sopenharmony_ci 78e41f4b71Sopenharmony_ci1. Instantiate the driver entry. 79e41f4b71Sopenharmony_ci 80e41f4b71Sopenharmony_ci The driver entry must be a global variable of the **HdfDriverEntry** type (defined in **hdf_device_desc.h**), and the value of **moduleName** must be the same as that in **device_info.hcs**. 81e41f4b71Sopenharmony_ci 82e41f4b71Sopenharmony_ci In the HDF, the start address of each **HdfDriverEntry** object of all loaded drivers is collected to form a segment address space similar to an array for the upper layer to invoke. 83e41f4b71Sopenharmony_ci 84e41f4b71Sopenharmony_ci Generally, the HDF calls the **Bind** function and then the **Init** function to load a driver. If **Init** fails to be called, the HDF calls **Release** to release driver resources and exit. 85e41f4b71Sopenharmony_ci 86e41f4b71Sopenharmony_ci RTC driver entry example: 87e41f4b71Sopenharmony_ci 88e41f4b71Sopenharmony_ci ``` 89e41f4b71Sopenharmony_ci struct HdfDriverEntry g_rtcDriverEntry = { 90e41f4b71Sopenharmony_ci .moduleVersion = 1, 91e41f4b71Sopenharmony_ci .Bind = HiRtcBind, // See the Bind function. 92e41f4b71Sopenharmony_ci .Init = HiRtcInit, // See the Init function. 93e41f4b71Sopenharmony_ci .Release = HiRtcRelease, //See the Release function. 94e41f4b71Sopenharmony_ci .moduleName = "HDF_PLATFORM_RTC", // (Mandatory) The value must be the same as that in the .hcs file. 95e41f4b71Sopenharmony_ci }; 96e41f4b71Sopenharmony_ci // Call HDF_INIT to register the driver entry with the HDF. 97e41f4b71Sopenharmony_ci HDF_INIT(g_rtcDriverEntry); 98e41f4b71Sopenharmony_ci ``` 99e41f4b71Sopenharmony_ci 100e41f4b71Sopenharmony_ci2. Add the **deviceNode** information to the **device_info.hcs** file and configure the device attributes in the **rtc_config.hcs** file. 101e41f4b71Sopenharmony_ci 102e41f4b71Sopenharmony_ci The **deviceNode** information is related to registration of the driver entry. The device attribute values are closely related to the default values or value ranges of the **RtcHost** members at the core layer. 103e41f4b71Sopenharmony_ci 104e41f4b71Sopenharmony_ci In this example, there is only one RTC controller. If there are multiple RTC controllers, you need to add the **deviceNode** information to the **device_info** file and add the corresponding device attributes to the **rtc_config** file for each controller. 105e41f4b71Sopenharmony_ci 106e41f4b71Sopenharmony_ci - **device_info.hcs** configuration example 107e41f4b71Sopenharmony_ci 108e41f4b71Sopenharmony_ci 109e41f4b71Sopenharmony_ci ``` 110e41f4b71Sopenharmony_ci root { 111e41f4b71Sopenharmony_ci device_info { 112e41f4b71Sopenharmony_ci platform :: host { 113e41f4b71Sopenharmony_ci device_rtc :: device { 114e41f4b71Sopenharmony_ci device0 :: deviceNode { 115e41f4b71Sopenharmony_ci policy = 1; // The driver publishes services for kernel-mode processes only. 116e41f4b71Sopenharmony_ci priority = 30; // A smaller value indicates a higher priority. 117e41f4b71Sopenharmony_ci permission = 0644; // Permission for the driver to create a device node 118e41f4b71Sopenharmony_ci moduleName = "HDF_PLATFORM_RTC"; // (Mandatory) Driver name, which must be the same as moduleName in the driver entry. 119e41f4b71Sopenharmony_ci serviceName = "HDF_PLATFORM_RTC"; // (Mandatory) Unique name of the service published by the driver. 120e41f4b71Sopenharmony_ci deviceMatchAttr = "hisilicon_hi35xx_rtc";// The value must be the same as that of match_attr in the .hcs file. 121e41f4b71Sopenharmony_ci } 122e41f4b71Sopenharmony_ci } 123e41f4b71Sopenharmony_ci } 124e41f4b71Sopenharmony_ci } 125e41f4b71Sopenharmony_ci } 126e41f4b71Sopenharmony_ci ``` 127e41f4b71Sopenharmony_ci 128e41f4b71Sopenharmony_ci - **rtc_config.hcs** configuration example 129e41f4b71Sopenharmony_ci 130e41f4b71Sopenharmony_ci 131e41f4b71Sopenharmony_ci ``` 132e41f4b71Sopenharmony_ci root { 133e41f4b71Sopenharmony_ci platform { 134e41f4b71Sopenharmony_ci rtc_config { 135e41f4b71Sopenharmony_ci controller_0x12080000 { 136e41f4b71Sopenharmony_ci match_attr = "hisilicon_hi35xx_rtc";// (Mandatory) The value must be the same as that of deviceMatchAttr in device_info.hcs. 137e41f4b71Sopenharmony_ci rtcSpiBaseAddr = 0x12080000; // Used for address mapping. 138e41f4b71Sopenharmony_ci regAddrLength = 0x100; // Used for address mapping. 139e41f4b71Sopenharmony_ci irq = 37; // Interrupt number. 140e41f4b71Sopenharmony_ci supportAnaCtrl = false; 141e41f4b71Sopenharmony_ci supportLock = false; 142e41f4b71Sopenharmony_ci anaCtrlAddr = 0xff; 143e41f4b71Sopenharmony_ci lock0Addr = 0xff; 144e41f4b71Sopenharmony_ci lock1Addr = 0xff; 145e41f4b71Sopenharmony_ci lock2Addr = 0xff; 146e41f4b71Sopenharmony_ci lock3Addr = 0xff; 147e41f4b71Sopenharmony_ci } 148e41f4b71Sopenharmony_ci } 149e41f4b71Sopenharmony_ci } 150e41f4b71Sopenharmony_ci } 151e41f4b71Sopenharmony_ci ``` 152e41f4b71Sopenharmony_ci 153e41f4b71Sopenharmony_ci3. Initialize the **RtcHost** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**) to instantiate **RtcMethod** in **RtcHost** (so that the underlying driver functions can be called). 154e41f4b71Sopenharmony_ci 155e41f4b71Sopenharmony_ci - Defining a custom structure 156e41f4b71Sopenharmony_ci 157e41f4b71Sopenharmony_ci To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **rtc_config.hcs** file to initialize the members in the custom structure. 158e41f4b71Sopenharmony_ci 159e41f4b71Sopenharmony_ci ``` 160e41f4b71Sopenharmony_ci struct RtcConfigInfo { 161e41f4b71Sopenharmony_ci uint32_t spiBaseAddr; // Used for address mapping. 162e41f4b71Sopenharmony_ci volatile void *remapBaseAddr; // Used for address mapping. 163e41f4b71Sopenharmony_ci uint16_t regAddrLength; // Used for address mapping. 164e41f4b71Sopenharmony_ci uint8_t supportAnaCtrl; // Whether ANACTRL is supported. 165e41f4b71Sopenharmony_ci uint8_t supportLock; // Whether lock is supported. 166e41f4b71Sopenharmony_ci uint8_t irq; // Interrupt number. 167e41f4b71Sopenharmony_ci uint8_t alarmIndex; // RTC alarm index. 168e41f4b71Sopenharmony_ci uint8_t anaCtrlAddr; // ANACTRL address. 169e41f4b71Sopenharmony_ci struct RtcLockAddr lockAddr; // Lock address. 170e41f4b71Sopenharmony_ci RtcAlarmCallback cb; // Callback. 171e41f4b71Sopenharmony_ci struct OsalMutex mutex; // Mutex. 172e41f4b71Sopenharmony_ci }; 173e41f4b71Sopenharmony_ci 174e41f4b71Sopenharmony_ci // RtcHost is the controller structure at the core layer. The Init function assigns values to the members of RtcHost. 175e41f4b71Sopenharmony_ci struct RtcHost { 176e41f4b71Sopenharmony_ci struct IDeviceIoService service; 177e41f4b71Sopenharmony_ci struct HdfDeviceObject *device; 178e41f4b71Sopenharmony_ci struct RtcMethod *method; 179e41f4b71Sopenharmony_ci void *data; 180e41f4b71Sopenharmony_ci }; 181e41f4b71Sopenharmony_ci ``` 182e41f4b71Sopenharmony_ci 183e41f4b71Sopenharmony_ci - Instantiating **RtcMethod** in **RtcHost** (other members are initialized by **Init**) 184e41f4b71Sopenharmony_ci 185e41f4b71Sopenharmony_ci ``` 186e41f4b71Sopenharmony_ci // Example in rtc_hi35xx.c: instantiate the hook. 187e41f4b71Sopenharmony_ci static struct RtcMethod g_method = { 188e41f4b71Sopenharmony_ci .ReadTime = HiRtcReadTime, 189e41f4b71Sopenharmony_ci .WriteTime = HiRtcWriteTime, 190e41f4b71Sopenharmony_ci .ReadAlarm = HiReadAlarm, 191e41f4b71Sopenharmony_ci .WriteAlarm = HiWriteAlarm, 192e41f4b71Sopenharmony_ci .RegisterAlarmCallback = HiRegisterAlarmCallback, 193e41f4b71Sopenharmony_ci .AlarmInterruptEnable = HiAlarmInterruptEnable, 194e41f4b71Sopenharmony_ci .GetFreq = HiGetFreq, 195e41f4b71Sopenharmony_ci .SetFreq = HiSetFreq, 196e41f4b71Sopenharmony_ci .Reset = HiReset, 197e41f4b71Sopenharmony_ci .ReadReg = HiReadReg, 198e41f4b71Sopenharmony_ci .WriteReg = HiWriteReg, 199e41f4b71Sopenharmony_ci }; 200e41f4b71Sopenharmony_ci ``` 201e41f4b71Sopenharmony_ci 202e41f4b71Sopenharmony_ci - **Bind** function 203e41f4b71Sopenharmony_ci 204e41f4b71Sopenharmony_ci **Input parameter**: 205e41f4b71Sopenharmony_ci 206e41f4b71Sopenharmony_ci **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information. 207e41f4b71Sopenharmony_ci 208e41f4b71Sopenharmony_ci **Return value**: 209e41f4b71Sopenharmony_ci 210e41f4b71Sopenharmony_ci **HDF_STATUS** 211e41f4b71Sopenharmony_ci 212e41f4b71Sopenharmony_ci The table below describes some status. For more information, see **HDF_STATUS** in the **/drivers/framework/include/utils/hdf_base.h** file. 213e41f4b71Sopenharmony_ci 214e41f4b71Sopenharmony_ci **Table 2** Description of HDF_STATUS 215e41f4b71Sopenharmony_ci 216e41f4b71Sopenharmony_ci | Status | Description | 217e41f4b71Sopenharmony_ci | ---------------------- | -------------------------- | 218e41f4b71Sopenharmony_ci | HDF_ERR_INVALID_OBJECT | Invalid controller object. | 219e41f4b71Sopenharmony_ci | HDF_ERR_MALLOC_FAIL | Failed to allocate memory. | 220e41f4b71Sopenharmony_ci | HDF_ERR_INVALID_PARAM | Invalid parameter. | 221e41f4b71Sopenharmony_ci | HDF_ERR_IO | I/O error. | 222e41f4b71Sopenharmony_ci | HDF_SUCCESS | Initialization successful. | 223e41f4b71Sopenharmony_ci | HDF_FAILURE | Initialization failed. | 224e41f4b71Sopenharmony_ci 225e41f4b71Sopenharmony_ci **Function description**: 226e41f4b71Sopenharmony_ci 227e41f4b71Sopenharmony_ci Binds the **HdfDeviceObject** object and **RtcHost**. 228e41f4b71Sopenharmony_ci 229e41f4b71Sopenharmony_ci ``` 230e41f4b71Sopenharmony_ci static int32_t HiRtcBind(struct HdfDeviceObject *device) 231e41f4b71Sopenharmony_ci { 232e41f4b71Sopenharmony_ci struct RtcHost *host = NULL; 233e41f4b71Sopenharmony_ci host = RtcHostCreate(device); // Allocate memory and attach the device host with the device. 234e41f4b71Sopenharmony_ci // Prerequisite for conversion between HdfDeviceObject and RtcHost. 235e41f4b71Sopenharmony_ci ... 236e41f4b71Sopenharmony_ci device->service = &host->service; // Prerequisite for conversion between HdfDeviceObject and RtcHost. 237e41f4b71Sopenharmony_ci // It helps implement a global host by calling RtcHostFromDevice. 238e41f4b71Sopenharmony_ci return HDF_SUCCESS; 239e41f4b71Sopenharmony_ci } 240e41f4b71Sopenharmony_ci ``` 241e41f4b71Sopenharmony_ci 242e41f4b71Sopenharmony_ci - **Init** function 243e41f4b71Sopenharmony_ci 244e41f4b71Sopenharmony_ci **Input parameter**: 245e41f4b71Sopenharmony_ci 246e41f4b71Sopenharmony_ci **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information. 247e41f4b71Sopenharmony_ci 248e41f4b71Sopenharmony_ci **Return value**: 249e41f4b71Sopenharmony_ci 250e41f4b71Sopenharmony_ci **HDF_STATUS** 251e41f4b71Sopenharmony_ci 252e41f4b71Sopenharmony_ci **Function description**: 253e41f4b71Sopenharmony_ci 254e41f4b71Sopenharmony_ci Initializes the custom structure object and **RtcHost**. 255e41f4b71Sopenharmony_ci 256e41f4b71Sopenharmony_ci ``` 257e41f4b71Sopenharmony_ci static int32_t HiRtcInit(struct HdfDeviceObject *device) 258e41f4b71Sopenharmony_ci { 259e41f4b71Sopenharmony_ci struct RtcHost *host = NULL; 260e41f4b71Sopenharmony_ci struct RtcConfigInfo *rtcInfo = NULL; 261e41f4b71Sopenharmony_ci ... 262e41f4b71Sopenharmony_ci host = RtcHostFromDevice(device);// Forcibly convert HdfDeviceObject to RtcHost. 263e41f4b71Sopenharmony_ci rtcInfo = OsalMemCalloc(sizeof(*rtcInfo)); 264e41f4b71Sopenharmony_ci ... 265e41f4b71Sopenharmony_ci // HiRtcConfigData reads attributes from the device configuration tree and fills in supportAnaCtrl, supportLock, spiBaseAddr, regAddrLength and irq of RTCInfo. 266e41f4b71Sopenharmony_ci // Provide parameters for HiRtcSwInit and HiRtcSwInit. When HiRtcSwInit and HiRtcSwInit fail to be executed internally, Release() can be called to release memory. 267e41f4b71Sopenharmony_ci if (HiRtcConfigData(rtcInfo, device->property) != 0) { 268e41f4b71Sopenharmony_ci ... 269e41f4b71Sopenharmony_ci } 270e41f4b71Sopenharmony_ci if (HiRtcSwInit(rtcInfo)! = 0) {// Address mapping and interrupt registration. 271e41f4b71Sopenharmony_ci ... 272e41f4b71Sopenharmony_ci } 273e41f4b71Sopenharmony_ci if (HiRtcHwInit(rtcInfo)! = 0) {// Initialize ANACTRL and lockAddr. 274e41f4b71Sopenharmony_ci ... 275e41f4b71Sopenharmony_ci } 276e41f4b71Sopenharmony_ci 277e41f4b71Sopenharmony_ci host->method = &g_method; // Attach the RtcMethod instance. 278e41f4b71Sopenharmony_ci host->data = rtcInfo; // Prerequisites for conversion between RtcConfigInfo and RtcHost. 279e41f4b71Sopenharmony_ci HDF_LOGI("Hdf dev service:%s init success!", HdfDeviceGetServiceName(device)); 280e41f4b71Sopenharmony_ci return HDF_SUCCESS; 281e41f4b71Sopenharmony_ci } 282e41f4b71Sopenharmony_ci ``` 283e41f4b71Sopenharmony_ci 284e41f4b71Sopenharmony_ci - **Release** function 285e41f4b71Sopenharmony_ci 286e41f4b71Sopenharmony_ci **Input parameter**: 287e41f4b71Sopenharmony_ci 288e41f4b71Sopenharmony_ci **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information. 289e41f4b71Sopenharmony_ci 290e41f4b71Sopenharmony_ci **Return value**: 291e41f4b71Sopenharmony_ci 292e41f4b71Sopenharmony_ci No value is returned. 293e41f4b71Sopenharmony_ci 294e41f4b71Sopenharmony_ci **Function description**: 295e41f4b71Sopenharmony_ci 296e41f4b71Sopenharmony_ci Releases the memory and deletes the controller. This function assigns values to the **Release** function in the driver entry structure. If the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources. 297e41f4b71Sopenharmony_ci 298e41f4b71Sopenharmony_ci 299e41f4b71Sopenharmony_ci >  **NOTE**<br> 300e41f4b71Sopenharmony_ci > All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** or **Bind** function has the corresponding value assignment operations. 301e41f4b71Sopenharmony_ci 302e41f4b71Sopenharmony_ci 303e41f4b71Sopenharmony_ci ``` 304e41f4b71Sopenharmony_ci static void HiRtcRelease(struct HdfDeviceObject *device) 305e41f4b71Sopenharmony_ci { 306e41f4b71Sopenharmony_ci struct RtcHost *host = NULL; 307e41f4b71Sopenharmony_ci struct RtcConfigInfo *rtcInfo = NULL; 308e41f4b71Sopenharmony_ci ... 309e41f4b71Sopenharmony_ci host = RtcHostFromDevice(device); // Forcibly convert HdfDeviceObject to RtcHost. 310e41f4b71Sopenharmony_ci rtcInfo = (struct RtcConfigInfo *)host->data;// Forcibly convert RtcHost to RtcConfigInfo. 311e41f4b71Sopenharmony_ci if (rtcInfo != NULL) { 312e41f4b71Sopenharmony_ci HiRtcSwExit(rtcInfo); 313e41f4b71Sopenharmony_ci OsalMemFree(rtcInfo); // Release RtcConfigInfo. 314e41f4b71Sopenharmony_ci host->data = NULL; 315e41f4b71Sopenharmony_ci } 316e41f4b71Sopenharmony_ci RtcHostDestroy(host); // Release RtcHost. 317e41f4b71Sopenharmony_ci } 318e41f4b71Sopenharmony_ci ``` 319