1 /* 2 * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved. 3 * 4 * UniProton is licensed under Mulan PSL v2. 5 * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 * You may obtain a copy of Mulan PSL v2 at: 7 * http://license.coscl.org.cn/MulanPSL2 8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 11 * See the Mulan PSL v2 for more details. 12 * Create: 2009-12-22 13 * Description: 定时器模块的对外头文件。 14 */ 15 #ifndef PRT_TIMER_H 16 #define PRT_TIMER_H 17 18 #include "prt_module.h" 19 #include "prt_errno.h" 20 21 #ifdef __cplusplus 22 #if __cplusplus 23 extern "C" { 24 #endif 25 #endif 26 27 /* 28 * 定时器状态枚举值 29 */ 30 enum TimerFlag { 31 OS_TIMER_FREE = 1, /* 定时器空闲状态 */ 32 OS_TIMER_CREATED = 2, /* 定时器没有运行 */ 33 OS_TIMER_RUNNING = 4, /* 定时器正在运行 */ 34 OS_TIMER_EXPIRED = 8 /* 定时器已经超时 */ 35 }; 36 37 /* 38 * OS_timer错误码: 指针参数为空。 39 * 40 * 值: 0x02000d01 41 * 42 * 解决方案: 查看入参指针是否为空。 43 */ 44 #define OS_ERRNO_TIMER_INPUT_PTR_NULL OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x01) 45 46 /* 47 * OS_timer错误码: 定时器回调函数为空。 48 * 49 * 值: 0x02000d02 50 * 51 * 解决方案: 查看定时器回调函数是否为空。 52 */ 53 #define OS_ERRNO_TIMER_PROC_FUNC_NULL OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x02) 54 55 /* 56 * OS_timer错误码: 定时器句柄非法。 57 * 58 * 值: 0x02000d03 59 * 60 * 解决方案: 检查输入的定时器句柄是否正确。 61 */ 62 #define OS_ERRNO_TIMER_HANDLE_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x03) 63 64 /* 65 * OS_timer错误码: 定时器周期参数非法。 66 * 67 * 值: 0x02000d04 68 * 69 * 解决方案: 查看定时器周期参数是否正确。 70 */ 71 #define OS_ERRNO_TIMER_INTERVAL_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x04) 72 73 /* 74 * OS_timer错误码: 定时器工作模式参数非法。 75 * 76 * 值: 0x02000d05 77 * 78 * 解决方案: 查看定时器工作模式参数是否正确,参照工作模式配置枚举定义#enum TmrMode。 79 */ 80 #define OS_ERRNO_TIMER_MODE_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x05) 81 82 /* 83 * OS_timer错误码: 定时器类型参数非法。 84 * 85 * 值: 0x02000d06 86 * 87 * 解决方案: 查看定时器类型参数是否正确,参照类型配置枚举定义#enum TimerType。 88 */ 89 #define OS_ERRNO_TIMER_TYPE_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x06) 90 91 /* 92 * 软件定时器错误码:软件定时器组的最大定时器个数为零。 93 * 94 * 值: 0x02000d07 95 * 96 * 解决方案: 软件定时器组的最大定时器个数必须大于零。 97 */ 98 #define OS_ERRNO_TIMER_NUM_ZERO OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x07) 99 100 /* 101 * 软件定时器错误码:定时器未初始化或定时器组未创建。 102 * 103 * 值: 0x02000d08 104 * 105 * 解决方案: 只有在定时器初始化且定时器组已经创建的情况下才能使用定时器。 106 */ 107 #define OS_ERRNO_TIMER_NOT_INIT_OR_GROUP_NOT_CREATED OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x08) 108 109 /* 110 * 软件定时器错误码:定时器设置的定时周期转化为Tick数后不为整数。 111 * 112 * 值: 0x02000d09 113 * 114 * 解决方案: 请确保设置的定时周期是Tick的整数倍。 115 */ 116 #define OS_ERRNO_SWTMR_INTERVAL_NOT_SUITED OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x09) 117 118 /* 119 * 软件定时器错误码:达到最大支持定时器数目。 120 * 121 * 值: 0x02000d0a 122 * 123 * 解决方案: 达到最大支持定时器个数,不能再创建软件定时器。 124 */ 125 #define OS_ERRNO_SWTMR_MAXSIZE OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x0a) 126 127 /* 128 * 软件定时器错误码:定时器未创建。 129 * 130 * 值: 0x02000d0b 131 * 132 * 解决方案: 创建定时器后再使用。 133 */ 134 #define OS_ERRNO_SWTMR_NOT_CREATED OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x0b) 135 136 /* 137 * 软件定时器错误码:定时器已经处于未启动状态。 138 * 139 * 值: 0x02000d0c 140 * 141 * 解决方案: 定时器处于未启动状态,不能进行一些操作,请检查操作的合法性。 142 */ 143 #define OS_ERRNO_SWTMR_UNSTART OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x0c) 144 145 /* 146 * 软件定时器错误码:初始化内存不足。 147 * 148 * 值: 0x02000d0d 149 * 150 * 解决方案: 请适当增加系统默认FSC分区大小。 151 */ 152 #define OS_ERRNO_SWTMR_NO_MEMORY OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x0d) 153 154 /* 155 * 软件定时器错误码:TICK没有初始化。 156 * 157 * 值: 0x02000d0e 158 * 159 * 解决方案: 初始化Tick。 160 */ 161 #define OS_ERRNO_TICK_NOT_INIT OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x0e) 162 163 /* 164 * 软件定时器错误码:软件定时器定时周期过大,转换为Tick数超过0xFFFFFFFF。 165 * 166 * 值: 0x02000d0f 167 * 168 * 解决方案: 请确保传入的定时周期转化为Tick数后不大于0xFFFFFFFF。 169 */ 170 #define OS_ERRNO_SWTMR_INTERVAL_OVERFLOW OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x0f) 171 172 /* 173 * 软件定时器错误码:Tick定时器组已创建。 174 * 175 * 值: 0x02000d10 176 * 177 * 解决方案: 不能重复创建定时器组。 178 */ 179 #define OS_ERRNO_TIMER_TICKGROUP_CREATED OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x10) 180 181 /* 182 * 软件定时器错误码:创建软件定时器时传入定时器组组号非法。 183 * 184 * 值: 0x02000d11 185 * 186 * 解决方案: 确保传入的定时器组号是通过使用定时器组创建接口得到。 187 */ 188 #define OS_ERRNO_TIMERGROUP_ID_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x11) 189 190 /* 191 * 软件定时器错误码:软件定时器组的最大定时器个数大于0xffff。 192 * 193 * 值: 0x02000d12 194 * 195 * 解决方案: 确保软件定时器组的最大定时器个数小于等于0xffff。 196 */ 197 #define OS_ERRNO_TIMER_NUM_TOO_LARGE OS_ERRNO_BUILD_ERROR(OS_MID_TIMER, 0x12) 198 199 /* 200 * 定时器句柄定义 201 */ 202 typedef U32 TimerHandle; 203 204 /* 205 * 定时器组句柄定义 206 */ 207 typedef U32 TimerGroupId; 208 209 /* 210 * 定时器回调函数定义,带5个参数、返回值类型为void的函数指针类型,其中参数tmrHandle在核内硬件定时器、 211 * 全局硬件定时器和软件定时器中分别表示逻辑ID、物理ID和逻辑ID。 212 */ 213 typedef void (*TmrProcFunc)(TimerHandle tmrHandle, U32 arg1, U32 arg2, U32 arg3, U32 arg4); 214 215 /* 216 * 定时器组时钟源类型枚举定义 217 */ 218 enum TimerGrpSrcType { 219 OS_TIMER_GRP_SRC_HARDWARE, /* 硬件私有时钟源 */ 220 OS_TIMER_GRP_SRC_HARDWARE_SHARED, /* 硬件共享时钟源 */ 221 OS_TIMER_GRP_SRC_EXTERN, /* 外部时钟源 */ 222 OS_TIMER_GRP_SRC_TICK, /* TICK时钟源 */ 223 OS_TIMER_GRP_SRC_INVALID 224 }; 225 226 /* 227 * 定时器组用户配置结构体 228 */ 229 struct TmrGrpUserCfg { 230 /* 时钟源类型 */ 231 enum TimerGrpSrcType tmrGrpSrcType; 232 /* 时间轮的刻度,即每刻度多少个us */ 233 U32 perStep; 234 /* 最大定时器个数 */ 235 U32 maxTimerNum; 236 /* 时间轮长度必须是2的N次方,此处配置N的大小 */ 237 U32 wheelLen2Power; 238 }; 239 240 /* 241 * 定时器工作模式枚举定义 242 */ 243 enum TmrMode { 244 OS_TIMER_LOOP, /* 定时器周期触发模式 */ 245 OS_TIMER_ONCE, /* 定时器单次触发模式 */ 246 OS_TIMER_INVALID_MODE 247 }; 248 249 /* 250 * 定时器类型枚举定义 251 */ 252 enum TimerType { 253 OS_TIMER_HARDWARE, /* 硬件定时器(核内私有硬件定时器) */ 254 OS_TIMER_SOFTWARE, /* 软件定时器(核内私有软件定时器) */ 255 OS_TIMER_SOFTWARE_SHARED, /* 共享软件定时器,目前不支持 */ 256 OS_TIMER_INVALID_TYPE 257 }; 258 259 /* 260 * 定时器创建参数结构体定义 261 */ 262 struct TimerCreatePara { 263 /* 定时器创建模块ID,当前未使用,忽略 */ 264 U32 moduleId; 265 /* 定时器类型 */ 266 enum TimerType type; 267 /* 定时器工作模式 */ 268 enum TmrMode mode; 269 /* 定时器周期(单次指定时器响应时长),软件定时器单位是ms,硬件定时器单位是us,高精度定时器单位是ns */ 270 U32 interval; 271 /* 272 * 定时器组号,硬件定时器不使用,若创建软件定时器,定时器组ID由OS创建 273 */ 274 U32 timerGroupId; 275 /* 定时器硬中断优先级 */ 276 U16 hwiPrio; 277 U16 resv; 278 /* 279 * 定时器回调函数 280 */ 281 TmrProcFunc callBackFunc; 282 /* 定时器用户参数1 */ 283 U32 arg1; 284 /* 定时器用户参数2 */ 285 U32 arg2; 286 /* 定时器用户参数3 */ 287 U32 arg3; 288 /* 定时器用户参数4 */ 289 U32 arg4; 290 }; 291 292 /* 293 * @brief 创建定时器。 294 * 295 * @par 描述 296 * 创建一个属性为createPara的定时器,返回定时器逻辑ID tmrHandle。 297 * 298 * @attention 299 * <ul> 300 * <li>如果用户打开Tick开关则可创建硬件定时器个数少一个。</li> 301 * <li>中断处理函数handler的第一个参数是创建的定时器的逻辑编号。</li> 302 * <li>定时器创建成功后并不立即开始计数,需显式调用#PRT_TimerStart或者#PRT_TimerRestart启动。</li> 303 * <li>对于周期定时模式的定时器,建议用户不要把定时间隔设置的过低,避免一直触发定时器的处理函数。</li> 304 * <li>struct TimerCreatePara参数里面的interval元素表示定时器周期,软件定时器单位是ms, 305 * 核内硬件定时器、全局硬件定时器单位是us,设置时间间隔的时候请注意适配,过大会出现溢出。</li> 306 * </ul> 307 * 308 * @param createPara [IN] 类型#struct TimerCreatePara *,定时器创建参数 309 * @param tmrHandle [OUT] 类型#TimerHandle *,定时器句柄 310 * 311 * @retval #OS_OK 0x00000000,定时器创建成功。 312 * @retval #其它值,创建失败。 313 * @par 依赖 314 * <ul><li>prt_timer.h:该接口声明所在的头文件。</li></ul> 315 * @see PRT_TimerDelete 316 */ 317 extern U32 PRT_TimerCreate(struct TimerCreatePara *createPara, TimerHandle *tmrHandle); 318 319 /* 320 * @brief 删除定时器。 321 * 322 * @par 描述 323 * 释放一个定时器逻辑ID为tmrHandle的定时器资源。 324 * 325 * @attention 326 * <ul> 327 * <li>硬件定时器删除后将停止计数。</li> 328 * <li>删除处于超时状态下的软件定时器时,OS采用延时删除的方式。详细说明请见手册注意事项。</li> 329 * </ul> 330 * 331 * @param mid [IN] 类型#U32,模块号,当前未使用,忽略 332 * @param tmrHandle [IN] 类型#TimerHandle,定时器句柄,通过PRT_TimerCreate接口获取 333 * 334 * @retval #OS_OK 0x00000000,定时器删除成功。 335 * @retval #其它值,删除失败。 336 * @par 依赖 337 * <ul><li>prt_timer.h:该接口声明所在的头文件。</li></ul> 338 * @see PRT_TimerCreate 339 */ 340 extern U32 PRT_TimerDelete(U32 mid, TimerHandle tmrHandle); 341 342 /* 343 * @brief 启动定时器。 344 * 345 * @par 描述 346 * 将定时器逻辑ID为tmrHandle的定时器由创建状态变成启动状态。 347 * 348 * @attention 349 * <ul> 350 * <li>创建后初次启动定时器时,从设置的值开始计数;如果重复启动或者启动后停止然后再启动, 351 * 从重复启动点或者停止点的计数值开始计数。</li> 352 * <li>对于全局硬件定时器,无论是第一次启动还是重复启动,下一次启动都从初始值开始计时。</li> 353 * <li>对于单次触发模式,触发一次后,可以调用启动接口再次启动该定时器,时间间隔为设置的时间间隔。</li> 354 * <li>启动处于超时状态下的软件定时器时,OS采用延时启动的方式。详细说明请见手册注意事项。</li> 355 * </ul> 356 * 357 * @param mid [IN] 类型#U32,模块号,当前未使用,忽略 358 * @param tmrHandle [IN] 类型#TimerHandle,定时器句柄,通过#PRT_TimerCreate接口获取 359 * 360 * @retval #OS_OK 0x00000000,定时器启动成功。 361 * @retval #其它值,启动失败。 362 * @par 依赖 363 * <ul><li>prt_timer.h:该接口声明所在的头文件。</li></ul> 364 * @see PRT_TimerStop 365 */ 366 extern U32 PRT_TimerStart(U32 mid, TimerHandle tmrHandle); 367 368 /* 369 * @brief 停止定时器。 370 * 371 * @par 描述 372 * 停止定时器逻辑ID为tmrHandle的定时器计数,使定时器由计时状态变成创建状态。 373 * 374 * @attention 375 * <ul> 376 * <li>定时器停止后,下一次启动将重新从停止点的计数值开始计数。 377 * 但是对于全局硬件定时器,下一次启动从初始值开始计时。</li> 378 * <li>不能停止未启动的定时器。</li> 379 * <li>停止处于超时状态下的软件定时器时,OS采用延时停止的方式。详细说明请见手册注意事项。</li> 380 * <li>核内硬件定时器在停止过程中如果发生超时,则剩余时间为0,但不会响应定时器处理函数。</li> 381 * </ul> 382 * 383 * @param mid [IN] 类型#U32,模块号,当前未使用,忽略 384 * @param tmrHandle [IN] 类型#TimerHandle,定时器句柄,通过#PRT_TimerCreate接口获取 385 * 386 * @retval #OS_OK 0x00000000,定时器停止成功。 387 * @retval #其它值,停止失败。 388 * 389 * @par 依赖 390 * <ul><li>prt_timer.h:该接口声明所在的头文件。</li></ul> 391 * @see PRT_TimerStart 392 */ 393 extern U32 PRT_TimerStop(U32 mid, TimerHandle tmrHandle); 394 395 /* 396 * @brief 重启定时器 397 * 398 * @par 描述 399 * 重启定时器逻辑ID为tmrHandle的定时器计数,对于停止过的定时器,相当于恢复到刚创建时的定时时长开始计时。 400 * 401 * @attention 402 * <ul> 403 * <li>重启处于超时状态下的软件定时器时,OS采用延时重启的方式。详细说明请见手册注意事项。</li> 404 * </ul> 405 * 406 * @param mid [IN] 类型#U32,模块号,当前未使用,忽略 407 * @param tmrHandle [IN] 类型#TimerHandle,定时器句柄,通过#PRT_TimerCreate接口获取 408 * 409 * @retval #OS_OK 0x00000000,定时器重启成功。 410 * @retval #其它值,重启失败。 411 * @par 依赖 412 * <ul><li>prt_timer.h:该接口声明所在的头文件。</li></ul> 413 * @see PRT_TimerStop 414 */ 415 extern U32 PRT_TimerRestart(U32 mid, TimerHandle tmrHandle); 416 417 /* 418 * @brief 定时器剩余超时时间查询 419 * 420 * @par 描述 421 * 输入定时器句柄tmrHandle,获得对应定时器超时剩余时间expireTime。 422 * 423 * @attention 424 * <ul> 425 * <li>软件定时器单位毫秒,核内和全局硬件定时器单位微秒。</li> 426 * <li>由于OS内部软件定时器采用Tick作为计时单位,硬件定时器采用Cycle作为计时单位, 427 * 所以剩余时间转化成ms或us不一定是整数,当转化后的ms或us数不为整数时,返回的剩余时间是该ms或us数取整后+1; 428 * 例如转化后ms数为4.2,则最终用户得到的剩余时间是5ms。</li> 429 * </ul> 430 * 431 * @param mid [IN] 类型#U32,模块号,当前未使用,忽略 432 * @param tmrHandle [IN] 类型#TimerHandle,定时器句柄,通过#PRT_TimerCreate接口获取 433 * @param expireTime [OUT] 类型#U32 *,定时器的剩余的超时时间,共享和私有硬件定时器单位us,软件定时器单位ms 434 * 435 * @retval #OS_OK 0x00000000,定时器剩余超时时间查询成功。 436 * @retval #其它值,查询失败。 437 * @par 依赖 438 * <ul><li>prt_timer.h:该接口声明所在的头文件。</li></ul> 439 * @see PRT_TimerCreate 440 */ 441 extern U32 PRT_TimerQuery(U32 mid, TimerHandle tmrHandle, U32 *expireTime); 442 443 #ifdef __cplusplus 444 #if __cplusplus 445 } 446 #endif 447 #endif 448 449 #endif /* PRT_TIMER_H */ 450