1 /* 2 * Copyright (c) 2006-2024, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2007-01-10 Bernard the first version 9 * 2008-07-12 Bernard remove all rt_int8, rt_uint32_t etc typedef 10 * 2010-10-26 yi.qiu add module support 11 * 2010-11-10 Bernard add cleanup callback function in thread exit. 12 * 2011-05-09 Bernard use builtin va_arg in GCC 4.x 13 * 2012-11-16 Bernard change RT_NULL from ((void*)0) to 0. 14 * 2012-12-29 Bernard change the RT_USING_MEMPOOL location and add 15 * RT_USING_MEMHEAP condition. 16 * 2012-12-30 Bernard add more control command for graphic. 17 * 2013-01-09 Bernard change version number. 18 * 2015-02-01 Bernard change version number to v2.1.0 19 * 2017-08-31 Bernard change version number to v3.0.0 20 * 2017-11-30 Bernard change version number to v3.0.1 21 * 2017-12-27 Bernard change version number to v3.0.2 22 * 2018-02-24 Bernard change version number to v3.0.3 23 * 2018-04-25 Bernard change version number to v3.0.4 24 * 2018-05-31 Bernard change version number to v3.1.0 25 * 2018-09-04 Bernard change version number to v3.1.1 26 * 2018-09-14 Bernard apply Apache License v2.0 to RT-Thread Kernel 27 * 2018-10-13 Bernard change version number to v4.0.0 28 * 2018-10-02 Bernard add 64bit arch support 29 * 2018-11-22 Jesven add smp member to struct rt_thread 30 * add struct rt_cpu 31 * add smp relevant macros 32 * 2019-01-27 Bernard change version number to v4.0.1 33 * 2019-05-17 Bernard change version number to v4.0.2 34 * 2019-12-20 Bernard change version number to v4.0.3 35 * 2020-08-10 Meco Man add macro for struct rt_device_ops 36 * 2020-10-23 Meco Man define maximum value of ipc type 37 * 2021-03-19 Meco Man add security devices 38 * 2021-05-10 armink change version number to v4.0.4 39 * 2021-11-19 Meco Man change version number to v4.1.0 40 * 2021-12-21 Meco Man re-implement RT_UNUSED 41 * 2022-01-01 Gabriel improve hooking method 42 * 2022-01-07 Gabriel move some __on_rt_xxxxx_hook to dedicated c source files 43 * 2022-01-12 Meco Man remove RT_THREAD_BLOCK 44 * 2022-04-20 Meco Man change version number to v4.1.1 45 * 2022-04-21 THEWON add macro RT_VERSION_CHECK 46 * 2022-06-29 Meco Man add RT_USING_LIBC and standard libc headers 47 * 2022-08-16 Meco Man change version number to v5.0.0 48 * 2022-09-12 Meco Man define rt_ssize_t 49 * 2022-12-20 Meco Man add const name for rt_object 50 * 2023-04-01 Chushicheng change version number to v5.0.1 51 * 2023-05-20 Bernard add stdc atomic detection. 52 * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable 53 * 2023-10-10 Chushicheng change version number to v5.1.0 54 * 2023-10-11 zmshahaha move specific devices related and driver to components/drivers 55 * 2023-11-21 Meco Man add RT_USING_NANO macro 56 * 2023-11-17 xqyjlj add process group and session support 57 * 2023-12-01 Shell Support of dynamic device 58 * 2023-12-18 xqyjlj add rt_always_inline 59 * 2023-12-22 Shell Support hook list 60 * 2024-01-18 Shell Seperate basical types to a rttypes.h 61 * Seperate the compiler portings to rtcompiler.h 62 * 2024-03-30 Meco Man update version number to v5.2.0 63 */ 64 65 #ifndef __RT_DEF_H__ 66 #define __RT_DEF_H__ 67 68 #include "rtsched.h" 69 #include "rttypes.h" 70 71 #include "klibc/kerrno.h" 72 73 #ifdef __cplusplus 74 extern "C" { 75 #endif 76 77 /** 78 * @addtogroup group_basic_definition 79 */ 80 81 /**@{*/ 82 83 /* RT-Thread version information */ 84 #define RT_VERSION_MAJOR 5 /**< Major version number (X.x.x) */ 85 #define RT_VERSION_MINOR 2 /**< Minor version number (x.X.x) */ 86 #define RT_VERSION_PATCH 1 /**< Patch version number (x.x.X) */ 87 88 /* e.g. #if (RTTHREAD_VERSION >= RT_VERSION_CHECK(4, 1, 0) */ 89 #define RT_VERSION_CHECK(major, minor, revise) ((major * 10000U) + (minor * 100U) + revise) 90 91 /* RT-Thread version */ 92 #define RTTHREAD_VERSION RT_VERSION_CHECK(RT_VERSION_MAJOR, RT_VERSION_MINOR, RT_VERSION_PATCH) 93 94 /**@}*/ 95 96 /* maximum value of base type */ 97 #ifdef RT_USING_LIBC 98 #define RT_UINT8_MAX UINT8_MAX /**< Maximum number of UINT8 */ 99 #define RT_UINT16_MAX UINT16_MAX /**< Maximum number of UINT16 */ 100 #define RT_UINT32_MAX UINT32_MAX /**< Maximum number of UINT32 */ 101 #define RT_UINT64_MAX UINT64_MAX /**< Maximum number of UINT64 */ 102 #else 103 #define RT_UINT8_MAX 0xFFU /**< Maximum number of UINT8 */ 104 #define RT_UINT16_MAX 0xFFFFU /**< Maximum number of UINT16 */ 105 #define RT_UINT32_MAX 0xFFFFFFFFUL /**< Maximum number of UINT32 */ 106 #define RT_UINT64_MAX 0xFFFFFFFFFFFFFFFFULL /**< Maximum number of UINT64 */ 107 #endif /* RT_USING_LIBC */ 108 109 #define RT_TICK_MAX RT_UINT32_MAX /**< Maximum number of tick */ 110 111 /* maximum value of ipc type */ 112 #define RT_SEM_VALUE_MAX RT_UINT16_MAX /**< Maximum number of semaphore .value */ 113 #define RT_MUTEX_VALUE_MAX RT_UINT16_MAX /**< Maximum number of mutex .value */ 114 #define RT_MUTEX_HOLD_MAX RT_UINT8_MAX /**< Maximum number of mutex .hold */ 115 #define RT_MB_ENTRY_MAX RT_UINT16_MAX /**< Maximum number of mailbox .entry */ 116 #define RT_MQ_ENTRY_MAX RT_UINT16_MAX /**< Maximum number of message queue .entry */ 117 118 /* Common Utilities */ 119 120 #define RT_UNUSED(x) ((void)(x)) 121 122 /* compile time assertion */ 123 #define RT_STATIC_ASSERT(name, expn) typedef char _static_assert_##name[(expn)?1:-1] 124 125 /* Compiler Related Definitions */ 126 #include "rtcompiler.h" 127 128 /* initialization export */ 129 #ifdef RT_USING_COMPONENTS_INIT 130 typedef int (*init_fn_t)(void); 131 #ifdef _MSC_VER 132 #pragma section("rti_fn$f",read) 133 #ifdef RT_DEBUGING_AUTO_INIT 134 struct rt_init_desc 135 { 136 const char* level; 137 const init_fn_t fn; 138 const char* fn_name; 139 }; 140 #define INIT_EXPORT(fn, level) \ 141 const char __rti_level_##fn[] = ".rti_fn." level; \ 142 const char __rti_##fn##_name[] = #fn; \ 143 __declspec(allocate("rti_fn$f")) \ 144 rt_used const struct rt_init_desc __rt_init_msc_##fn = \ 145 {__rti_level_##fn, fn, __rti_##fn##_name}; 146 #else 147 struct rt_init_desc 148 { 149 const char* level; 150 const init_fn_t fn; 151 }; 152 #define INIT_EXPORT(fn, level) \ 153 const char __rti_level_##fn[] = ".rti_fn." level; \ 154 __declspec(allocate("rti_fn$f")) \ 155 rt_used const struct rt_init_desc __rt_init_msc_##fn = \ 156 {__rti_level_##fn, fn }; 157 #endif /* RT_DEBUGING_AUTO_INIT */ 158 #else 159 #ifdef RT_DEBUGING_AUTO_INIT 160 struct rt_init_desc 161 { 162 const char* fn_name; 163 const init_fn_t fn; 164 }; 165 #define INIT_EXPORT(fn, level) \ 166 const char __rti_##fn##_name[] = #fn; \ 167 rt_used const struct rt_init_desc __rt_init_desc_##fn rt_section(".rti_fn." level) = \ 168 { __rti_##fn##_name, fn}; 169 #else 170 #define INIT_EXPORT(fn, level) \ 171 rt_used const init_fn_t __rt_init_##fn rt_section(".rti_fn." level) = fn 172 #endif /* RT_DEBUGING_AUTO_INIT */ 173 #endif /* _MSC_VER */ 174 #else 175 #define INIT_EXPORT(fn, level) 176 #endif /* RT_USING_COMPONENTS_INIT */ 177 178 /* board init routines will be called in board_init() function */ 179 #define INIT_BOARD_EXPORT(fn) INIT_EXPORT(fn, "1") 180 181 /* init cpu, memory, interrupt-controller, bus... */ 182 #define INIT_CORE_EXPORT(fn) INIT_EXPORT(fn, "1.0") 183 /* init sys-timer, clk, pinctrl... */ 184 #define INIT_SUBSYS_EXPORT(fn) INIT_EXPORT(fn, "1.1") 185 /* init platform, user code... */ 186 #define INIT_PLATFORM_EXPORT(fn) INIT_EXPORT(fn, "1.2") 187 188 /* pre/device/component/env/app init routines will be called in init_thread */ 189 /* components pre-initialization (pure software initialization) */ 190 #define INIT_PREV_EXPORT(fn) INIT_EXPORT(fn, "2") 191 /* device initialization */ 192 #define INIT_DEVICE_EXPORT(fn) INIT_EXPORT(fn, "3") 193 /* components initialization (dfs, lwip, ...) */ 194 #define INIT_COMPONENT_EXPORT(fn) INIT_EXPORT(fn, "4") 195 /* environment initialization (mount disk, ...) */ 196 #define INIT_ENV_EXPORT(fn) INIT_EXPORT(fn, "5") 197 /* application initialization (rtgui application etc ...) */ 198 #define INIT_APP_EXPORT(fn) INIT_EXPORT(fn, "6") 199 200 /* init after mount fs */ 201 #define INIT_FS_EXPORT(fn) INIT_EXPORT(fn, "6.0") 202 /* init in secondary_cpu_c_start */ 203 #define INIT_SECONDARY_CPU_EXPORT(fn) INIT_EXPORT(fn, "7") 204 205 #if !defined(RT_USING_FINSH) 206 /* define these to empty, even if not include finsh.h file */ 207 #define FINSH_FUNCTION_EXPORT(name, desc) 208 #define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) 209 210 #define MSH_CMD_EXPORT(command, desc) 211 #define MSH_CMD_EXPORT_ALIAS(command, alias, desc) 212 #elif !defined(FINSH_USING_SYMTAB) 213 #define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) 214 #endif 215 216 /* event length */ 217 #define RT_EVENT_LENGTH 32 218 219 /* memory management option */ 220 #define RT_MM_PAGE_SIZE 4096 221 #define RT_MM_PAGE_MASK (RT_MM_PAGE_SIZE - 1) 222 #define RT_MM_PAGE_BITS 12 223 224 /* kernel malloc definitions */ 225 #ifndef RT_KERNEL_MALLOC 226 #define RT_KERNEL_MALLOC(sz) rt_malloc(sz) 227 #endif /* RT_KERNEL_MALLOC */ 228 229 #ifndef RT_KERNEL_FREE 230 #define RT_KERNEL_FREE(ptr) rt_free(ptr) 231 #endif /* RT_KERNEL_FREE */ 232 233 #ifndef RT_KERNEL_REALLOC 234 #define RT_KERNEL_REALLOC(ptr, size) rt_realloc(ptr, size) 235 #endif /* RT_KERNEL_REALLOC */ 236 237 /** 238 * @ingroup group_basic_definition 239 * 240 * @def RT_IS_ALIGN(addr, align) 241 * Return true(1) or false(0). 242 * RT_IS_ALIGN(128, 4) is judging whether 128 aligns with 4. 243 * The result is 1, which means 128 aligns with 4. 244 * @note If the address is NULL, false(0) will be returned 245 */ 246 #define RT_IS_ALIGN(addr, align) ((!(addr & (align - 1))) && (addr != RT_NULL)) 247 248 /** 249 * @ingroup group_basic_definition 250 * 251 * @def RT_ALIGN(size, align) 252 * Return the most contiguous size aligned at specified width. RT_ALIGN(13, 4) 253 * would return 16. 254 * @note align Must be an integer power of 2 or the result will be incorrect 255 */ 256 #define RT_ALIGN(size, align) (((size) + (align) - 1) & ~((align) - 1)) 257 258 /** 259 * @ingroup group_basic_definition 260 * 261 * @def RT_ALIGN_DOWN(size, align) 262 * Return the down number of aligned at specified width. RT_ALIGN_DOWN(13, 4) 263 * would return 12. 264 * @note align Must be an integer power of 2 or the result will be incorrect 265 */ 266 #define RT_ALIGN_DOWN(size, align) ((size) & ~((align) - 1)) 267 268 /** 269 * @addtogroup group_object_management 270 */ 271 272 /**@{*/ 273 274 /* 275 * kernel object macros 276 */ 277 #define RT_OBJECT_FLAG_MODULE 0x80 /**< is module object. */ 278 279 /** 280 * Base structure of Kernel object 281 */ 282 struct rt_object 283 { 284 #if RT_NAME_MAX > 0 285 char name[RT_NAME_MAX]; /**< dynamic name of kernel object */ 286 #else 287 const char *name; /**< static name of kernel object */ 288 #endif /* RT_NAME_MAX > 0 */ 289 rt_uint8_t type; /**< type of kernel object */ 290 rt_uint8_t flag; /**< flag of kernel object */ 291 292 #ifdef RT_USING_MODULE 293 void * module_id; /**< id of application module */ 294 #endif /* RT_USING_MODULE */ 295 296 #ifdef RT_USING_SMART 297 rt_atomic_t lwp_ref_count; /**< ref count for lwp */ 298 #endif /* RT_USING_SMART */ 299 300 rt_list_t list; /**< list node of kernel object */ 301 }; 302 typedef struct rt_object *rt_object_t; /**< Type for kernel objects. */ 303 304 /** 305 * iterator of rt_object_for_each() 306 * 307 * data is the data passing in to rt_object_for_each(). iterator can return 308 * RT_EOK to continue the iteration; or any positive value to break the loop 309 * successfully; or any negative errno to break the loop on failure. 310 */ 311 typedef rt_err_t (*rt_object_iter_t)(rt_object_t object, void *data); 312 313 /** 314 * The object type can be one of the follows with specific 315 * macros enabled: 316 * - Thread 317 * - Semaphore 318 * - Mutex 319 * - Event 320 * - MailBox 321 * - MessageQueue 322 * - MemHeap 323 * - MemPool 324 * - Device 325 * - Timer 326 * - Module 327 * - Unknown 328 * - Static 329 */ 330 enum rt_object_class_type 331 { 332 RT_Object_Class_Null = 0x00, /**< The object is not used. */ 333 RT_Object_Class_Thread = 0x01, /**< The object is a thread. */ 334 RT_Object_Class_Semaphore = 0x02, /**< The object is a semaphore. */ 335 RT_Object_Class_Mutex = 0x03, /**< The object is a mutex. */ 336 RT_Object_Class_Event = 0x04, /**< The object is a event. */ 337 RT_Object_Class_MailBox = 0x05, /**< The object is a mail box. */ 338 RT_Object_Class_MessageQueue = 0x06, /**< The object is a message queue. */ 339 RT_Object_Class_MemHeap = 0x07, /**< The object is a memory heap. */ 340 RT_Object_Class_MemPool = 0x08, /**< The object is a memory pool. */ 341 RT_Object_Class_Device = 0x09, /**< The object is a device. */ 342 RT_Object_Class_Timer = 0x0a, /**< The object is a timer. */ 343 RT_Object_Class_Module = 0x0b, /**< The object is a module. */ 344 RT_Object_Class_Memory = 0x0c, /**< The object is a memory. */ 345 RT_Object_Class_Channel = 0x0d, /**< The object is a channel */ 346 RT_Object_Class_ProcessGroup = 0x0e, /**< The object is a process group */ 347 RT_Object_Class_Session = 0x0f, /**< The object is a session */ 348 RT_Object_Class_Custom = 0x10, /**< The object is a custom object */ 349 RT_Object_Class_Unknown = 0x11, /**< The object is unknown. */ 350 RT_Object_Class_Static = 0x80 /**< The object is a static object. */ 351 }; 352 353 /** 354 * The information of the kernel object 355 */ 356 struct rt_object_information 357 { 358 enum rt_object_class_type type; /**< object class type */ 359 rt_list_t object_list; /**< object list */ 360 rt_size_t object_size; /**< object size */ 361 struct rt_spinlock spinlock; 362 }; 363 364 /** 365 * The hook function call macro 366 */ 367 #ifndef RT_USING_HOOK 368 #define RT_OBJECT_HOOK_CALL(func, argv) 369 370 #else 371 372 /** 373 * @brief Add hook point in the routines 374 * @note Usage: 375 * void foo() { 376 * do_something(); 377 * 378 * RT_OBJECT_HOOK_CALL(foo); 379 * 380 * do_other_things(); 381 * } 382 */ 383 #define _RT_OBJECT_HOOK_CALL(func, argv) __ON_HOOK_ARGS(func, argv) 384 #define RT_OBJECT_HOOK_CALL(func, argv) _RT_OBJECT_HOOK_CALL(func, argv) 385 386 #ifdef RT_HOOK_USING_FUNC_PTR 387 #define __ON_HOOK_ARGS(__hook, argv) do {if ((__hook) != RT_NULL) __hook argv; } while (0) 388 #else 389 #define __ON_HOOK_ARGS(__hook, argv) 390 #endif /* RT_HOOK_USING_FUNC_PTR */ 391 #endif /* RT_USING_HOOK */ 392 393 #ifdef RT_USING_HOOKLIST 394 395 /** 396 * @brief Add declaration for hook list types. 397 * 398 * @note Usage: 399 * This is typically used in your header. In foo.h using this like: 400 * 401 * ```foo.h 402 * typedef void (*bar_hook_proto_t)(arguments...); 403 * RT_OBJECT_HOOKLIST_DECLARE(bar_hook_proto_t, bar_myhook); 404 * ``` 405 */ 406 #define RT_OBJECT_HOOKLIST_DECLARE(handler_type, name) \ 407 typedef struct name##_hooklistnode \ 408 { \ 409 handler_type handler; \ 410 rt_list_t list_node; \ 411 } *name##_hooklistnode_t; \ 412 extern volatile rt_ubase_t name##_nested; \ 413 void name##_sethook(name##_hooklistnode_t node); \ 414 void name##_rmhook(name##_hooklistnode_t node) 415 416 /** 417 * @brief Add declaration for hook list node. 418 * 419 * @note Usage 420 * You can add a hook like this. 421 * 422 * ```addhook.c 423 * void myhook(arguments...) { do_something(); } 424 * RT_OBJECT_HOOKLIST_DEFINE_NODE(bar_myhook, myhook_node, myhook); 425 * 426 * void addhook(void) 427 * { 428 * bar_myhook_sethook(myhook); 429 * } 430 * ``` 431 * 432 * BTW, you can also find examples codes under 433 * `examples/utest/testcases/kernel/hooklist_tc.c`. 434 */ 435 #define RT_OBJECT_HOOKLIST_DEFINE_NODE(hookname, nodename, hooker_handler) \ 436 struct hookname##_hooklistnode nodename = { \ 437 .handler = hooker_handler, \ 438 .list_node = RT_LIST_OBJECT_INIT(nodename.list_node), \ 439 }; 440 441 /** 442 * @note Usage 443 * Add this macro to the source file where your hook point is inserted. 444 */ 445 #define RT_OBJECT_HOOKLIST_DEFINE(name) \ 446 static rt_list_t name##_hooklist = RT_LIST_OBJECT_INIT(name##_hooklist); \ 447 static struct rt_spinlock name##lock = RT_SPINLOCK_INIT; \ 448 volatile rt_ubase_t name##_nested = 0; \ 449 void name##_sethook(name##_hooklistnode_t node) \ 450 { \ 451 rt_ubase_t level = rt_spin_lock_irqsave(&name##lock); \ 452 while (name##_nested) \ 453 { \ 454 rt_spin_unlock_irqrestore(&name##lock, level); \ 455 level = rt_spin_lock_irqsave(&name##lock); \ 456 } \ 457 rt_list_insert_before(&name##_hooklist, &node->list_node); \ 458 rt_spin_unlock_irqrestore(&name##lock, level); \ 459 } \ 460 void name##_rmhook(name##_hooklistnode_t node) \ 461 { \ 462 rt_ubase_t level = rt_spin_lock_irqsave(&name##lock); \ 463 while (name##_nested) \ 464 { \ 465 rt_spin_unlock_irqrestore(&name##lock, level); \ 466 level = rt_spin_lock_irqsave(&name##lock); \ 467 } \ 468 rt_list_remove(&node->list_node); \ 469 rt_spin_unlock_irqrestore(&name##lock, level); \ 470 } 471 472 /** 473 * @brief Add hook list point in the routines. Multiple hookers in the list will 474 * be called one by one starting from head node. 475 * 476 * @note Usage: 477 * void foo() { 478 * do_something(); 479 * 480 * RT_OBJECT_HOOKLIST_CALL(foo); 481 * 482 * do_other_things(); 483 * } 484 */ 485 #define _RT_OBJECT_HOOKLIST_CALL(nodetype, nested, list, lock, argv) \ 486 do \ 487 { \ 488 nodetype iter, next; \ 489 rt_ubase_t level = rt_spin_lock_irqsave(&lock); \ 490 nested += 1; \ 491 rt_spin_unlock_irqrestore(&lock, level); \ 492 if (!rt_list_isempty(&list)) \ 493 { \ 494 rt_list_for_each_entry_safe(iter, next, &list, list_node) \ 495 { \ 496 iter->handler argv; \ 497 } \ 498 } \ 499 level = rt_spin_lock_irqsave(&lock); \ 500 nested -= 1; \ 501 rt_spin_unlock_irqrestore(&lock, level); \ 502 } while (0) 503 #define RT_OBJECT_HOOKLIST_CALL(name, argv) \ 504 _RT_OBJECT_HOOKLIST_CALL(name##_hooklistnode_t, name##_nested, \ 505 name##_hooklist, name##lock, argv) 506 507 #else 508 509 #define RT_OBJECT_HOOKLIST_DECLARE(handler_type, name) 510 #define RT_OBJECT_HOOKLIST_DEFINE_NODE(hookname, nodename, hooker_handler) 511 #define RT_OBJECT_HOOKLIST_DEFINE(name) 512 #define RT_OBJECT_HOOKLIST_CALL(name, argv) 513 #endif /* RT_USING_HOOKLIST */ 514 515 /**@}*/ 516 517 /** 518 * @addtogroup group_clock_management 519 */ 520 521 /**@{*/ 522 523 /** 524 * clock & timer macros 525 */ 526 #define RT_TIMER_FLAG_DEACTIVATED 0x0 /**< timer is deactive */ 527 #define RT_TIMER_FLAG_ACTIVATED 0x1 /**< timer is active */ 528 #define RT_TIMER_FLAG_ONE_SHOT 0x0 /**< one shot timer */ 529 #define RT_TIMER_FLAG_PERIODIC 0x2 /**< periodic timer */ 530 531 #define RT_TIMER_FLAG_HARD_TIMER 0x0 /**< hard timer,the timer's callback function will be called in tick isr. */ 532 #define RT_TIMER_FLAG_SOFT_TIMER 0x4 /**< soft timer,the timer's callback function will be called in timer thread. */ 533 #define RT_TIMER_FLAG_THREAD_TIMER \ 534 (0x8 | RT_TIMER_FLAG_HARD_TIMER) /**< thread timer that cooperates with scheduler directly */ 535 536 #define RT_TIMER_CTRL_SET_TIME 0x0 /**< set timer control command */ 537 #define RT_TIMER_CTRL_GET_TIME 0x1 /**< get timer control command */ 538 #define RT_TIMER_CTRL_SET_ONESHOT 0x2 /**< change timer to one shot */ 539 #define RT_TIMER_CTRL_SET_PERIODIC 0x3 /**< change timer to periodic */ 540 #define RT_TIMER_CTRL_GET_STATE 0x4 /**< get timer run state active or deactive*/ 541 #define RT_TIMER_CTRL_GET_REMAIN_TIME 0x5 /**< get the remaining hang time */ 542 #define RT_TIMER_CTRL_GET_FUNC 0x6 /**< get timer timeout func */ 543 #define RT_TIMER_CTRL_SET_FUNC 0x7 /**< set timer timeout func */ 544 #define RT_TIMER_CTRL_GET_PARM 0x8 /**< get timer parameter */ 545 #define RT_TIMER_CTRL_SET_PARM 0x9 /**< set timer parameter */ 546 547 #ifndef RT_TIMER_SKIP_LIST_LEVEL 548 #define RT_TIMER_SKIP_LIST_LEVEL 1 549 #endif 550 551 /* 1 or 3 */ 552 #ifndef RT_TIMER_SKIP_LIST_MASK 553 #define RT_TIMER_SKIP_LIST_MASK 0x3 /**< Timer skips the list mask */ 554 #endif 555 556 /** 557 * timeout handler of rt_timer 558 */ 559 typedef void (*rt_timer_func_t)(void *parameter); 560 561 /** 562 * timer structure 563 */ 564 struct rt_timer 565 { 566 struct rt_object parent; /**< inherit from rt_object */ 567 568 rt_list_t row[RT_TIMER_SKIP_LIST_LEVEL]; 569 570 rt_timer_func_t timeout_func; /**< timeout function */ 571 void *parameter; /**< timeout function's parameter */ 572 573 rt_tick_t init_tick; /**< timer timeout tick */ 574 rt_tick_t timeout_tick; /**< timeout tick */ 575 }; 576 typedef struct rt_timer *rt_timer_t; 577 578 /**@}*/ 579 580 /** 581 * @addtogroup group_signal 582 */ 583 /**@{*/ 584 585 #ifdef RT_USING_SIGNALS 586 #define RT_SIG_MAX 32 587 typedef unsigned long rt_sigset_t; 588 typedef siginfo_t rt_siginfo_t; 589 typedef void (*rt_sighandler_t)(int signo); 590 #endif /* RT_USING_SIGNALS */ 591 /**@}*/ 592 593 /** 594 * @addtogroup group_thread_management 595 */ 596 597 /**@{*/ 598 599 /* 600 * Thread 601 */ 602 603 /* 604 * thread state definitions 605 */ 606 #define RT_THREAD_INIT 0x00 /**< Initialized status */ 607 #define RT_THREAD_CLOSE 0x01 /**< Closed status */ 608 #define RT_THREAD_READY 0x02 /**< Ready status */ 609 #define RT_THREAD_RUNNING 0x03 /**< Running status */ 610 611 /* 612 * for rt_thread_suspend_with_flag() 613 */ 614 enum 615 { 616 RT_INTERRUPTIBLE = 0, 617 RT_KILLABLE, 618 RT_UNINTERRUPTIBLE, 619 }; 620 621 #define RT_THREAD_SUSPEND_MASK 0x04 622 #define RT_SIGNAL_COMMON_WAKEUP_MASK 0x02 623 #define RT_SIGNAL_KILL_WAKEUP_MASK 0x01 624 625 #define RT_THREAD_SUSPEND_INTERRUPTIBLE (RT_THREAD_SUSPEND_MASK) /**< Suspend interruptable 0x4 */ 626 #define RT_THREAD_SUSPEND RT_THREAD_SUSPEND_INTERRUPTIBLE 627 #define RT_THREAD_SUSPEND_KILLABLE (RT_THREAD_SUSPEND_MASK | RT_SIGNAL_COMMON_WAKEUP_MASK) /**< Suspend with killable 0x6 */ 628 #define RT_THREAD_SUSPEND_UNINTERRUPTIBLE (RT_THREAD_SUSPEND_MASK | RT_SIGNAL_COMMON_WAKEUP_MASK | RT_SIGNAL_KILL_WAKEUP_MASK) /**< Suspend with uninterruptable 0x7 */ 629 #define RT_THREAD_STAT_MASK 0x07 630 631 #define RT_THREAD_STAT_YIELD 0x08 /**< indicate whether remaining_tick has been reloaded since last schedule */ 632 #define RT_THREAD_STAT_YIELD_MASK RT_THREAD_STAT_YIELD 633 634 #define RT_THREAD_STAT_SIGNAL 0x10 /**< task hold signals */ 635 #define RT_THREAD_STAT_SIGNAL_READY (RT_THREAD_STAT_SIGNAL | RT_THREAD_READY) 636 #define RT_THREAD_STAT_SIGNAL_WAIT 0x20 /**< task is waiting for signals */ 637 #define RT_THREAD_STAT_SIGNAL_PENDING 0x40 /**< signals is held and it has not been procressed */ 638 #define RT_THREAD_STAT_SIGNAL_MASK 0xf0 639 640 /** 641 * thread control command definitions 642 */ 643 #define RT_THREAD_CTRL_STARTUP 0x00 /**< Startup thread. */ 644 #define RT_THREAD_CTRL_CLOSE 0x01 /**< Close thread. */ 645 #define RT_THREAD_CTRL_CHANGE_PRIORITY 0x02 /**< Change thread priority. */ 646 #define RT_THREAD_CTRL_INFO 0x03 /**< Get thread information. */ 647 #define RT_THREAD_CTRL_BIND_CPU 0x04 /**< Set thread bind cpu. */ 648 #define RT_THREAD_CTRL_RESET_PRIORITY 0x05 /**< Reset thread priority. */ 649 650 /** 651 * CPU usage statistics data 652 */ 653 struct rt_cpu_usage_stats 654 { 655 rt_ubase_t user; 656 rt_ubase_t system; 657 rt_ubase_t irq; 658 rt_ubase_t idle; 659 }; 660 typedef struct rt_cpu_usage_stats *rt_cpu_usage_stats_t; 661 662 #ifdef RT_USING_SMP 663 664 #define RT_CPU_DETACHED RT_CPUS_NR /**< The thread not running on cpu. */ 665 #define RT_CPU_MASK ((1 << RT_CPUS_NR) - 1) /**< All CPUs mask bit. */ 666 667 #ifndef RT_SCHEDULE_IPI 668 #define RT_SCHEDULE_IPI 0 669 #endif /* RT_SCHEDULE_IPI */ 670 671 #ifndef RT_STOP_IPI 672 #define RT_STOP_IPI 1 673 #endif /* RT_STOP_IPI */ 674 675 #ifndef RT_SMP_CALL_IPI 676 #define RT_SMP_CALL_IPI 2 677 #endif 678 679 #define RT_MAX_IPI 3 680 681 #define _SCHEDULER_CONTEXT(fileds) fileds 682 683 /** 684 * CPUs definitions 685 * 686 */ 687 struct rt_cpu 688 { 689 /** 690 * protected by: 691 * - other cores: accessing from other coress is undefined behaviour 692 * - local core: rt_enter_critical()/rt_exit_critical() 693 */ 694 _SCHEDULER_CONTEXT( 695 struct rt_thread *current_thread; 696 697 rt_uint8_t irq_switch_flag:1; 698 rt_uint8_t sched_lock_flag:1; 699 #ifndef ARCH_USING_HW_THREAD_SELF 700 rt_uint8_t critical_switch_flag:1; 701 #endif /* ARCH_USING_HW_THREAD_SELF */ 702 703 rt_uint8_t current_priority; 704 rt_list_t priority_table[RT_THREAD_PRIORITY_MAX]; 705 #if RT_THREAD_PRIORITY_MAX > 32 706 rt_uint32_t priority_group; 707 rt_uint8_t ready_table[32]; 708 #else 709 rt_uint32_t priority_group; 710 #endif /* RT_THREAD_PRIORITY_MAX > 32 */ 711 712 rt_atomic_t tick; /**< Passing tickes on this core */ 713 ); 714 715 struct rt_thread *idle_thread; 716 rt_atomic_t irq_nest; 717 718 #ifdef RT_USING_SMART 719 struct rt_spinlock spinlock; 720 #endif /* RT_USING_SMART */ 721 #ifdef RT_USING_CPU_USAGE_TRACER 722 struct rt_cpu_usage_stats cpu_stat; 723 #endif /* RT_USING_CPU_USAGE_TRACER */ 724 #ifdef ARCH_USING_IRQ_CTX_LIST 725 rt_slist_t irq_ctx_head; 726 #endif /* ARCH_USING_IRQ_CTX_LIST */ 727 }; 728 729 #else /* !RT_USING_SMP */ 730 struct rt_cpu 731 { 732 struct rt_thread *current_thread; 733 struct rt_thread *idle_thread; 734 735 #ifdef RT_USING_CPU_USAGE_TRACER 736 struct rt_cpu_usage_stats cpu_stat; 737 #endif /* RT_USING_CPU_USAGE_TRACER */ 738 #ifdef ARCH_USING_IRQ_CTX_LIST 739 rt_slist_t irq_ctx_head; 740 #endif /* ARCH_USING_IRQ_CTX_LIST */ 741 }; 742 743 #endif /* RT_USING_SMP */ 744 745 typedef struct rt_cpu *rt_cpu_t; 746 /* Noted: As API to reject writing to this variable from application codes */ 747 #define rt_current_thread rt_thread_self() 748 749 struct rt_thread; 750 751 /** 752 * interrupt/exception frame handling 753 * 754 */ 755 756 typedef struct rt_interrupt_context { 757 void *context; /**< arch specific context */ 758 rt_slist_t node; /**< node for nested interrupt */ 759 } *rt_interrupt_context_t; 760 761 #ifdef RT_USING_SMART 762 typedef rt_err_t (*rt_wakeup_func_t)(void *object, struct rt_thread *thread); 763 764 struct rt_wakeup 765 { 766 rt_wakeup_func_t func; 767 void *user_data; 768 }; 769 770 #define _LWP_NSIG 64 771 772 #ifdef ARCH_CPU_64BIT 773 #define _LWP_NSIG_BPW 64 774 #else 775 #define _LWP_NSIG_BPW 32 776 #endif 777 778 #define _LWP_NSIG_WORDS (RT_ALIGN(_LWP_NSIG, _LWP_NSIG_BPW) / _LWP_NSIG_BPW) 779 780 typedef void (*lwp_sighandler_t)(int); 781 typedef void (*lwp_sigaction_t)(int signo, siginfo_t *info, void *context); 782 783 typedef struct { 784 unsigned long sig[_LWP_NSIG_WORDS]; 785 } lwp_sigset_t; 786 787 #if _LWP_NSIG <= 64 788 #define lwp_sigmask(signo) ((lwp_sigset_t){.sig = {[0] = ((long)(1u << ((signo)-1)))}}) 789 #define lwp_sigset_init(mask) ((lwp_sigset_t){.sig = {[0] = (long)(mask)}}) 790 #endif /* _LWP_NSIG <= 64 */ 791 792 struct lwp_sigaction { 793 union { 794 void (*_sa_handler)(int); 795 void (*_sa_sigaction)(int, siginfo_t *, void *); 796 } __sa_handler; 797 lwp_sigset_t sa_mask; 798 int sa_flags; 799 void (*sa_restorer)(void); 800 }; 801 802 typedef struct lwp_siginfo_ext { 803 union { 804 /* for SIGCHLD */ 805 struct { 806 int status; 807 clock_t utime; 808 clock_t stime; 809 } sigchld; 810 }; 811 } *lwp_siginfo_ext_t; 812 813 typedef struct lwp_siginfo { 814 rt_list_t node; 815 816 struct { 817 int signo; 818 int code; 819 820 int from_tid; 821 pid_t from_pid; 822 } ksiginfo; 823 824 /* the signal specified extension field */ 825 struct lwp_siginfo_ext *ext; 826 } *lwp_siginfo_t; 827 828 typedef struct lwp_sigqueue { 829 rt_list_t siginfo_list; 830 lwp_sigset_t sigset_pending; 831 } *lwp_sigqueue_t; 832 833 struct lwp_thread_signal { 834 lwp_sigset_t sigset_mask; 835 struct lwp_sigqueue sig_queue; 836 }; 837 838 struct rt_user_context 839 { 840 void *sp; 841 void *pc; 842 void *flag; 843 844 void *ctx; 845 }; 846 #endif /* RT_USING_SMART */ 847 848 typedef void (*rt_thread_cleanup_t)(struct rt_thread *tid); 849 850 /** 851 * Thread structure 852 */ 853 854 struct rt_thread 855 { 856 struct rt_object parent; 857 858 /* stack point and entry */ 859 void *sp; /**< stack point */ 860 void *entry; /**< entry */ 861 void *parameter; /**< parameter */ 862 void *stack_addr; /**< stack address */ 863 rt_uint32_t stack_size; /**< stack size */ 864 865 /* error code */ 866 rt_err_t error; /**< error code */ 867 868 #ifdef RT_USING_SMP 869 rt_atomic_t cpus_lock_nest; /**< cpus lock count */ 870 #endif 871 872 RT_SCHED_THREAD_CTX 873 struct rt_timer thread_timer; /**< built-in thread timer */ 874 rt_thread_cleanup_t cleanup; /**< cleanup function when thread exit */ 875 876 #ifdef RT_USING_MUTEX 877 /* object for IPC */ 878 rt_list_t taken_object_list; 879 rt_object_t pending_object; 880 #endif /* RT_USING_MUTEX */ 881 882 #ifdef RT_USING_EVENT 883 /* thread event */ 884 rt_uint32_t event_set; 885 rt_uint8_t event_info; 886 #endif /* RT_USING_EVENT */ 887 888 #ifdef RT_USING_SIGNALS 889 rt_sigset_t sig_pending; /**< the pending signals */ 890 rt_sigset_t sig_mask; /**< the mask bits of signal */ 891 892 #ifndef RT_USING_SMP 893 void *sig_ret; /**< the return stack pointer from signal */ 894 #endif /* RT_USING_SMP */ 895 rt_sighandler_t *sig_vectors; /**< vectors of signal handler */ 896 void *si_list; /**< the signal infor list */ 897 #endif /* RT_USING_SIGNALS */ 898 899 #ifdef RT_USING_CPU_USAGE 900 rt_uint64_t duration_tick; /**< cpu usage tick */ 901 #endif /* RT_USING_CPU_USAGE */ 902 903 #ifdef RT_USING_PTHREADS 904 void *pthread_data; /**< the handle of pthread data, adapt 32/64bit */ 905 #endif /* RT_USING_PTHREADS */ 906 907 /* light weight process if present */ 908 #ifdef RT_USING_SMART 909 void *msg_ret; /**< the return msg */ 910 911 void *lwp; /**< the lwp reference */ 912 /* for user create */ 913 void *user_entry; 914 void *user_stack; 915 rt_uint32_t user_stack_size; 916 rt_uint32_t *kernel_sp; /**< kernel stack point */ 917 rt_list_t sibling; /**< next thread of same process */ 918 919 struct lwp_thread_signal signal; /**< lwp signal for user-space thread */ 920 struct rt_user_context user_ctx; /**< user space context */ 921 struct rt_wakeup wakeup_handle; /**< wakeup handle for IPC */ 922 rt_atomic_t exit_request; /**< pending exit request of thread */ 923 int tid; /**< thread ID used by process */ 924 int tid_ref_count; /**< reference of tid */ 925 void *susp_recycler; /**< suspended recycler on this thread */ 926 void *robust_list; /**< pi lock, very carefully, it's a userspace list!*/ 927 928 #ifndef ARCH_MM_MMU 929 lwp_sighandler_t signal_handler[32]; 930 #else 931 int step_exec; 932 int debug_attach_req; 933 int debug_ret_user; 934 int debug_suspend; 935 struct rt_hw_exp_stack *regs; 936 void *thread_idr; /** lwp thread indicator */ 937 int *clear_child_tid; 938 #endif /* ARCH_MM_MMU */ 939 #endif /* RT_USING_SMART */ 940 941 #ifdef RT_USING_CPU_USAGE_TRACER 942 rt_ubase_t user_time; /**< Ticks on user */ 943 rt_ubase_t system_time; /**< Ticks on system */ 944 #endif /* RT_USING_CPU_USAGE_TRACER */ 945 946 #ifdef RT_USING_MEM_PROTECTION 947 void *mem_regions; 948 #ifdef RT_USING_HW_STACK_GUARD 949 void *stack_buf; 950 #endif /* RT_USING_HW_STACK_GUARD */ 951 #endif /* RT_USING_MEM_PROTECTION */ 952 953 struct rt_spinlock spinlock; 954 rt_ubase_t user_data; /**< private user data beyond this thread */ 955 }; 956 typedef struct rt_thread *rt_thread_t; 957 958 #ifdef RT_USING_SMART 959 #define LWP_IS_USER_MODE(t) ((t)->user_ctx.ctx == RT_NULL) 960 #else 961 #define LWP_IS_USER_MODE(t) (0) 962 #endif /* RT_USING_SMART */ 963 964 /**@}*/ 965 966 /** 967 * @addtogroup group_thread_comm 968 */ 969 970 /**@{*/ 971 972 /** 973 * IPC flags and control command definitions 974 */ 975 #define RT_IPC_FLAG_FIFO 0x00 /**< FIFOed IPC. @ref group_thread_comm. */ 976 #define RT_IPC_FLAG_PRIO 0x01 /**< PRIOed IPC. @ref group_thread_comm. */ 977 978 #define RT_IPC_CMD_UNKNOWN 0x00 /**< unknown IPC command */ 979 #define RT_IPC_CMD_RESET 0x01 /**< reset IPC object */ 980 #define RT_IPC_CMD_GET_STATE 0x02 /**< get the state of IPC object */ 981 #define RT_IPC_CMD_SET_VLIMIT 0x03 /**< set max limit value of IPC value */ 982 983 #define RT_WAITING_FOREVER -1 /**< Block forever until get resource. */ 984 #define RT_WAITING_NO 0 /**< Non-block. */ 985 986 /** 987 * Base structure of IPC object 988 */ 989 struct rt_ipc_object 990 { 991 struct rt_object parent; /**< inherit from rt_object */ 992 993 rt_list_t suspend_thread; /**< threads pended on this resource */ 994 }; 995 996 /** 997 * @addtogroup group_semaphore Semaphore 998 * @{ 999 */ 1000 1001 #ifdef RT_USING_SEMAPHORE 1002 /** 1003 * Semaphore structure 1004 */ 1005 struct rt_semaphore 1006 { 1007 struct rt_ipc_object parent; /**< inherit from ipc_object */ 1008 1009 rt_uint16_t value; /**< value of semaphore. */ 1010 rt_uint16_t max_value; 1011 struct rt_spinlock spinlock; 1012 }; 1013 typedef struct rt_semaphore *rt_sem_t; 1014 #endif /* RT_USING_SEMAPHORE */ 1015 1016 /**@}*/ 1017 1018 /** 1019 * @addtogroup group_mutex Mutex 1020 * @{ 1021 */ 1022 1023 #ifdef RT_USING_MUTEX 1024 /** 1025 * Mutual exclusion (mutex) structure 1026 */ 1027 struct rt_mutex 1028 { 1029 struct rt_ipc_object parent; /**< inherit from ipc_object */ 1030 1031 rt_uint8_t ceiling_priority; /**< the priority ceiling of mutexe */ 1032 rt_uint8_t priority; /**< the maximal priority for pending thread */ 1033 rt_uint8_t hold; /**< numbers of thread hold the mutex */ 1034 rt_uint8_t reserved; /**< reserved field */ 1035 1036 struct rt_thread *owner; /**< current owner of mutex */ 1037 rt_list_t taken_list; /**< the object list taken by thread */ 1038 struct rt_spinlock spinlock; 1039 }; 1040 typedef struct rt_mutex *rt_mutex_t; 1041 #endif /* RT_USING_MUTEX */ 1042 1043 /**@}*/ 1044 1045 /** 1046 * @addtogroup group_event Event 1047 * @{ 1048 */ 1049 1050 #ifdef RT_USING_EVENT 1051 /** 1052 * flag definitions in event 1053 */ 1054 #define RT_EVENT_FLAG_AND 0x01 /**< logic and */ 1055 #define RT_EVENT_FLAG_OR 0x02 /**< logic or */ 1056 #define RT_EVENT_FLAG_CLEAR 0x04 /**< clear flag */ 1057 1058 /* 1059 * event structure 1060 */ 1061 struct rt_event 1062 { 1063 struct rt_ipc_object parent; /**< inherit from ipc_object */ 1064 1065 rt_uint32_t set; /**< event set */ 1066 struct rt_spinlock spinlock; 1067 }; 1068 typedef struct rt_event *rt_event_t; 1069 #endif /* RT_USING_EVENT */ 1070 1071 /**@}*/ 1072 1073 /** 1074 * @addtogroup group_mailbox MailBox 1075 * @{ 1076 */ 1077 1078 #ifdef RT_USING_MAILBOX 1079 /** 1080 * mailbox structure 1081 */ 1082 struct rt_mailbox 1083 { 1084 struct rt_ipc_object parent; /**< inherit from ipc_object */ 1085 1086 rt_ubase_t *msg_pool; /**< start address of message buffer */ 1087 1088 rt_uint16_t size; /**< size of message pool */ 1089 1090 rt_uint16_t entry; /**< index of messages in msg_pool */ 1091 rt_uint16_t in_offset; /**< input offset of the message buffer */ 1092 rt_uint16_t out_offset; /**< output offset of the message buffer */ 1093 1094 rt_list_t suspend_sender_thread; /**< sender thread suspended on this mailbox */ 1095 struct rt_spinlock spinlock; 1096 }; 1097 typedef struct rt_mailbox *rt_mailbox_t; 1098 #endif /* RT_USING_MAILBOX */ 1099 1100 /**@}*/ 1101 1102 /** 1103 * @addtogroup group_messagequeue Message Queue 1104 * @{ 1105 */ 1106 1107 #ifdef RT_USING_MESSAGEQUEUE 1108 /** 1109 * message queue structure 1110 */ 1111 struct rt_messagequeue 1112 { 1113 struct rt_ipc_object parent; /**< inherit from ipc_object */ 1114 1115 void *msg_pool; /**< start address of message queue */ 1116 1117 rt_uint16_t msg_size; /**< message size of each message */ 1118 rt_uint16_t max_msgs; /**< max number of messages */ 1119 1120 rt_uint16_t entry; /**< index of messages in the queue */ 1121 1122 void *msg_queue_head; /**< list head */ 1123 void *msg_queue_tail; /**< list tail */ 1124 void *msg_queue_free; /**< pointer indicated the free node of queue */ 1125 1126 rt_list_t suspend_sender_thread; /**< sender thread suspended on this message queue */ 1127 struct rt_spinlock spinlock; 1128 }; 1129 typedef struct rt_messagequeue *rt_mq_t; 1130 #endif /* RT_USING_MESSAGEQUEUE */ 1131 1132 /**@}*/ 1133 1134 /**@}*/ 1135 1136 /** 1137 * @addtogroup group_memory_management 1138 */ 1139 1140 /**@{*/ 1141 1142 #ifdef RT_USING_HEAP 1143 /* 1144 * memory structure 1145 */ 1146 struct rt_memory 1147 { 1148 struct rt_object parent; /**< inherit from rt_object */ 1149 const char * algorithm; /**< Memory management algorithm name */ 1150 rt_ubase_t address; /**< memory start address */ 1151 rt_size_t total; /**< memory size */ 1152 rt_size_t used; /**< size used */ 1153 rt_size_t max; /**< maximum usage */ 1154 }; 1155 typedef struct rt_memory *rt_mem_t; 1156 #endif /* RT_USING_HEAP */ 1157 1158 /* 1159 * memory management 1160 * heap & partition 1161 */ 1162 1163 #ifdef RT_USING_SMALL_MEM 1164 typedef rt_mem_t rt_smem_t; 1165 #endif /* RT_USING_SMALL_MEM */ 1166 1167 #ifdef RT_USING_SLAB 1168 typedef rt_mem_t rt_slab_t; 1169 #endif /* RT_USING_SLAB */ 1170 1171 #ifdef RT_USING_MEMHEAP 1172 /** 1173 * memory item on the heap 1174 */ 1175 struct rt_memheap_item 1176 { 1177 rt_uint32_t magic; /**< magic number for memheap */ 1178 struct rt_memheap *pool_ptr; /**< point of pool */ 1179 1180 struct rt_memheap_item *next; /**< next memheap item */ 1181 struct rt_memheap_item *prev; /**< prev memheap item */ 1182 1183 struct rt_memheap_item *next_free; /**< next free memheap item */ 1184 struct rt_memheap_item *prev_free; /**< prev free memheap item */ 1185 #ifdef RT_USING_MEMTRACE 1186 rt_uint8_t owner_thread_name[4]; /**< owner thread name */ 1187 #endif /* RT_USING_MEMTRACE */ 1188 }; 1189 1190 /** 1191 * Base structure of memory heap object 1192 */ 1193 struct rt_memheap 1194 { 1195 struct rt_object parent; /**< inherit from rt_object */ 1196 1197 void *start_addr; /**< pool start address and size */ 1198 1199 rt_size_t pool_size; /**< pool size */ 1200 rt_size_t available_size; /**< available size */ 1201 rt_size_t max_used_size; /**< maximum allocated size */ 1202 1203 struct rt_memheap_item *block_list; /**< used block list */ 1204 1205 struct rt_memheap_item *free_list; /**< free block list */ 1206 struct rt_memheap_item free_header; /**< free block list header */ 1207 1208 struct rt_semaphore lock; /**< semaphore lock */ 1209 rt_bool_t locked; /**< External lock mark */ 1210 }; 1211 #endif /* RT_USING_MEMHEAP */ 1212 1213 #ifdef RT_USING_MEMPOOL 1214 /** 1215 * Base structure of Memory pool object 1216 */ 1217 struct rt_mempool 1218 { 1219 struct rt_object parent; /**< inherit from rt_object */ 1220 1221 void *start_address; /**< memory pool start */ 1222 rt_size_t size; /**< size of memory pool */ 1223 1224 rt_size_t block_size; /**< size of memory blocks */ 1225 rt_uint8_t *block_list; /**< memory blocks list */ 1226 1227 rt_size_t block_total_count; /**< numbers of memory block */ 1228 rt_size_t block_free_count; /**< numbers of free memory block */ 1229 1230 rt_list_t suspend_thread; /**< threads pended on this resource */ 1231 struct rt_spinlock spinlock; 1232 }; 1233 typedef struct rt_mempool *rt_mp_t; 1234 #endif /* RT_USING_MEMPOOL */ 1235 1236 /**@}*/ 1237 1238 #ifdef RT_USING_DEVICE 1239 /** 1240 * @addtogroup group_device_driver 1241 */ 1242 1243 /**@{*/ 1244 1245 /** 1246 * device (I/O) class type 1247 */ 1248 enum rt_device_class_type 1249 { 1250 RT_Device_Class_Char = 0, /**< character device */ 1251 RT_Device_Class_Block, /**< block device */ 1252 RT_Device_Class_NetIf, /**< net interface */ 1253 RT_Device_Class_MTD, /**< memory device */ 1254 RT_Device_Class_CAN, /**< CAN device */ 1255 RT_Device_Class_RTC, /**< RTC device */ 1256 RT_Device_Class_Sound, /**< Sound device */ 1257 RT_Device_Class_Graphic, /**< Graphic device */ 1258 RT_Device_Class_I2CBUS, /**< I2C bus device */ 1259 RT_Device_Class_USBDevice, /**< USB slave device */ 1260 RT_Device_Class_USBHost, /**< USB host bus */ 1261 RT_Device_Class_USBOTG, /**< USB OTG bus */ 1262 RT_Device_Class_SPIBUS, /**< SPI bus device */ 1263 RT_Device_Class_SPIDevice, /**< SPI device */ 1264 RT_Device_Class_SDIO, /**< SDIO bus device */ 1265 RT_Device_Class_PM, /**< PM pseudo device */ 1266 RT_Device_Class_Pipe, /**< Pipe device */ 1267 RT_Device_Class_Portal, /**< Portal device */ 1268 RT_Device_Class_Timer, /**< Timer device */ 1269 RT_Device_Class_Miscellaneous, /**< Miscellaneous device */ 1270 RT_Device_Class_Sensor, /**< Sensor device */ 1271 RT_Device_Class_Touch, /**< Touch device */ 1272 RT_Device_Class_PHY, /**< PHY device */ 1273 RT_Device_Class_Security, /**< Security device */ 1274 RT_Device_Class_WLAN, /**< WLAN device */ 1275 RT_Device_Class_Pin, /**< Pin device */ 1276 RT_Device_Class_ADC, /**< ADC device */ 1277 RT_Device_Class_DAC, /**< DAC device */ 1278 RT_Device_Class_WDT, /**< WDT device */ 1279 RT_Device_Class_PWM, /**< PWM device */ 1280 RT_Device_Class_Bus, /**< Bus device */ 1281 RT_Device_Class_Unknown /**< unknown device */ 1282 }; 1283 1284 /** 1285 * device flags definitions 1286 */ 1287 #define RT_DEVICE_FLAG_DEACTIVATE 0x000 /**< device is not not initialized */ 1288 1289 #define RT_DEVICE_FLAG_RDONLY 0x001 /**< read only */ 1290 #define RT_DEVICE_FLAG_WRONLY 0x002 /**< write only */ 1291 #define RT_DEVICE_FLAG_RDWR 0x003 /**< read and write */ 1292 1293 #define RT_DEVICE_FLAG_REMOVABLE 0x004 /**< removable device */ 1294 #define RT_DEVICE_FLAG_STANDALONE 0x008 /**< standalone device */ 1295 #define RT_DEVICE_FLAG_ACTIVATED 0x010 /**< device is activated */ 1296 #define RT_DEVICE_FLAG_SUSPENDED 0x020 /**< device is suspended */ 1297 #define RT_DEVICE_FLAG_STREAM 0x040 /**< stream mode */ 1298 #define RT_DEVICE_FLAG_DYNAMIC 0x080 /**< device is determined when open() */ 1299 1300 #define RT_DEVICE_FLAG_INT_RX 0x100 /**< INT mode on Rx */ 1301 #define RT_DEVICE_FLAG_DMA_RX 0x200 /**< DMA mode on Rx */ 1302 #define RT_DEVICE_FLAG_INT_TX 0x400 /**< INT mode on Tx */ 1303 #define RT_DEVICE_FLAG_DMA_TX 0x800 /**< DMA mode on Tx */ 1304 1305 #define RT_DEVICE_OFLAG_CLOSE 0x000 /**< device is closed */ 1306 #define RT_DEVICE_OFLAG_RDONLY 0x001 /**< read only access */ 1307 #define RT_DEVICE_OFLAG_WRONLY 0x002 /**< write only access */ 1308 #define RT_DEVICE_OFLAG_RDWR 0x003 /**< read and write */ 1309 #define RT_DEVICE_OFLAG_OPEN 0x008 /**< device is opened */ 1310 #define RT_DEVICE_OFLAG_MASK 0xf0f /**< mask of open flag */ 1311 1312 /** 1313 * general device commands 1314 * 0x01 - 0x1F general device control commands 1315 * 0x20 - 0x3F udevice control commands 1316 * 0x40 - special device control commands 1317 */ 1318 #define RT_DEVICE_CTRL_RESUME 0x01 /**< resume device */ 1319 #define RT_DEVICE_CTRL_SUSPEND 0x02 /**< suspend device */ 1320 #define RT_DEVICE_CTRL_CONFIG 0x03 /**< configure device */ 1321 #define RT_DEVICE_CTRL_CLOSE 0x04 /**< close device */ 1322 #define RT_DEVICE_CTRL_NOTIFY_SET 0x05 /**< set notify func */ 1323 #define RT_DEVICE_CTRL_SET_INT 0x06 /**< set interrupt */ 1324 #define RT_DEVICE_CTRL_CLR_INT 0x07 /**< clear interrupt */ 1325 #define RT_DEVICE_CTRL_GET_INT 0x08 /**< get interrupt status */ 1326 #define RT_DEVICE_CTRL_CONSOLE_OFLAG 0x09 /**< get console open flag */ 1327 #define RT_DEVICE_CTRL_MASK 0x1f /**< mask for contrl commands */ 1328 1329 /** 1330 * device control 1331 */ 1332 #define RT_DEVICE_CTRL_BASE(Type) ((RT_Device_Class_##Type + 1) * 0x100) 1333 1334 typedef struct rt_driver *rt_driver_t; 1335 typedef struct rt_device *rt_device_t; 1336 1337 #ifdef RT_USING_DEVICE_OPS 1338 /** 1339 * operations set for device object 1340 */ 1341 struct rt_device_ops 1342 { 1343 /* common device interface */ 1344 rt_err_t (*init) (rt_device_t dev); 1345 rt_err_t (*open) (rt_device_t dev, rt_uint16_t oflag); 1346 rt_err_t (*close) (rt_device_t dev); 1347 rt_ssize_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size); 1348 rt_ssize_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size); 1349 rt_err_t (*control)(rt_device_t dev, int cmd, void *args); 1350 }; 1351 #endif /* RT_USING_DEVICE_OPS */ 1352 1353 /** 1354 * WaitQueue structure 1355 */ 1356 struct rt_wqueue 1357 { 1358 rt_uint32_t flag; 1359 rt_list_t waiting_list; 1360 struct rt_spinlock spinlock; 1361 }; 1362 typedef struct rt_wqueue rt_wqueue_t; 1363 1364 #ifdef RT_USING_DM 1365 struct rt_driver; 1366 struct rt_bus; 1367 #endif /* RT_USING_DM */ 1368 1369 /** 1370 * Device structure 1371 */ 1372 struct rt_device 1373 { 1374 struct rt_object parent; /**< inherit from rt_object */ 1375 1376 #ifdef RT_USING_DM 1377 struct rt_bus *bus; /**< the bus mounting to */ 1378 rt_list_t node; /**< to mount on bus */ 1379 struct rt_driver *drv; /**< driver for powering the device */ 1380 #ifdef RT_USING_OFW 1381 void *ofw_node; /**< ofw node get from device tree */ 1382 #endif /* RT_USING_OFW */ 1383 void *power_domain_unit; 1384 #ifdef RT_USING_DMA 1385 const void *dma_ops; 1386 #endif 1387 #endif /* RT_USING_DM */ 1388 1389 enum rt_device_class_type type; /**< device type */ 1390 rt_uint16_t flag; /**< device flag */ 1391 rt_uint16_t open_flag; /**< device open flag */ 1392 1393 rt_uint8_t ref_count; /**< reference count */ 1394 #ifdef RT_USING_DM 1395 rt_uint8_t master_id; /**< 0 - 255 */ 1396 #endif 1397 rt_uint8_t device_id; /**< 0 - 255 */ 1398 1399 /* device call back */ 1400 rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size); 1401 rt_err_t (*tx_complete)(rt_device_t dev, void *buffer); 1402 1403 #ifdef RT_USING_DEVICE_OPS 1404 const struct rt_device_ops *ops; 1405 #else 1406 /* common device interface */ 1407 rt_err_t (*init) (rt_device_t dev); 1408 rt_err_t (*open) (rt_device_t dev, rt_uint16_t oflag); 1409 rt_err_t (*close) (rt_device_t dev); 1410 rt_ssize_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size); 1411 rt_ssize_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size); 1412 rt_err_t (*control)(rt_device_t dev, int cmd, void *args); 1413 #endif /* RT_USING_DEVICE_OPS */ 1414 1415 #ifdef RT_USING_POSIX_DEVIO 1416 const struct dfs_file_ops *fops; 1417 struct rt_wqueue wait_queue; 1418 #endif /* RT_USING_POSIX_DEVIO */ 1419 1420 rt_err_t (*readlink) 1421 (rt_device_t dev, char *buf, int len); /**< for dynamic device */ 1422 1423 void *user_data; /**< device private data */ 1424 }; 1425 1426 /** 1427 * Notify structure 1428 */ 1429 struct rt_device_notify 1430 { 1431 void (*notify)(rt_device_t dev); 1432 struct rt_device *dev; 1433 }; 1434 1435 #ifdef RT_USING_SMART 1436 struct rt_channel 1437 { 1438 struct rt_ipc_object parent; /**< inherit from object */ 1439 struct rt_thread *reply; /**< the thread will be reply */ 1440 struct rt_spinlock slock; /**< spinlock of this channel */ 1441 rt_list_t wait_msg; /**< the wait queue of sender msg */ 1442 rt_list_t wait_thread; /**< the wait queue of sender thread */ 1443 rt_wqueue_t reader_queue; /**< channel poll queue */ 1444 rt_uint8_t stat; /**< the status of this channel */ 1445 rt_ubase_t ref; 1446 }; 1447 typedef struct rt_channel *rt_channel_t; 1448 #endif /* RT_USING_SMART */ 1449 1450 /**@}*/ 1451 #endif /* RT_USING_DEVICE */ 1452 1453 #ifdef __cplusplus 1454 } 1455 #endif 1456 1457 #ifdef __cplusplus 1458 /* RT-Thread definitions for C++ */ 1459 namespace rtthread { 1460 1461 enum TICK_WAIT { 1462 WAIT_NONE = 0, 1463 WAIT_FOREVER = -1, 1464 }; 1465 1466 } 1467 1468 #endif /* __cplusplus */ 1469 1470 #endif /* __RT_DEF_H__ */ 1471