first
This commit is contained in:
235
rt-thread/include/rtatomic.h
Normal file
235
rt-thread/include/rtatomic.h
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-03-14 WangShun first version
|
||||
* 2023-05-20 Bernard add stdc atomic detection.
|
||||
*/
|
||||
#ifndef __RT_ATOMIC_H__
|
||||
#define __RT_ATOMIC_H__
|
||||
|
||||
#include <rthw.h>
|
||||
|
||||
#if !defined(__cplusplus)
|
||||
|
||||
rt_atomic_t rt_hw_atomic_load(volatile rt_atomic_t *ptr);
|
||||
void rt_hw_atomic_store(volatile rt_atomic_t *ptr, rt_atomic_t val);
|
||||
rt_atomic_t rt_hw_atomic_add(volatile rt_atomic_t *ptr, rt_atomic_t val);
|
||||
rt_atomic_t rt_hw_atomic_sub(volatile rt_atomic_t *ptr, rt_atomic_t val);
|
||||
rt_atomic_t rt_hw_atomic_and(volatile rt_atomic_t *ptr, rt_atomic_t val);
|
||||
rt_atomic_t rt_hw_atomic_or(volatile rt_atomic_t *ptr, rt_atomic_t val);
|
||||
rt_atomic_t rt_hw_atomic_xor(volatile rt_atomic_t *ptr, rt_atomic_t val);
|
||||
rt_atomic_t rt_hw_atomic_exchange(volatile rt_atomic_t *ptr, rt_atomic_t val);
|
||||
void rt_hw_atomic_flag_clear(volatile rt_atomic_t *ptr);
|
||||
rt_atomic_t rt_hw_atomic_flag_test_and_set(volatile rt_atomic_t *ptr);
|
||||
rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_atomic_t *expected, rt_atomic_t desired);
|
||||
|
||||
#if defined(RT_USING_HW_ATOMIC)
|
||||
#define rt_atomic_load(ptr) rt_hw_atomic_load(ptr)
|
||||
#define rt_atomic_store(ptr, v) rt_hw_atomic_store(ptr, v)
|
||||
#define rt_atomic_add(ptr, v) rt_hw_atomic_add(ptr, v)
|
||||
#define rt_atomic_sub(ptr, v) rt_hw_atomic_sub(ptr, v)
|
||||
#define rt_atomic_and(ptr, v) rt_hw_atomic_and(ptr, v)
|
||||
#define rt_atomic_or(ptr, v) rt_hw_atomic_or(ptr, v)
|
||||
#define rt_atomic_xor(ptr, v) rt_hw_atomic_xor(ptr, v)
|
||||
#define rt_atomic_exchange(ptr, v) rt_hw_atomic_exchange(ptr, v)
|
||||
#define rt_atomic_flag_clear(ptr) rt_hw_atomic_flag_clear(ptr)
|
||||
#define rt_atomic_flag_test_and_set(ptr) rt_hw_atomic_flag_test_and_set(ptr)
|
||||
#define rt_atomic_compare_exchange_strong(ptr, v,des) rt_hw_atomic_compare_exchange_strong(ptr, v ,des)
|
||||
|
||||
#elif defined(RT_USING_STDC_ATOMIC)
|
||||
|
||||
#ifndef __STDC_NO_ATOMICS__
|
||||
#define rt_atomic_load(ptr) atomic_load(ptr)
|
||||
#define rt_atomic_store(ptr, v) atomic_store(ptr, v)
|
||||
#define rt_atomic_add(ptr, v) atomic_fetch_add(ptr, v)
|
||||
#define rt_atomic_sub(ptr, v) atomic_fetch_sub(ptr, v)
|
||||
#define rt_atomic_and(ptr, v) atomic_fetch_and(ptr, v)
|
||||
#define rt_atomic_or(ptr, v) atomic_fetch_or(ptr, v)
|
||||
#define rt_atomic_xor(ptr, v) atomic_fetch_xor(ptr, v)
|
||||
#define rt_atomic_exchange(ptr, v) atomic_exchange(ptr, v)
|
||||
#define rt_atomic_flag_clear(ptr) atomic_flag_clear(ptr)
|
||||
#define rt_atomic_flag_test_and_set(ptr) atomic_flag_test_and_set(ptr)
|
||||
#define rt_atomic_compare_exchange_strong(ptr, v,des) atomic_compare_exchange_strong(ptr, v ,des)
|
||||
#else
|
||||
#error "The standard library C doesn't support the atomic operation"
|
||||
#endif /* __STDC_NO_ATOMICS__ */
|
||||
|
||||
#else
|
||||
#include <rthw.h>
|
||||
#define rt_atomic_load(ptr) rt_soft_atomic_load(ptr)
|
||||
#define rt_atomic_store(ptr, v) rt_soft_atomic_store(ptr, v)
|
||||
#define rt_atomic_add(ptr, v) rt_soft_atomic_add(ptr, v)
|
||||
#define rt_atomic_sub(ptr, v) rt_soft_atomic_sub(ptr, v)
|
||||
#define rt_atomic_and(ptr, v) rt_soft_atomic_and(ptr, v)
|
||||
#define rt_atomic_or(ptr, v) rt_soft_atomic_or(ptr, v)
|
||||
#define rt_atomic_xor(ptr, v) rt_soft_atomic_xor(ptr, v)
|
||||
#define rt_atomic_exchange(ptr, v) rt_soft_atomic_exchange(ptr, v)
|
||||
#define rt_atomic_flag_clear(ptr) rt_soft_atomic_flag_clear(ptr)
|
||||
#define rt_atomic_flag_test_and_set(ptr) rt_soft_atomic_flag_test_and_set(ptr)
|
||||
#define rt_atomic_compare_exchange_strong(ptr, v,des) rt_soft_atomic_compare_exchange_strong(ptr, v ,des)
|
||||
|
||||
rt_inline rt_atomic_t rt_soft_atomic_exchange(volatile rt_atomic_t *ptr, rt_atomic_t val)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_atomic_t temp;
|
||||
level = rt_hw_interrupt_disable();
|
||||
temp = *ptr;
|
||||
*ptr = val;
|
||||
rt_hw_interrupt_enable(level);
|
||||
return temp;
|
||||
}
|
||||
|
||||
rt_inline rt_atomic_t rt_soft_atomic_add(volatile rt_atomic_t *ptr, rt_atomic_t val)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_atomic_t temp;
|
||||
level = rt_hw_interrupt_disable();
|
||||
temp = *ptr;
|
||||
*ptr += val;
|
||||
rt_hw_interrupt_enable(level);
|
||||
return temp;
|
||||
}
|
||||
|
||||
rt_inline rt_atomic_t rt_soft_atomic_sub(volatile rt_atomic_t *ptr, rt_atomic_t val)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_atomic_t temp;
|
||||
level = rt_hw_interrupt_disable();
|
||||
temp = *ptr;
|
||||
*ptr -= val;
|
||||
rt_hw_interrupt_enable(level);
|
||||
return temp;
|
||||
}
|
||||
|
||||
rt_inline rt_atomic_t rt_soft_atomic_xor(volatile rt_atomic_t *ptr, rt_atomic_t val)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_atomic_t temp;
|
||||
level = rt_hw_interrupt_disable();
|
||||
temp = *ptr;
|
||||
*ptr = (*ptr) ^ val;
|
||||
rt_hw_interrupt_enable(level);
|
||||
return temp;
|
||||
}
|
||||
|
||||
rt_inline rt_atomic_t rt_soft_atomic_and(volatile rt_atomic_t *ptr, rt_atomic_t val)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_atomic_t temp;
|
||||
level = rt_hw_interrupt_disable();
|
||||
temp = *ptr;
|
||||
*ptr = (*ptr) & val;
|
||||
rt_hw_interrupt_enable(level);
|
||||
return temp;
|
||||
}
|
||||
|
||||
rt_inline rt_atomic_t rt_soft_atomic_or(volatile rt_atomic_t *ptr, rt_atomic_t val)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_atomic_t temp;
|
||||
level = rt_hw_interrupt_disable();
|
||||
temp = *ptr;
|
||||
*ptr = (*ptr) | val;
|
||||
rt_hw_interrupt_enable(level);
|
||||
return temp;
|
||||
}
|
||||
|
||||
rt_inline rt_atomic_t rt_soft_atomic_load(volatile rt_atomic_t *ptr)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_atomic_t temp;
|
||||
level = rt_hw_interrupt_disable();
|
||||
temp = *ptr;
|
||||
rt_hw_interrupt_enable(level);
|
||||
return temp;
|
||||
}
|
||||
|
||||
rt_inline void rt_soft_atomic_store(volatile rt_atomic_t *ptr, rt_atomic_t val)
|
||||
{
|
||||
rt_base_t level;
|
||||
level = rt_hw_interrupt_disable();
|
||||
*ptr = val;
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
|
||||
rt_inline rt_atomic_t rt_soft_atomic_flag_test_and_set(volatile rt_atomic_t *ptr)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_atomic_t temp;
|
||||
level = rt_hw_interrupt_disable();
|
||||
if (*ptr == 0)
|
||||
{
|
||||
temp = 0;
|
||||
*ptr = 1;
|
||||
}
|
||||
else
|
||||
temp = 1;
|
||||
rt_hw_interrupt_enable(level);
|
||||
return temp;
|
||||
}
|
||||
|
||||
rt_inline void rt_soft_atomic_flag_clear(volatile rt_atomic_t *ptr)
|
||||
{
|
||||
rt_base_t level;
|
||||
level = rt_hw_interrupt_disable();
|
||||
*ptr = 0;
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
|
||||
rt_inline rt_atomic_t rt_soft_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr1, rt_atomic_t *ptr2,
|
||||
rt_atomic_t desired)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_atomic_t temp;
|
||||
level = rt_hw_interrupt_disable();
|
||||
if ((*ptr1) != (*ptr2))
|
||||
{
|
||||
*ptr2 = *ptr1;
|
||||
temp = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr1 = desired;
|
||||
temp = 1;
|
||||
}
|
||||
rt_hw_interrupt_enable(level);
|
||||
return temp;
|
||||
}
|
||||
#endif /* RT_USING_STDC_ATOMIC */
|
||||
|
||||
rt_inline rt_bool_t rt_atomic_dec_and_test(volatile rt_atomic_t *ptr)
|
||||
{
|
||||
return rt_atomic_sub(ptr, 1) == 0;
|
||||
}
|
||||
|
||||
rt_inline rt_atomic_t rt_atomic_fetch_add_unless(volatile rt_atomic_t *ptr, rt_atomic_t a, rt_atomic_t u)
|
||||
{
|
||||
rt_atomic_t c = rt_atomic_load(ptr);
|
||||
|
||||
do {
|
||||
if (c == u)
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (!rt_atomic_compare_exchange_strong(ptr, &c, c + a));
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
rt_inline rt_bool_t rt_atomic_add_unless(volatile rt_atomic_t *ptr, rt_atomic_t a, rt_atomic_t u)
|
||||
{
|
||||
return rt_atomic_fetch_add_unless(ptr, a, u) != u;
|
||||
}
|
||||
|
||||
rt_inline rt_bool_t rt_atomic_inc_not_zero(volatile rt_atomic_t *ptr)
|
||||
{
|
||||
return rt_atomic_add_unless(ptr, 1, 0);
|
||||
}
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __RT_ATOMIC_H__ */
|
100
rt-thread/include/rtcompiler.h
Normal file
100
rt-thread/include/rtcompiler.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2024-01-18 Shell Separate the compiler porting from rtdef.h
|
||||
*/
|
||||
#ifndef __RT_COMPILER_H__
|
||||
#define __RT_COMPILER_H__
|
||||
|
||||
#include <rtconfig.h>
|
||||
|
||||
#if defined(__ARMCC_VERSION) /* ARM Compiler */
|
||||
#define rt_section(x) __attribute__((section(x)))
|
||||
#define rt_used __attribute__((used))
|
||||
#define rt_align(n) __attribute__((aligned(n)))
|
||||
#define rt_weak __attribute__((weak))
|
||||
#define rt_typeof typeof
|
||||
#define rt_noreturn
|
||||
#define rt_inline static __inline
|
||||
#define rt_always_inline rt_inline
|
||||
#elif defined (__IAR_SYSTEMS_ICC__) /* for IAR Compiler */
|
||||
#define rt_section(x) @ x
|
||||
#define rt_used __root
|
||||
#define PRAGMA(x) _Pragma(#x)
|
||||
#define rt_align(n) PRAGMA(data_alignment=n)
|
||||
#define rt_weak __weak
|
||||
#define rt_typeof __typeof
|
||||
#define rt_noreturn
|
||||
#define rt_inline static inline
|
||||
#define rt_always_inline rt_inline
|
||||
#elif defined (__GNUC__) /* GNU GCC Compiler */
|
||||
#define __RT_STRINGIFY(x...) #x
|
||||
#define RT_STRINGIFY(x...) __RT_STRINGIFY(x)
|
||||
#define rt_section(x) __attribute__((section(x)))
|
||||
#define rt_used __attribute__((used))
|
||||
#define rt_align(n) __attribute__((aligned(n)))
|
||||
#define rt_weak __attribute__((weak))
|
||||
#define rt_typeof __typeof__
|
||||
#define rt_noreturn __attribute__ ((noreturn))
|
||||
#define rt_inline static __inline
|
||||
#define rt_always_inline static inline __attribute__((always_inline))
|
||||
#elif defined (__ADSPBLACKFIN__) /* for VisualDSP++ Compiler */
|
||||
#define rt_section(x) __attribute__((section(x)))
|
||||
#define rt_used __attribute__((used))
|
||||
#define rt_align(n) __attribute__((aligned(n)))
|
||||
#define rt_weak __attribute__((weak))
|
||||
#define rt_typeof typeof
|
||||
#define rt_noreturn
|
||||
#define rt_inline static inline
|
||||
#define rt_always_inline rt_inline
|
||||
#elif defined (_MSC_VER) /* for Visual Studio Compiler */
|
||||
#define rt_section(x)
|
||||
#define rt_used
|
||||
#define rt_align(n) __declspec(align(n))
|
||||
#define rt_weak
|
||||
#define rt_typeof typeof
|
||||
#define rt_noreturn
|
||||
#define rt_inline static __inline
|
||||
#define rt_always_inline rt_inline
|
||||
#elif defined (__TI_COMPILER_VERSION__) /* for TI CCS Compiler */
|
||||
/**
|
||||
* The way that TI compiler set section is different from other(at least
|
||||
* GCC and MDK) compilers. See ARM Optimizing C/C++ Compiler 5.9.3 for more
|
||||
* details.
|
||||
*/
|
||||
#define rt_section(x) __attribute__((section(x)))
|
||||
#ifdef __TI_EABI__
|
||||
#define rt_used __attribute__((retain)) __attribute__((used))
|
||||
#else
|
||||
#define rt_used __attribute__((used))
|
||||
#endif
|
||||
#define PRAGMA(x) _Pragma(#x)
|
||||
#define rt_align(n) __attribute__((aligned(n)))
|
||||
#ifdef __TI_EABI__
|
||||
#define rt_weak __attribute__((weak))
|
||||
#else
|
||||
#define rt_weak
|
||||
#endif
|
||||
#define rt_typeof typeof
|
||||
#define rt_noreturn
|
||||
#define rt_inline static inline
|
||||
#define rt_always_inline rt_inline
|
||||
#elif defined (__TASKING__) /* for TASKING Compiler */
|
||||
#define rt_section(x) __attribute__((section(x)))
|
||||
#define rt_used __attribute__((used, protect))
|
||||
#define PRAGMA(x) _Pragma(#x)
|
||||
#define rt_align(n) __attribute__((__align(n)))
|
||||
#define rt_weak __attribute__((weak))
|
||||
#define rt_typeof typeof
|
||||
#define rt_noreturn
|
||||
#define rt_inline static inline
|
||||
#define rt_always_inline rt_inline
|
||||
#else /* Unkown Compiler */
|
||||
#error not supported tool chain
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
#endif /* __RT_COMPILER_H__ */
|
196
rt-thread/include/rtdbg.h
Normal file
196
rt-thread/include/rtdbg.h
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016-11-12 Bernard The first version
|
||||
* 2018-05-25 armink Add simple API, such as LOG_D, LOG_E
|
||||
*/
|
||||
|
||||
/*
|
||||
* The macro definitions for debug
|
||||
*
|
||||
* These macros are defined in static. If you want to use debug macro, you can
|
||||
* use as following code:
|
||||
*
|
||||
* In your C/C++ file, enable/disable DEBUG_ENABLE macro, and then include this
|
||||
* header file.
|
||||
*
|
||||
* #define DBG_TAG "MOD_TAG"
|
||||
* #define DBG_LVL DBG_INFO
|
||||
* #include <rtdbg.h> // must after of DBG_LVL, DBG_TAG or other options
|
||||
*
|
||||
* Then in your C/C++ file, you can use LOG_X macro to print out logs:
|
||||
* LOG_D("this is a debug log!");
|
||||
* LOG_E("this is a error log!");
|
||||
*/
|
||||
|
||||
#ifndef RT_DBG_H__
|
||||
#define RT_DBG_H__
|
||||
|
||||
#include <rtconfig.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* the debug log will force enable when RT_USING_DEBUG macro is defined */
|
||||
#if defined(RT_USING_DEBUG) && !defined(DBG_ENABLE)
|
||||
#define DBG_ENABLE
|
||||
#endif
|
||||
|
||||
/* it will force output color log when RT_DEBUGING_COLOR macro is defined */
|
||||
#if defined(RT_DEBUGING_COLOR) && !defined(DBG_COLOR)
|
||||
#define DBG_COLOR
|
||||
#endif
|
||||
|
||||
/* for dlog */
|
||||
#ifdef PKG_USING_DLOG
|
||||
#include <dlog.h>
|
||||
#else
|
||||
#define DLOG(...)
|
||||
#endif
|
||||
|
||||
#if defined(RT_USING_ULOG)
|
||||
/* using ulog compatible with rtdbg */
|
||||
#include <ulog.h>
|
||||
#else
|
||||
|
||||
/* DEBUG level */
|
||||
#define DBG_ERROR 0
|
||||
#define DBG_WARNING 1
|
||||
#define DBG_INFO 2
|
||||
#define DBG_LOG 3
|
||||
|
||||
#ifdef DBG_TAG
|
||||
#ifndef DBG_SECTION_NAME
|
||||
#define DBG_SECTION_NAME DBG_TAG
|
||||
#endif
|
||||
#else
|
||||
/* compatible with old version */
|
||||
#ifndef DBG_SECTION_NAME
|
||||
#define DBG_SECTION_NAME "DBG"
|
||||
#endif
|
||||
#endif /* DBG_TAG */
|
||||
|
||||
#ifdef DBG_ENABLE
|
||||
|
||||
#ifdef DBG_LVL
|
||||
#ifndef DBG_LEVEL
|
||||
#define DBG_LEVEL DBG_LVL
|
||||
#endif
|
||||
#else
|
||||
/* compatible with old version */
|
||||
#ifndef DBG_LEVEL
|
||||
#define DBG_LEVEL DBG_WARNING
|
||||
#endif
|
||||
#endif /* DBG_LVL */
|
||||
|
||||
/*
|
||||
* The color for terminal (foreground)
|
||||
* BLACK 30
|
||||
* RED 31
|
||||
* GREEN 32
|
||||
* YELLOW 33
|
||||
* BLUE 34
|
||||
* PURPLE 35
|
||||
* CYAN 36
|
||||
* WHITE 37
|
||||
*/
|
||||
#ifdef DBG_COLOR
|
||||
#define _DBG_COLOR(n) rt_kprintf("\033["#n"m")
|
||||
#define _DBG_LOG_HDR(lvl_name, color_n) \
|
||||
rt_kprintf("\033["#color_n"m[" lvl_name "/" DBG_SECTION_NAME "] ")
|
||||
#define _DBG_LOG_X_END \
|
||||
rt_kprintf("\033[0m\n")
|
||||
#else
|
||||
#define _DBG_COLOR(n)
|
||||
#define _DBG_LOG_HDR(lvl_name, color_n) \
|
||||
rt_kprintf("[" lvl_name "/" DBG_SECTION_NAME "] ")
|
||||
#define _DBG_LOG_X_END \
|
||||
rt_kprintf("\n")
|
||||
#endif /* DBG_COLOR */
|
||||
|
||||
/*
|
||||
* static debug routine
|
||||
* NOTE: This is a NOT RECOMMENDED API. Please using LOG_X API.
|
||||
* It will be DISCARDED later. Because it will take up more resources.
|
||||
*/
|
||||
#define dbg_log(level, fmt, ...) \
|
||||
if ((level) <= DBG_LEVEL) \
|
||||
{ \
|
||||
switch(level) \
|
||||
{ \
|
||||
case DBG_ERROR: _DBG_LOG_HDR("E", 31); break; \
|
||||
case DBG_WARNING: _DBG_LOG_HDR("W", 33); break; \
|
||||
case DBG_INFO: _DBG_LOG_HDR("I", 32); break; \
|
||||
case DBG_LOG: _DBG_LOG_HDR("D", 0); break; \
|
||||
default: break; \
|
||||
} \
|
||||
rt_kprintf(fmt, ##__VA_ARGS__); \
|
||||
_DBG_COLOR(0); \
|
||||
}
|
||||
|
||||
#define dbg_here \
|
||||
if ((DBG_LEVEL) <= DBG_LOG){ \
|
||||
rt_kprintf(DBG_SECTION_NAME " Here %s:%d\n", \
|
||||
__FUNCTION__, __LINE__); \
|
||||
}
|
||||
|
||||
#define dbg_log_line(lvl, color_n, fmt, ...) \
|
||||
do \
|
||||
{ \
|
||||
_DBG_LOG_HDR(lvl, color_n); \
|
||||
rt_kprintf(fmt, ##__VA_ARGS__); \
|
||||
_DBG_LOG_X_END; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define dbg_raw(...) rt_kprintf(__VA_ARGS__);
|
||||
|
||||
#else
|
||||
#define dbg_log(level, fmt, ...)
|
||||
#define dbg_here
|
||||
#define dbg_enter
|
||||
#define dbg_exit
|
||||
#define dbg_log_line(lvl, color_n, fmt, ...)
|
||||
#define dbg_raw(...)
|
||||
#endif /* DBG_ENABLE */
|
||||
|
||||
#if (DBG_LEVEL >= DBG_LOG)
|
||||
#define LOG_D(fmt, ...) dbg_log_line("D", 0, fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define LOG_D(...)
|
||||
#endif
|
||||
|
||||
#if (DBG_LEVEL >= DBG_INFO)
|
||||
#define LOG_I(fmt, ...) dbg_log_line("I", 32, fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define LOG_I(...)
|
||||
#endif
|
||||
|
||||
#if (DBG_LEVEL >= DBG_WARNING)
|
||||
#define LOG_W(fmt, ...) dbg_log_line("W", 33, fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define LOG_W(...)
|
||||
#endif
|
||||
|
||||
#if (DBG_LEVEL >= DBG_ERROR)
|
||||
#define LOG_E(fmt, ...) dbg_log_line("E", 31, fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define LOG_E(...)
|
||||
#endif
|
||||
|
||||
#define LOG_RAW(...) dbg_raw(__VA_ARGS__)
|
||||
|
||||
#define LOG_HEX(name, width, buf, size)
|
||||
|
||||
#endif /* defined(RT_USING_ULOG) && define(DBG_ENABLE) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RT_DBG_H__ */
|
1495
rt-thread/include/rtdef.h
Normal file
1495
rt-thread/include/rtdef.h
Normal file
File diff suppressed because it is too large
Load Diff
251
rt-thread/include/rthw.h
Normal file
251
rt-thread/include/rthw.h
Normal file
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-03-18 Bernard the first version
|
||||
* 2006-04-25 Bernard add rt_hw_context_switch_interrupt declaration
|
||||
* 2006-09-24 Bernard add rt_hw_context_switch_to declaration
|
||||
* 2012-12-29 Bernard add rt_hw_exception_install declaration
|
||||
* 2017-10-17 Hichard add some macros
|
||||
* 2018-11-17 Jesven add rt_hw_spinlock_t
|
||||
* add smp support
|
||||
* 2019-05-18 Bernard add empty definition for not enable cache case
|
||||
* 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
|
||||
* 2023-10-16 Shell Support a new backtrace framework
|
||||
*/
|
||||
|
||||
#ifndef __RT_HW_H__
|
||||
#define __RT_HW_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
#if defined (RT_USING_CACHE) || defined(RT_USING_SMP) || defined(RT_HW_INCLUDE_CPUPORT)
|
||||
#include <cpuport.h> /* include spinlock, cache ops, etc. */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some macros define
|
||||
*/
|
||||
#ifndef HWREG64
|
||||
#define HWREG64(x) (*((volatile rt_uint64_t *)(x)))
|
||||
#endif
|
||||
#ifndef HWREG32
|
||||
#define HWREG32(x) (*((volatile rt_uint32_t *)(x)))
|
||||
#endif
|
||||
#ifndef HWREG16
|
||||
#define HWREG16(x) (*((volatile rt_uint16_t *)(x)))
|
||||
#endif
|
||||
#ifndef HWREG8
|
||||
#define HWREG8(x) (*((volatile rt_uint8_t *)(x)))
|
||||
#endif
|
||||
|
||||
#ifndef RT_CPU_CACHE_LINE_SZ
|
||||
#define RT_CPU_CACHE_LINE_SZ 32
|
||||
#endif
|
||||
|
||||
enum RT_HW_CACHE_OPS
|
||||
{
|
||||
RT_HW_CACHE_FLUSH = 0x01,
|
||||
RT_HW_CACHE_INVALIDATE = 0x02,
|
||||
};
|
||||
|
||||
/*
|
||||
* CPU interfaces
|
||||
*/
|
||||
#ifdef RT_USING_CACHE
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
#include <cache.h>
|
||||
#endif
|
||||
|
||||
void rt_hw_cpu_icache_enable(void);
|
||||
void rt_hw_cpu_icache_disable(void);
|
||||
rt_base_t rt_hw_cpu_icache_status(void);
|
||||
void rt_hw_cpu_icache_ops(int ops, void* addr, int size);
|
||||
|
||||
void rt_hw_cpu_dcache_enable(void);
|
||||
void rt_hw_cpu_dcache_disable(void);
|
||||
rt_base_t rt_hw_cpu_dcache_status(void);
|
||||
void rt_hw_cpu_dcache_ops(int ops, void* addr, int size);
|
||||
#else
|
||||
|
||||
/* define cache ops as empty */
|
||||
#define rt_hw_cpu_icache_enable(...)
|
||||
#define rt_hw_cpu_icache_disable(...)
|
||||
#define rt_hw_cpu_icache_ops(...)
|
||||
#define rt_hw_cpu_dcache_enable(...)
|
||||
#define rt_hw_cpu_dcache_disable(...)
|
||||
#define rt_hw_cpu_dcache_ops(...)
|
||||
|
||||
#define rt_hw_cpu_icache_status(...) 0
|
||||
#define rt_hw_cpu_dcache_status(...) 0
|
||||
|
||||
#endif
|
||||
|
||||
void rt_hw_cpu_reset(void);
|
||||
void rt_hw_cpu_shutdown(void);
|
||||
|
||||
const char *rt_hw_cpu_arch(void);
|
||||
|
||||
rt_uint8_t *rt_hw_stack_init(void *entry,
|
||||
void *parameter,
|
||||
rt_uint8_t *stack_addr,
|
||||
void *exit);
|
||||
|
||||
#ifdef RT_USING_HW_STACK_GUARD
|
||||
void rt_hw_stack_guard_init(rt_thread_t thread);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Interrupt handler definition
|
||||
*/
|
||||
typedef void (*rt_isr_handler_t)(int vector, void *param);
|
||||
|
||||
struct rt_irq_desc
|
||||
{
|
||||
rt_isr_handler_t handler;
|
||||
void *param;
|
||||
|
||||
#ifdef RT_USING_INTERRUPT_INFO
|
||||
char name[RT_NAME_MAX];
|
||||
rt_uint32_t counter;
|
||||
#ifdef RT_USING_SMP
|
||||
rt_ubase_t cpu_counter[RT_CPUS_NR];
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* Interrupt interfaces
|
||||
*/
|
||||
void rt_hw_interrupt_init(void);
|
||||
void rt_hw_interrupt_mask(int vector);
|
||||
void rt_hw_interrupt_umask(int vector);
|
||||
rt_isr_handler_t rt_hw_interrupt_install(int vector,
|
||||
rt_isr_handler_t handler,
|
||||
void *param,
|
||||
const char *name);
|
||||
void rt_hw_interrupt_uninstall(int vector,
|
||||
rt_isr_handler_t handler,
|
||||
void *param);
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
rt_base_t rt_hw_local_irq_disable(void);
|
||||
void rt_hw_local_irq_enable(rt_base_t level);
|
||||
|
||||
rt_base_t rt_cpus_lock(void);
|
||||
void rt_cpus_unlock(rt_base_t level);
|
||||
|
||||
#define rt_hw_interrupt_disable rt_cpus_lock
|
||||
#define rt_hw_interrupt_enable rt_cpus_unlock
|
||||
#else
|
||||
rt_base_t rt_hw_interrupt_disable(void);
|
||||
void rt_hw_interrupt_enable(rt_base_t level);
|
||||
|
||||
#define rt_hw_local_irq_disable rt_hw_interrupt_disable
|
||||
#define rt_hw_local_irq_enable rt_hw_interrupt_enable
|
||||
|
||||
#endif /*RT_USING_SMP*/
|
||||
rt_bool_t rt_hw_interrupt_is_disabled(void);
|
||||
|
||||
/*
|
||||
* Context interfaces
|
||||
*/
|
||||
#ifdef RT_USING_SMP
|
||||
void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread);
|
||||
void rt_hw_context_switch_to(rt_ubase_t to, struct rt_thread *to_thread);
|
||||
void rt_hw_context_switch_interrupt(void *context, rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread);
|
||||
#else
|
||||
void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
|
||||
void rt_hw_context_switch_to(rt_ubase_t to);
|
||||
void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to, rt_thread_t from_thread, rt_thread_t to_thread);
|
||||
#endif /*RT_USING_SMP*/
|
||||
|
||||
/**
|
||||
* Hardware Layer Backtrace Service
|
||||
*/
|
||||
struct rt_hw_backtrace_frame {
|
||||
rt_base_t fp;
|
||||
rt_base_t pc;
|
||||
};
|
||||
|
||||
rt_err_t rt_hw_backtrace_frame_get(rt_thread_t thread, struct rt_hw_backtrace_frame *frame);
|
||||
|
||||
rt_err_t rt_hw_backtrace_frame_unwind(rt_thread_t thread, struct rt_hw_backtrace_frame *frame);
|
||||
|
||||
void rt_hw_console_output(const char *str);
|
||||
|
||||
void rt_hw_show_memory(rt_uint32_t addr, rt_size_t size);
|
||||
|
||||
/*
|
||||
* Exception interfaces
|
||||
*/
|
||||
void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context));
|
||||
|
||||
/*
|
||||
* delay interfaces
|
||||
*/
|
||||
void rt_hw_us_delay(rt_uint32_t us);
|
||||
|
||||
int rt_hw_cpu_id(void);
|
||||
|
||||
#if defined(RT_USING_SMP) || defined(RT_USING_AMP)
|
||||
/**
|
||||
* ipi function
|
||||
*/
|
||||
void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
|
||||
void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock);
|
||||
void rt_hw_spin_lock(rt_hw_spinlock_t *lock);
|
||||
void rt_hw_spin_unlock(rt_hw_spinlock_t *lock);
|
||||
|
||||
extern rt_hw_spinlock_t _cpus_lock;
|
||||
|
||||
#define __RT_HW_SPIN_LOCK_INITIALIZER(lockname) {0}
|
||||
|
||||
#define __RT_HW_SPIN_LOCK_UNLOCKED(lockname) \
|
||||
(rt_hw_spinlock_t) __RT_HW_SPIN_LOCK_INITIALIZER(lockname)
|
||||
|
||||
#define RT_DEFINE_HW_SPINLOCK(x) rt_hw_spinlock_t x = __RT_HW_SPIN_LOCK_UNLOCKED(x)
|
||||
|
||||
/**
|
||||
* boot secondary cpu
|
||||
*/
|
||||
void rt_hw_secondary_cpu_up(void);
|
||||
|
||||
/**
|
||||
* secondary cpu idle function
|
||||
*/
|
||||
void rt_hw_secondary_cpu_idle_exec(void);
|
||||
|
||||
#else /* !RT_USING_SMP */
|
||||
|
||||
#define RT_DEFINE_HW_SPINLOCK(x) rt_ubase_t x
|
||||
|
||||
#define rt_hw_spin_lock(lock) *(lock) = rt_hw_interrupt_disable()
|
||||
#define rt_hw_spin_unlock(lock) rt_hw_interrupt_enable(*(lock))
|
||||
|
||||
|
||||
#endif /* RT_USING_SMP */
|
||||
|
||||
#ifndef RT_USING_CACHE
|
||||
#define rt_hw_isb()
|
||||
#define rt_hw_dmb()
|
||||
#define rt_hw_dsb()
|
||||
#endif /* RT_USING_CACHE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
57
rt-thread/include/rtklibc.h
Normal file
57
rt-thread/include/rtklibc.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2024-03-10 Meco Man the first version
|
||||
*/
|
||||
|
||||
#ifndef __RT_KLIBC_H__
|
||||
#define __RT_KLIBC_H__
|
||||
|
||||
#include <rtconfig.h>
|
||||
#include <rtdef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* kstdio */
|
||||
int rt_vsprintf(char *dest, const char *format, va_list arg_ptr);
|
||||
int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args);
|
||||
int rt_sprintf(char *buf, const char *format, ...);
|
||||
int rt_snprintf(char *buf, rt_size_t size, const char *format, ...);
|
||||
|
||||
rt_err_t rt_get_errno(void);
|
||||
void rt_set_errno(rt_err_t no);
|
||||
int *_rt_errno(void);
|
||||
const char *rt_strerror(rt_err_t error);
|
||||
#if !defined(RT_USING_NEWLIBC) && !defined(_WIN32)
|
||||
#ifndef errno
|
||||
#define errno *_rt_errno()
|
||||
#endif
|
||||
#endif /* !defined(RT_USING_NEWLIBC) && !defined(_WIN32) */
|
||||
|
||||
/* kstring */
|
||||
|
||||
void *rt_memset(void *src, int c, rt_ubase_t n);
|
||||
void *rt_memcpy(void *dest, const void *src, rt_ubase_t n);
|
||||
void *rt_memmove(void *dest, const void *src, rt_size_t n);
|
||||
rt_int32_t rt_memcmp(const void *cs, const void *ct, rt_size_t count);
|
||||
char *rt_strdup(const char *s);
|
||||
rt_size_t rt_strnlen(const char *s, rt_ubase_t maxlen);
|
||||
char *rt_strstr(const char *str1, const char *str2);
|
||||
rt_int32_t rt_strcasecmp(const char *a, const char *b);
|
||||
char *rt_strcpy(char *dst, const char *src);
|
||||
char *rt_strncpy(char *dest, const char *src, rt_size_t n);
|
||||
rt_int32_t rt_strncmp(const char *cs, const char *ct, rt_size_t count);
|
||||
rt_int32_t rt_strcmp(const char *cs, const char *ct);
|
||||
rt_size_t rt_strlen(const char *src);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __RT_KLIBC_H__ */
|
46
rt-thread/include/rtm.h
Normal file
46
rt-thread/include/rtm.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
|
||||
#ifndef __RTM_H__
|
||||
#define __RTM_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef RT_USING_MODULE
|
||||
struct rt_module_symtab
|
||||
{
|
||||
void *addr;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma section("RTMSymTab$f",read)
|
||||
#define RTM_EXPORT(symbol) \
|
||||
__declspec(allocate("RTMSymTab$f"))const char __rtmsym_##symbol##_name[] = "__vs_rtm_"#symbol;
|
||||
#pragma comment(linker, "/merge:RTMSymTab=mytext")
|
||||
|
||||
#elif defined(__MINGW32__)
|
||||
#define RTM_EXPORT(symbol)
|
||||
|
||||
#else
|
||||
#define RTM_EXPORT(symbol) \
|
||||
const char __rtmsym_##symbol##_name[] rt_section(".rodata.name") = #symbol; \
|
||||
const struct rt_module_symtab __rtmsym_##symbol rt_section("RTMSymTab")= \
|
||||
{ \
|
||||
(void *)&symbol, \
|
||||
__rtmsym_##symbol##_name \
|
||||
};
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define RTM_EXPORT(symbol)
|
||||
#endif
|
||||
|
||||
#endif
|
185
rt-thread/include/rtsched.h
Normal file
185
rt-thread/include/rtsched.h
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2024, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2024-01-19 Shell Seperate schduling statements from rt_thread_t
|
||||
* to rt_sched_thread_ctx. Add definitions of scheduler.
|
||||
*/
|
||||
#ifndef __RT_SCHED_H__
|
||||
#define __RT_SCHED_H__
|
||||
|
||||
#include "rttypes.h"
|
||||
#include "rtcompiler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct rt_thread;
|
||||
|
||||
typedef rt_uint8_t rt_sched_thread_status_t;
|
||||
|
||||
#ifdef RT_USING_SCHED_THREAD_CTX
|
||||
|
||||
/**
|
||||
* Scheduler private status binding on thread. Caller should never accessing
|
||||
* these members.
|
||||
*/
|
||||
struct rt_sched_thread_priv
|
||||
{
|
||||
rt_tick_t init_tick; /**< thread's initialized tick */
|
||||
rt_tick_t remaining_tick; /**< remaining tick */
|
||||
|
||||
/* priority */
|
||||
rt_uint8_t current_priority; /**< current priority */
|
||||
rt_uint8_t init_priority; /**< initialized priority */
|
||||
#if RT_THREAD_PRIORITY_MAX > 32
|
||||
rt_uint8_t number; /**< priority low number */
|
||||
rt_uint8_t high_mask; /**< priority high mask */
|
||||
#endif /* RT_THREAD_PRIORITY_MAX > 32 */
|
||||
rt_uint32_t number_mask; /**< priority number mask */
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Scheduler public status binding on thread. Caller must hold the scheduler
|
||||
* lock before access any one of its member.
|
||||
*/
|
||||
struct rt_sched_thread_ctx
|
||||
{
|
||||
rt_list_t thread_list_node; /**< node in thread list */
|
||||
|
||||
rt_uint8_t stat; /**< thread status */
|
||||
rt_uint8_t sched_flag_locked:1; /**< calling thread have the scheduler locked */
|
||||
rt_uint8_t sched_flag_ttmr_set:1; /**< thread timer is start */
|
||||
|
||||
#ifdef ARCH_USING_HW_THREAD_SELF
|
||||
rt_uint8_t critical_switch_flag:1; /**< critical switch pending */
|
||||
#endif /* ARCH_USING_HW_THREAD_SELF */
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
rt_uint8_t bind_cpu; /**< thread is bind to cpu */
|
||||
rt_uint8_t oncpu; /**< process on cpu */
|
||||
|
||||
rt_base_t critical_lock_nest; /**< critical lock count */
|
||||
#endif
|
||||
|
||||
struct rt_sched_thread_priv sched_thread_priv; /**< private context of scheduler */
|
||||
};
|
||||
|
||||
#define RT_SCHED_THREAD_CTX struct rt_sched_thread_ctx sched_thread_ctx;
|
||||
|
||||
#define RT_SCHED_PRIV(thread) ((thread)->sched_thread_ctx.sched_thread_priv)
|
||||
#define RT_SCHED_CTX(thread) ((thread)->sched_thread_ctx)
|
||||
|
||||
/**
|
||||
* Convert a list node in container RT_SCHED_CTX(thread)->thread_list_node
|
||||
* to a thread pointer.
|
||||
*/
|
||||
#define RT_THREAD_LIST_NODE_ENTRY(node) \
|
||||
rt_container_of( \
|
||||
rt_list_entry((node), struct rt_sched_thread_ctx, thread_list_node), \
|
||||
struct rt_thread, sched_thread_ctx)
|
||||
#define RT_THREAD_LIST_NODE(thread) (RT_SCHED_CTX(thread).thread_list_node)
|
||||
|
||||
#else /* !defined(RT_USING_SCHED_THREAD_CTX) */
|
||||
|
||||
#if RT_THREAD_PRIORITY_MAX > 32
|
||||
#define _RT_SCHED_THREAD_CTX_PRIO_EXT \
|
||||
rt_uint8_t number; /**< priority low number */ \
|
||||
rt_uint8_t high_mask; /**< priority high mask */
|
||||
|
||||
#else /* ! RT_THREAD_PRIORITY_MAX > 32 */
|
||||
|
||||
#define _RT_SCHED_THREAD_CTX_PRIO_EXT
|
||||
#endif /* RT_THREAD_PRIORITY_MAX > 32 */
|
||||
|
||||
#define RT_SCHED_THREAD_CTX \
|
||||
rt_list_t tlist; /**< node in thread list */ \
|
||||
rt_uint8_t stat; /**< thread status */ \
|
||||
rt_uint8_t sched_flag_locked:1; \
|
||||
/**< calling thread have the scheduler locked */ \
|
||||
rt_uint8_t sched_flag_ttmr_set:1; /**< thread timer is start */ \
|
||||
rt_tick_t init_tick; /**< thread's initialized tick */ \
|
||||
rt_tick_t remaining_tick; /**< remaining tick */ \
|
||||
rt_uint8_t current_priority; /**< current priority */ \
|
||||
rt_uint8_t init_priority; /**< initialized priority */ \
|
||||
_RT_SCHED_THREAD_CTX_PRIO_EXT \
|
||||
rt_uint32_t number_mask; /**< priority number mask */
|
||||
|
||||
#define RT_SCHED_PRIV(thread) (*thread)
|
||||
#define RT_SCHED_CTX(thread) (*thread)
|
||||
|
||||
/**
|
||||
* Convert a list node in container RT_SCHED_CTX(thread)->thread_list_node
|
||||
* to a thread pointer.
|
||||
*/
|
||||
#define RT_THREAD_LIST_NODE_ENTRY(node) rt_list_entry((node), struct rt_thread, tlist)
|
||||
#define RT_THREAD_LIST_NODE(thread) (RT_SCHED_CTX(thread).tlist)
|
||||
|
||||
#endif /* RT_USING_SCHED_THREAD_CTX */
|
||||
|
||||
/**
|
||||
* System Scheduler Locking
|
||||
*/
|
||||
|
||||
typedef rt_ubase_t rt_sched_lock_level_t;
|
||||
|
||||
rt_err_t rt_sched_lock(rt_sched_lock_level_t *plvl);
|
||||
rt_err_t rt_sched_unlock(rt_sched_lock_level_t level);
|
||||
rt_err_t rt_sched_unlock_n_resched(rt_sched_lock_level_t level);
|
||||
|
||||
rt_bool_t rt_sched_is_locked(void);
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
#define RT_SCHED_DEBUG_IS_LOCKED do { RT_ASSERT(rt_sched_is_locked()); } while (0)
|
||||
#define RT_SCHED_DEBUG_IS_UNLOCKED do { RT_ASSERT(!rt_sched_is_locked()); } while (0)
|
||||
|
||||
#else /* !RT_USING_SMP */
|
||||
|
||||
#define RT_SCHED_DEBUG_IS_LOCKED
|
||||
#define RT_SCHED_DEBUG_IS_UNLOCKED
|
||||
#endif /* RT_USING_SMP */
|
||||
|
||||
/**
|
||||
* NOTE: user should NEVER use these APIs directly. See rt_thread_.* or IPC
|
||||
* methods instead.
|
||||
*/
|
||||
#if defined(__RT_KERNEL_SOURCE__) || defined(__RT_IPC_SOURCE__)
|
||||
|
||||
/* thread initialization and startup routine */
|
||||
void rt_sched_thread_init_ctx(struct rt_thread *thread, rt_uint32_t tick, rt_uint8_t priority);
|
||||
void rt_sched_thread_init_priv(struct rt_thread *thread, rt_uint32_t tick, rt_uint8_t priority);
|
||||
void rt_sched_thread_startup(struct rt_thread *thread);
|
||||
|
||||
/* scheduler related routine */
|
||||
void rt_sched_post_ctx_switch(struct rt_thread *thread);
|
||||
rt_err_t rt_sched_tick_increase(void);
|
||||
|
||||
/* thread status operation */
|
||||
rt_uint8_t rt_sched_thread_get_stat(struct rt_thread *thread);
|
||||
rt_uint8_t rt_sched_thread_get_curr_prio(struct rt_thread *thread);
|
||||
rt_uint8_t rt_sched_thread_get_init_prio(struct rt_thread *thread);
|
||||
rt_err_t rt_sched_thread_yield(struct rt_thread *thread);
|
||||
rt_err_t rt_sched_thread_close(struct rt_thread *thread);
|
||||
rt_err_t rt_sched_thread_ready(struct rt_thread *thread);
|
||||
rt_err_t rt_sched_thread_suspend(struct rt_thread *thread, rt_sched_lock_level_t level);
|
||||
rt_err_t rt_sched_thread_change_priority(struct rt_thread *thread, rt_uint8_t priority);
|
||||
rt_err_t rt_sched_thread_bind_cpu(struct rt_thread *thread, int cpu);
|
||||
rt_uint8_t rt_sched_thread_is_suspended(struct rt_thread *thread);
|
||||
rt_err_t rt_sched_thread_timer_stop(struct rt_thread *thread);
|
||||
rt_err_t rt_sched_thread_timer_start(struct rt_thread *thread);
|
||||
void rt_sched_insert_thread(struct rt_thread *thread);
|
||||
void rt_sched_remove_thread(struct rt_thread *thread);
|
||||
struct rt_thread *rt_sched_thread_self(void);
|
||||
|
||||
#endif /* defined(__RT_KERNEL_SOURCE__) || defined(__RT_IPC_SOURCE__) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __RT_SCHED_H__ */
|
317
rt-thread/include/rtservice.h
Normal file
317
rt-thread/include/rtservice.h
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-03-16 Bernard the first version
|
||||
* 2006-09-07 Bernard move the kservice APIs to rtthread.h
|
||||
* 2007-06-27 Bernard fix the rt_list_remove bug
|
||||
* 2012-03-22 Bernard rename kservice.h to rtservice.h
|
||||
* 2017-11-15 JasonJia Modify rt_slist_foreach to rt_slist_for_each_entry.
|
||||
* Make code cleanup.
|
||||
*/
|
||||
|
||||
#ifndef __RT_SERVICE_H__
|
||||
#define __RT_SERVICE_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup KernelService
|
||||
*/
|
||||
|
||||
/**@{*/
|
||||
|
||||
/**
|
||||
* rt_container_of - return the start address of struct type, while ptr is the
|
||||
* member of struct type.
|
||||
*/
|
||||
#define rt_container_of(ptr, type, member) \
|
||||
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
|
||||
|
||||
|
||||
/**
|
||||
* @brief initialize a list object
|
||||
*/
|
||||
#define RT_LIST_OBJECT_INIT(object) { &(object), &(object) }
|
||||
|
||||
/**
|
||||
* @brief initialize a list
|
||||
*
|
||||
* @param l list to be initialized
|
||||
*/
|
||||
rt_inline void rt_list_init(rt_list_t *l)
|
||||
{
|
||||
l->next = l->prev = l;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief insert a node after a list
|
||||
*
|
||||
* @param l list to insert it
|
||||
* @param n new node to be inserted
|
||||
*/
|
||||
rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n)
|
||||
{
|
||||
l->next->prev = n;
|
||||
n->next = l->next;
|
||||
|
||||
l->next = n;
|
||||
n->prev = l;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief insert a node before a list
|
||||
*
|
||||
* @param n new node to be inserted
|
||||
* @param l list to insert it
|
||||
*/
|
||||
rt_inline void rt_list_insert_before(rt_list_t *l, rt_list_t *n)
|
||||
{
|
||||
l->prev->next = n;
|
||||
n->prev = l->prev;
|
||||
|
||||
l->prev = n;
|
||||
n->next = l;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief remove node from list.
|
||||
* @param n the node to remove from the list.
|
||||
*/
|
||||
rt_inline void rt_list_remove(rt_list_t *n)
|
||||
{
|
||||
n->next->prev = n->prev;
|
||||
n->prev->next = n->next;
|
||||
|
||||
n->next = n->prev = n;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief tests whether a list is empty
|
||||
* @param l the list to test.
|
||||
*/
|
||||
rt_inline int rt_list_isempty(const rt_list_t *l)
|
||||
{
|
||||
return l->next == l;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get the list length
|
||||
* @param l the list to get.
|
||||
*/
|
||||
rt_inline unsigned int rt_list_len(const rt_list_t *l)
|
||||
{
|
||||
unsigned int len = 0;
|
||||
const rt_list_t *p = l;
|
||||
while (p->next != l)
|
||||
{
|
||||
p = p->next;
|
||||
len ++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get the struct for this entry
|
||||
* @param node the entry point
|
||||
* @param type the type of structure
|
||||
* @param member the name of list in structure
|
||||
*/
|
||||
#define rt_list_entry(node, type, member) \
|
||||
rt_container_of(node, type, member)
|
||||
|
||||
/**
|
||||
* rt_list_for_each - iterate over a list
|
||||
* @param pos the rt_list_t * to use as a loop cursor.
|
||||
* @param head the head for your list.
|
||||
*/
|
||||
#define rt_list_for_each(pos, head) \
|
||||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||||
|
||||
/**
|
||||
* rt_list_for_each_safe - iterate over a list safe against removal of list entry
|
||||
* @param pos the rt_list_t * to use as a loop cursor.
|
||||
* @param n another rt_list_t * to use as temporary storage
|
||||
* @param head the head for your list.
|
||||
*/
|
||||
#define rt_list_for_each_safe(pos, n, head) \
|
||||
for (pos = (head)->next, n = pos->next; pos != (head); \
|
||||
pos = n, n = pos->next)
|
||||
|
||||
/**
|
||||
* rt_list_for_each_entry - iterate over list of given type
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
*/
|
||||
#define rt_list_for_each_entry(pos, head, member) \
|
||||
for (pos = rt_list_entry((head)->next, rt_typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = rt_list_entry(pos->member.next, rt_typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* rt_list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param n another type * to use as temporary storage
|
||||
* @param head the head for your list.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
*/
|
||||
#define rt_list_for_each_entry_safe(pos, n, head, member) \
|
||||
for (pos = rt_list_entry((head)->next, rt_typeof(*pos), member), \
|
||||
n = rt_list_entry(pos->member.next, rt_typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = rt_list_entry(n->member.next, rt_typeof(*n), member))
|
||||
|
||||
/**
|
||||
* rt_list_first_entry - get the first element from a list
|
||||
* @param ptr the list head to take the element from.
|
||||
* @param type the type of the struct this is embedded in.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
*
|
||||
* Note, that list is expected to be not empty.
|
||||
*/
|
||||
#define rt_list_first_entry(ptr, type, member) \
|
||||
rt_list_entry((ptr)->next, type, member)
|
||||
|
||||
#define RT_SLIST_OBJECT_INIT(object) { RT_NULL }
|
||||
|
||||
/**
|
||||
* @brief initialize a single list
|
||||
*
|
||||
* @param l the single list to be initialized
|
||||
*/
|
||||
rt_inline void rt_slist_init(rt_slist_t *l)
|
||||
{
|
||||
l->next = RT_NULL;
|
||||
}
|
||||
|
||||
rt_inline void rt_slist_append(rt_slist_t *l, rt_slist_t *n)
|
||||
{
|
||||
struct rt_slist_node *node;
|
||||
|
||||
node = l;
|
||||
while (node->next) node = node->next;
|
||||
|
||||
/* append the node to the tail */
|
||||
node->next = n;
|
||||
n->next = RT_NULL;
|
||||
}
|
||||
|
||||
rt_inline void rt_slist_insert(rt_slist_t *l, rt_slist_t *n)
|
||||
{
|
||||
n->next = l->next;
|
||||
l->next = n;
|
||||
}
|
||||
|
||||
rt_inline unsigned int rt_slist_len(const rt_slist_t *l)
|
||||
{
|
||||
unsigned int len = 0;
|
||||
const rt_slist_t *list = l->next;
|
||||
while (list != RT_NULL)
|
||||
{
|
||||
list = list->next;
|
||||
len ++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
rt_inline rt_slist_t *rt_slist_remove(rt_slist_t *l, rt_slist_t *n)
|
||||
{
|
||||
/* remove slist head */
|
||||
struct rt_slist_node *node = l;
|
||||
while (node->next && node->next != n) node = node->next;
|
||||
|
||||
/* remove node */
|
||||
if (node->next != (rt_slist_t *)0) node->next = node->next->next;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
rt_inline rt_slist_t *rt_slist_first(rt_slist_t *l)
|
||||
{
|
||||
return l->next;
|
||||
}
|
||||
|
||||
rt_inline rt_slist_t *rt_slist_tail(rt_slist_t *l)
|
||||
{
|
||||
while (l->next) l = l->next;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
rt_inline rt_slist_t *rt_slist_next(rt_slist_t *n)
|
||||
{
|
||||
return n->next;
|
||||
}
|
||||
|
||||
rt_inline int rt_slist_isempty(rt_slist_t *l)
|
||||
{
|
||||
return l->next == RT_NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get the struct for this single list node
|
||||
* @param node the entry point
|
||||
* @param type the type of structure
|
||||
* @param member the name of list in structure
|
||||
*/
|
||||
#define rt_slist_entry(node, type, member) \
|
||||
rt_container_of(node, type, member)
|
||||
|
||||
/**
|
||||
* rt_slist_for_each - iterate over a single list
|
||||
* @param pos the rt_slist_t * to use as a loop cursor.
|
||||
* @param head the head for your single list.
|
||||
*/
|
||||
#define rt_slist_for_each(pos, head) \
|
||||
for (pos = (head)->next; pos != RT_NULL; pos = pos->next)
|
||||
|
||||
/**
|
||||
* rt_slist_for_each_entry - iterate over single list of given type
|
||||
* @param pos the type * to use as a loop cursor.
|
||||
* @param head the head for your single list.
|
||||
* @param member the name of the list_struct within the struct.
|
||||
*/
|
||||
#define rt_slist_for_each_entry(pos, head, member) \
|
||||
for (pos = ((head)->next == (RT_NULL) ? (RT_NULL) : rt_slist_entry((head)->next, rt_typeof(*pos), member)); \
|
||||
pos != (RT_NULL) && &pos->member != (RT_NULL); \
|
||||
pos = (pos->member.next == (RT_NULL) ? (RT_NULL) : rt_slist_entry(pos->member.next, rt_typeof(*pos), member)))
|
||||
|
||||
/**
|
||||
* rt_slist_first_entry - get the first element from a slist
|
||||
* @param ptr the slist head to take the element from.
|
||||
* @param type the type of the struct this is embedded in.
|
||||
* @param member the name of the slist_struct within the struct.
|
||||
*
|
||||
* Note, that slist is expected to be not empty.
|
||||
*/
|
||||
#define rt_slist_first_entry(ptr, type, member) \
|
||||
rt_slist_entry((ptr)->next, type, member)
|
||||
|
||||
/**
|
||||
* rt_slist_tail_entry - get the tail element from a slist
|
||||
* @param ptr the slist head to take the element from.
|
||||
* @param type the type of the struct this is embedded in.
|
||||
* @param member the name of the slist_struct within the struct.
|
||||
*
|
||||
* Note, that slist is expected to be not empty.
|
||||
*/
|
||||
#define rt_slist_tail_entry(ptr, type, member) \
|
||||
rt_slist_entry(rt_slist_tail(ptr), type, member)
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
894
rt-thread/include/rtthread.h
Normal file
894
rt-thread/include/rtthread.h
Normal file
@@ -0,0 +1,894 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-03-18 Bernard the first version
|
||||
* 2006-04-26 Bernard add semaphore APIs
|
||||
* 2006-08-10 Bernard add version information
|
||||
* 2007-01-28 Bernard rename RT_OBJECT_Class_Static to RT_Object_Class_Static
|
||||
* 2007-03-03 Bernard clean up the definitions to rtdef.h
|
||||
* 2010-04-11 yi.qiu add module feature
|
||||
* 2013-06-24 Bernard add rt_kprintf re-define when not use RT_USING_CONSOLE.
|
||||
* 2016-08-09 ArdaFu add new thread and interrupt hook.
|
||||
* 2018-11-22 Jesven add all cpu's lock and ipi handler
|
||||
* 2021-02-28 Meco Man add RT_KSERVICE_USING_STDLIB
|
||||
* 2021-11-14 Meco Man add rtlegacy.h for compatibility
|
||||
* 2022-06-04 Meco Man remove strnlen
|
||||
* 2023-05-20 Bernard add rtatomic.h header file to included files.
|
||||
* 2023-06-30 ChuShicheng move debug check from the rtdebug.h
|
||||
* 2023-10-16 Shell Support a new backtrace framework
|
||||
* 2023-12-10 xqyjlj fix spinlock in up
|
||||
* 2024-01-25 Shell Add rt_susp_list for IPC primitives
|
||||
* 2024-03-10 Meco Man move std libc related functions to rtklibc
|
||||
*/
|
||||
|
||||
#ifndef __RT_THREAD_H__
|
||||
#define __RT_THREAD_H__
|
||||
|
||||
#include <rtconfig.h>
|
||||
#include <rtdef.h>
|
||||
#include <rtservice.h>
|
||||
#include <rtm.h>
|
||||
#include <rtatomic.h>
|
||||
#include <rtklibc.h>
|
||||
#ifdef RT_USING_LEGACY
|
||||
#include <rtlegacy.h>
|
||||
#endif
|
||||
#ifdef RT_USING_FINSH
|
||||
#include <finsh.h>
|
||||
#endif /* RT_USING_FINSH */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
int entry(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup KernelObject
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* kernel object interface
|
||||
*/
|
||||
struct rt_object_information *
|
||||
rt_object_get_information(enum rt_object_class_type type);
|
||||
int rt_object_get_length(enum rt_object_class_type type);
|
||||
int rt_object_get_pointers(enum rt_object_class_type type, rt_object_t *pointers, int maxlen);
|
||||
|
||||
void rt_object_init(struct rt_object *object,
|
||||
enum rt_object_class_type type,
|
||||
const char *name);
|
||||
void rt_object_detach(rt_object_t object);
|
||||
#ifdef RT_USING_HEAP
|
||||
rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name);
|
||||
void rt_object_delete(rt_object_t object);
|
||||
/* custom object */
|
||||
rt_object_t rt_custom_object_create(const char *name, void *data, rt_err_t (*data_destroy)(void *));
|
||||
rt_err_t rt_custom_object_destroy(rt_object_t obj);
|
||||
#endif /* RT_USING_HEAP */
|
||||
rt_bool_t rt_object_is_systemobject(rt_object_t object);
|
||||
rt_uint8_t rt_object_get_type(rt_object_t object);
|
||||
rt_err_t rt_object_for_each(rt_uint8_t type, rt_object_iter_t iter, void *data);
|
||||
rt_object_t rt_object_find(const char *name, rt_uint8_t type);
|
||||
rt_err_t rt_object_get_name(rt_object_t object, char *name, rt_uint8_t name_size);
|
||||
|
||||
#ifdef RT_USING_HOOK
|
||||
void rt_object_attach_sethook(void (*hook)(struct rt_object *object));
|
||||
void rt_object_detach_sethook(void (*hook)(struct rt_object *object));
|
||||
void rt_object_trytake_sethook(void (*hook)(struct rt_object *object));
|
||||
void rt_object_take_sethook(void (*hook)(struct rt_object *object));
|
||||
void rt_object_put_sethook(void (*hook)(struct rt_object *object));
|
||||
#endif /* RT_USING_HOOK */
|
||||
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @addtogroup Clock
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* clock & timer interface
|
||||
*/
|
||||
rt_tick_t rt_tick_get(void);
|
||||
void rt_tick_set(rt_tick_t tick);
|
||||
void rt_tick_increase(void);
|
||||
rt_tick_t rt_tick_from_millisecond(rt_int32_t ms);
|
||||
rt_tick_t rt_tick_get_millisecond(void);
|
||||
#ifdef RT_USING_HOOK
|
||||
void rt_tick_sethook(void (*hook)(void));
|
||||
#endif /* RT_USING_HOOK */
|
||||
|
||||
void rt_system_timer_init(void);
|
||||
void rt_system_timer_thread_init(void);
|
||||
|
||||
void rt_timer_init(rt_timer_t timer,
|
||||
const char *name,
|
||||
void (*timeout)(void *parameter),
|
||||
void *parameter,
|
||||
rt_tick_t time,
|
||||
rt_uint8_t flag);
|
||||
rt_err_t rt_timer_detach(rt_timer_t timer);
|
||||
#ifdef RT_USING_HEAP
|
||||
rt_timer_t rt_timer_create(const char *name,
|
||||
void (*timeout)(void *parameter),
|
||||
void *parameter,
|
||||
rt_tick_t time,
|
||||
rt_uint8_t flag);
|
||||
rt_err_t rt_timer_delete(rt_timer_t timer);
|
||||
#endif /* RT_USING_HEAP */
|
||||
rt_err_t rt_timer_start(rt_timer_t timer);
|
||||
rt_err_t rt_timer_stop(rt_timer_t timer);
|
||||
rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg);
|
||||
rt_tick_t rt_timer_next_timeout_tick(void);
|
||||
void rt_timer_check(void);
|
||||
#ifdef RT_USING_HOOK
|
||||
void rt_timer_enter_sethook(void (*hook)(struct rt_timer *timer));
|
||||
void rt_timer_exit_sethook(void (*hook)(struct rt_timer *timer));
|
||||
#endif /* RT_USING_HOOK */
|
||||
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @addtogroup Thread
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* thread interface
|
||||
*/
|
||||
rt_err_t rt_thread_init(struct rt_thread *thread,
|
||||
const char *name,
|
||||
void (*entry)(void *parameter),
|
||||
void *parameter,
|
||||
void *stack_start,
|
||||
rt_uint32_t stack_size,
|
||||
rt_uint8_t priority,
|
||||
rt_uint32_t tick);
|
||||
rt_err_t rt_thread_detach(rt_thread_t thread);
|
||||
#ifdef RT_USING_HEAP
|
||||
rt_thread_t rt_thread_create(const char *name,
|
||||
void (*entry)(void *parameter),
|
||||
void *parameter,
|
||||
rt_uint32_t stack_size,
|
||||
rt_uint8_t priority,
|
||||
rt_uint32_t tick);
|
||||
rt_err_t rt_thread_delete(rt_thread_t thread);
|
||||
#endif /* RT_USING_HEAP */
|
||||
rt_err_t rt_thread_close(rt_thread_t thread);
|
||||
rt_thread_t rt_thread_self(void);
|
||||
rt_thread_t rt_thread_find(char *name);
|
||||
rt_err_t rt_thread_startup(rt_thread_t thread);
|
||||
rt_err_t rt_thread_yield(void);
|
||||
rt_err_t rt_thread_delay(rt_tick_t tick);
|
||||
rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick);
|
||||
rt_err_t rt_thread_mdelay(rt_int32_t ms);
|
||||
rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg);
|
||||
rt_err_t rt_thread_suspend(rt_thread_t thread);
|
||||
rt_err_t rt_thread_suspend_with_flag(rt_thread_t thread, int suspend_flag);
|
||||
rt_err_t rt_thread_resume(rt_thread_t thread);
|
||||
#ifdef RT_USING_SMART
|
||||
rt_err_t rt_thread_wakeup(rt_thread_t thread);
|
||||
void rt_thread_wakeup_set(struct rt_thread *thread, rt_wakeup_func_t func, void* user_data);
|
||||
#endif /* RT_USING_SMART */
|
||||
rt_err_t rt_thread_get_name(rt_thread_t thread, char *name, rt_uint8_t name_size);
|
||||
#ifdef RT_USING_SIGNALS
|
||||
void rt_thread_alloc_sig(rt_thread_t tid);
|
||||
void rt_thread_free_sig(rt_thread_t tid);
|
||||
int rt_thread_kill(rt_thread_t tid, int sig);
|
||||
#endif /* RT_USING_SIGNALS */
|
||||
#ifdef RT_USING_HOOK
|
||||
void rt_thread_suspend_sethook(void (*hook)(rt_thread_t thread));
|
||||
void rt_thread_resume_sethook (void (*hook)(rt_thread_t thread));
|
||||
|
||||
/**
|
||||
* @brief Sets a hook function when a thread is initialized.
|
||||
*
|
||||
* @param thread is the target thread that initializing
|
||||
*/
|
||||
typedef void (*rt_thread_inited_hookproto_t)(rt_thread_t thread);
|
||||
RT_OBJECT_HOOKLIST_DECLARE(rt_thread_inited_hookproto_t, rt_thread_inited);
|
||||
|
||||
#endif /* RT_USING_HOOK */
|
||||
|
||||
/*
|
||||
* idle thread interface
|
||||
*/
|
||||
void rt_thread_idle_init(void);
|
||||
#if defined(RT_USING_HOOK) || defined(RT_USING_IDLE_HOOK)
|
||||
rt_err_t rt_thread_idle_sethook(void (*hook)(void));
|
||||
rt_err_t rt_thread_idle_delhook(void (*hook)(void));
|
||||
#endif /* defined(RT_USING_HOOK) || defined(RT_USING_IDLE_HOOK) */
|
||||
rt_thread_t rt_thread_idle_gethandler(void);
|
||||
|
||||
/*
|
||||
* schedule service
|
||||
*/
|
||||
void rt_system_scheduler_init(void);
|
||||
void rt_system_scheduler_start(void);
|
||||
|
||||
void rt_schedule(void);
|
||||
void rt_scheduler_do_irq_switch(void *context);
|
||||
|
||||
#ifdef RT_USING_OVERFLOW_CHECK
|
||||
void rt_scheduler_stack_check(struct rt_thread *thread);
|
||||
|
||||
#define RT_SCHEDULER_STACK_CHECK(thr) rt_scheduler_stack_check(thr)
|
||||
|
||||
#else /* !RT_USING_OVERFLOW_CHECK */
|
||||
|
||||
#define RT_SCHEDULER_STACK_CHECK(thr)
|
||||
|
||||
#endif /* RT_USING_OVERFLOW_CHECK */
|
||||
|
||||
rt_base_t rt_enter_critical(void);
|
||||
void rt_exit_critical(void);
|
||||
void rt_exit_critical_safe(rt_base_t critical_level);
|
||||
rt_uint16_t rt_critical_level(void);
|
||||
|
||||
#ifdef RT_USING_HOOK
|
||||
void rt_scheduler_sethook(void (*hook)(rt_thread_t from, rt_thread_t to));
|
||||
void rt_scheduler_switch_sethook(void (*hook)(struct rt_thread *tid));
|
||||
#endif /* RT_USING_HOOK */
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
void rt_secondary_cpu_entry(void);
|
||||
void rt_scheduler_ipi_handler(int vector, void *param);
|
||||
#endif /* RT_USING_SMP */
|
||||
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @addtogroup Signal
|
||||
* @{
|
||||
*/
|
||||
#ifdef RT_USING_SIGNALS
|
||||
void rt_signal_mask(int signo);
|
||||
void rt_signal_unmask(int signo);
|
||||
rt_sighandler_t rt_signal_install(int signo, rt_sighandler_t handler);
|
||||
int rt_signal_wait(const rt_sigset_t *set, rt_siginfo_t *si, rt_int32_t timeout);
|
||||
int rt_system_signal_init(void);
|
||||
#endif /* RT_USING_SIGNALS */
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @addtogroup MM
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* memory management interface
|
||||
*/
|
||||
#ifdef RT_USING_MEMPOOL
|
||||
/*
|
||||
* memory pool interface
|
||||
*/
|
||||
rt_err_t rt_mp_init(struct rt_mempool *mp,
|
||||
const char *name,
|
||||
void *start,
|
||||
rt_size_t size,
|
||||
rt_size_t block_size);
|
||||
rt_err_t rt_mp_detach(struct rt_mempool *mp);
|
||||
#ifdef RT_USING_HEAP
|
||||
rt_mp_t rt_mp_create(const char *name,
|
||||
rt_size_t block_count,
|
||||
rt_size_t block_size);
|
||||
rt_err_t rt_mp_delete(rt_mp_t mp);
|
||||
#endif /* RT_USING_HEAP */
|
||||
void *rt_mp_alloc(rt_mp_t mp, rt_int32_t time);
|
||||
void rt_mp_free(void *block);
|
||||
#ifdef RT_USING_HOOK
|
||||
void rt_mp_alloc_sethook(void (*hook)(struct rt_mempool *mp, void *block));
|
||||
void rt_mp_free_sethook(void (*hook)(struct rt_mempool *mp, void *block));
|
||||
#endif /* RT_USING_HOOK */
|
||||
|
||||
#endif /* RT_USING_MEMPOOL */
|
||||
|
||||
#ifdef RT_USING_HEAP
|
||||
/*
|
||||
* heap memory interface
|
||||
*/
|
||||
void rt_system_heap_init(void *begin_addr, void *end_addr);
|
||||
void rt_system_heap_init_generic(void *begin_addr, void *end_addr);
|
||||
|
||||
void *rt_malloc(rt_size_t size);
|
||||
void rt_free(void *ptr);
|
||||
void *rt_realloc(void *ptr, rt_size_t newsize);
|
||||
void *rt_calloc(rt_size_t count, rt_size_t size);
|
||||
void *rt_malloc_align(rt_size_t size, rt_size_t align);
|
||||
void rt_free_align(void *ptr);
|
||||
|
||||
void rt_memory_info(rt_size_t *total,
|
||||
rt_size_t *used,
|
||||
rt_size_t *max_used);
|
||||
|
||||
#if defined(RT_USING_SLAB) && defined(RT_USING_SLAB_AS_HEAP)
|
||||
void *rt_page_alloc(rt_size_t npages);
|
||||
void rt_page_free(void *addr, rt_size_t npages);
|
||||
#endif /* defined(RT_USING_SLAB) && defined(RT_USING_SLAB_AS_HEAP) */
|
||||
|
||||
/**
|
||||
* @ingroup Hook
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef RT_USING_HOOK
|
||||
void rt_malloc_sethook(void (*hook)(void **ptr, rt_size_t size));
|
||||
void rt_realloc_set_entry_hook(void (*hook)(void **ptr, rt_size_t size));
|
||||
void rt_realloc_set_exit_hook(void (*hook)(void **ptr, rt_size_t size));
|
||||
void rt_free_sethook(void (*hook)(void **ptr));
|
||||
#endif /* RT_USING_HOOK */
|
||||
/**@}*/
|
||||
|
||||
#endif /* RT_USING_HEAP */
|
||||
|
||||
#ifdef RT_USING_SMALL_MEM
|
||||
/**
|
||||
* small memory object interface
|
||||
*/
|
||||
rt_smem_t rt_smem_init(const char *name,
|
||||
void *begin_addr,
|
||||
rt_size_t size);
|
||||
rt_err_t rt_smem_detach(rt_smem_t m);
|
||||
void *rt_smem_alloc(rt_smem_t m, rt_size_t size);
|
||||
void *rt_smem_realloc(rt_smem_t m, void *rmem, rt_size_t newsize);
|
||||
void rt_smem_free(void *rmem);
|
||||
#endif /* RT_USING_SMALL_MEM */
|
||||
|
||||
#ifdef RT_USING_MEMHEAP
|
||||
/**
|
||||
* memory heap object interface
|
||||
*/
|
||||
rt_err_t rt_memheap_init(struct rt_memheap *memheap,
|
||||
const char *name,
|
||||
void *start_addr,
|
||||
rt_size_t size);
|
||||
rt_err_t rt_memheap_detach(struct rt_memheap *heap);
|
||||
void *rt_memheap_alloc(struct rt_memheap *heap, rt_size_t size);
|
||||
void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize);
|
||||
void rt_memheap_free(void *ptr);
|
||||
void rt_memheap_info(struct rt_memheap *heap,
|
||||
rt_size_t *total,
|
||||
rt_size_t *used,
|
||||
rt_size_t *max_used);
|
||||
#endif /* RT_USING_MEMHEAP */
|
||||
|
||||
#ifdef RT_USING_MEMHEAP_AS_HEAP
|
||||
/**
|
||||
* memory heap as heap
|
||||
*/
|
||||
void *_memheap_alloc(struct rt_memheap *heap, rt_size_t size);
|
||||
void _memheap_free(void *rmem);
|
||||
void *_memheap_realloc(struct rt_memheap *heap, void *rmem, rt_size_t newsize);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_SLAB
|
||||
/**
|
||||
* slab object interface
|
||||
*/
|
||||
rt_slab_t rt_slab_init(const char *name, void *begin_addr, rt_size_t size);
|
||||
rt_err_t rt_slab_detach(rt_slab_t m);
|
||||
void *rt_slab_page_alloc(rt_slab_t m, rt_size_t npages);
|
||||
void rt_slab_page_free(rt_slab_t m, void *addr, rt_size_t npages);
|
||||
void *rt_slab_alloc(rt_slab_t m, rt_size_t size);
|
||||
void *rt_slab_realloc(rt_slab_t m, void *ptr, rt_size_t size);
|
||||
void rt_slab_free(rt_slab_t m, void *ptr);
|
||||
#endif /* RT_USING_SLAB */
|
||||
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @addtogroup IPC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Suspend list - A basic building block for IPC primitives which interacts with
|
||||
* scheduler directly. Its API is similar to a FIFO list.
|
||||
*
|
||||
* Note: don't use in application codes directly
|
||||
*/
|
||||
void rt_susp_list_print(rt_list_t *list);
|
||||
/* reserve thread error while resuming it */
|
||||
#define RT_THREAD_RESUME_RES_THR_ERR (-1)
|
||||
struct rt_thread *rt_susp_list_dequeue(rt_list_t *susp_list, rt_err_t thread_error);
|
||||
rt_err_t rt_susp_list_resume_all(rt_list_t *susp_list, rt_err_t thread_error);
|
||||
rt_err_t rt_susp_list_resume_all_irq(rt_list_t *susp_list,
|
||||
rt_err_t thread_error,
|
||||
struct rt_spinlock *lock);
|
||||
|
||||
/* suspend and enqueue */
|
||||
rt_err_t rt_thread_suspend_to_list(rt_thread_t thread, rt_list_t *susp_list, int ipc_flags, int suspend_flag);
|
||||
/* only for a suspended thread, and caller must hold the scheduler lock */
|
||||
rt_err_t rt_susp_list_enqueue(rt_list_t *susp_list, rt_thread_t thread, int ipc_flags);
|
||||
|
||||
/**
|
||||
* @addtogroup semaphore
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef RT_USING_SEMAPHORE
|
||||
/*
|
||||
* semaphore interface
|
||||
*/
|
||||
rt_err_t rt_sem_init(rt_sem_t sem,
|
||||
const char *name,
|
||||
rt_uint32_t value,
|
||||
rt_uint8_t flag);
|
||||
rt_err_t rt_sem_detach(rt_sem_t sem);
|
||||
#ifdef RT_USING_HEAP
|
||||
rt_sem_t rt_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag);
|
||||
rt_err_t rt_sem_delete(rt_sem_t sem);
|
||||
#endif /* RT_USING_HEAP */
|
||||
|
||||
rt_err_t rt_sem_take(rt_sem_t sem, rt_int32_t timeout);
|
||||
rt_err_t rt_sem_take_interruptible(rt_sem_t sem, rt_int32_t timeout);
|
||||
rt_err_t rt_sem_take_killable(rt_sem_t sem, rt_int32_t timeout);
|
||||
rt_err_t rt_sem_trytake(rt_sem_t sem);
|
||||
rt_err_t rt_sem_release(rt_sem_t sem);
|
||||
rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg);
|
||||
#endif /* RT_USING_SEMAPHORE */
|
||||
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @addtogroup mutex
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef RT_USING_MUTEX
|
||||
/*
|
||||
* mutex interface
|
||||
*/
|
||||
rt_err_t rt_mutex_init(rt_mutex_t mutex, const char *name, rt_uint8_t flag);
|
||||
rt_err_t rt_mutex_detach(rt_mutex_t mutex);
|
||||
#ifdef RT_USING_HEAP
|
||||
rt_mutex_t rt_mutex_create(const char *name, rt_uint8_t flag);
|
||||
rt_err_t rt_mutex_delete(rt_mutex_t mutex);
|
||||
#endif /* RT_USING_HEAP */
|
||||
void rt_mutex_drop_thread(rt_mutex_t mutex, rt_thread_t thread);
|
||||
rt_uint8_t rt_mutex_setprioceiling(rt_mutex_t mutex, rt_uint8_t priority);
|
||||
rt_uint8_t rt_mutex_getprioceiling(rt_mutex_t mutex);
|
||||
|
||||
rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout);
|
||||
rt_err_t rt_mutex_trytake(rt_mutex_t mutex);
|
||||
rt_err_t rt_mutex_take_interruptible(rt_mutex_t mutex, rt_int32_t time);
|
||||
rt_err_t rt_mutex_take_killable(rt_mutex_t mutex, rt_int32_t time);
|
||||
rt_err_t rt_mutex_release(rt_mutex_t mutex);
|
||||
rt_err_t rt_mutex_control(rt_mutex_t mutex, int cmd, void *arg);
|
||||
|
||||
rt_inline rt_thread_t rt_mutex_get_owner(rt_mutex_t mutex)
|
||||
{
|
||||
return mutex->owner;
|
||||
}
|
||||
rt_inline rt_ubase_t rt_mutex_get_hold(rt_mutex_t mutex)
|
||||
{
|
||||
return mutex->hold;
|
||||
}
|
||||
|
||||
#endif /* RT_USING_MUTEX */
|
||||
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @addtogroup event
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef RT_USING_EVENT
|
||||
/*
|
||||
* event interface
|
||||
*/
|
||||
rt_err_t rt_event_init(rt_event_t event, const char *name, rt_uint8_t flag);
|
||||
rt_err_t rt_event_detach(rt_event_t event);
|
||||
#ifdef RT_USING_HEAP
|
||||
rt_event_t rt_event_create(const char *name, rt_uint8_t flag);
|
||||
rt_err_t rt_event_delete(rt_event_t event);
|
||||
#endif /* RT_USING_HEAP */
|
||||
|
||||
rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set);
|
||||
rt_err_t rt_event_recv(rt_event_t event,
|
||||
rt_uint32_t set,
|
||||
rt_uint8_t opt,
|
||||
rt_int32_t timeout,
|
||||
rt_uint32_t *recved);
|
||||
rt_err_t rt_event_recv_interruptible(rt_event_t event,
|
||||
rt_uint32_t set,
|
||||
rt_uint8_t opt,
|
||||
rt_int32_t timeout,
|
||||
rt_uint32_t *recved);
|
||||
rt_err_t rt_event_recv_killable(rt_event_t event,
|
||||
rt_uint32_t set,
|
||||
rt_uint8_t opt,
|
||||
rt_int32_t timeout,
|
||||
rt_uint32_t *recved);
|
||||
rt_err_t rt_event_control(rt_event_t event, int cmd, void *arg);
|
||||
#endif /* RT_USING_EVENT */
|
||||
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @addtogroup mailbox
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef RT_USING_MAILBOX
|
||||
/*
|
||||
* mailbox interface
|
||||
*/
|
||||
rt_err_t rt_mb_init(rt_mailbox_t mb,
|
||||
const char *name,
|
||||
void *msgpool,
|
||||
rt_size_t size,
|
||||
rt_uint8_t flag);
|
||||
rt_err_t rt_mb_detach(rt_mailbox_t mb);
|
||||
#ifdef RT_USING_HEAP
|
||||
rt_mailbox_t rt_mb_create(const char *name, rt_size_t size, rt_uint8_t flag);
|
||||
rt_err_t rt_mb_delete(rt_mailbox_t mb);
|
||||
#endif /* RT_USING_HEAP */
|
||||
|
||||
rt_err_t rt_mb_send(rt_mailbox_t mb, rt_ubase_t value);
|
||||
rt_err_t rt_mb_send_interruptible(rt_mailbox_t mb, rt_ubase_t value);
|
||||
rt_err_t rt_mb_send_killable(rt_mailbox_t mb, rt_ubase_t value);
|
||||
rt_err_t rt_mb_send_wait(rt_mailbox_t mb,
|
||||
rt_ubase_t value,
|
||||
rt_int32_t timeout);
|
||||
rt_err_t rt_mb_send_wait_interruptible(rt_mailbox_t mb,
|
||||
rt_ubase_t value,
|
||||
rt_int32_t timeout);
|
||||
rt_err_t rt_mb_send_wait_killable(rt_mailbox_t mb,
|
||||
rt_ubase_t value,
|
||||
rt_int32_t timeout);
|
||||
rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value);
|
||||
rt_err_t rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeout);
|
||||
rt_err_t rt_mb_recv_interruptible(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeout);
|
||||
rt_err_t rt_mb_recv_killable(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeout);
|
||||
rt_err_t rt_mb_control(rt_mailbox_t mb, int cmd, void *arg);
|
||||
#endif /* RT_USING_MAILBOX */
|
||||
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @addtogroup messagequeue
|
||||
* @{
|
||||
*/
|
||||
#ifdef RT_USING_MESSAGEQUEUE
|
||||
|
||||
struct rt_mq_message
|
||||
{
|
||||
struct rt_mq_message *next;
|
||||
rt_ssize_t length;
|
||||
#ifdef RT_USING_MESSAGEQUEUE_PRIORITY
|
||||
rt_int32_t prio;
|
||||
#endif /* RT_USING_MESSAGEQUEUE_PRIORITY */
|
||||
};
|
||||
|
||||
#define RT_MQ_BUF_SIZE(msg_size, max_msgs) \
|
||||
((RT_ALIGN((msg_size), RT_ALIGN_SIZE) + sizeof(struct rt_mq_message)) * (max_msgs))
|
||||
|
||||
/*
|
||||
* message queue interface
|
||||
*/
|
||||
rt_err_t rt_mq_init(rt_mq_t mq,
|
||||
const char *name,
|
||||
void *msgpool,
|
||||
rt_size_t msg_size,
|
||||
rt_size_t pool_size,
|
||||
rt_uint8_t flag);
|
||||
rt_err_t rt_mq_detach(rt_mq_t mq);
|
||||
#ifdef RT_USING_HEAP
|
||||
rt_mq_t rt_mq_create(const char *name,
|
||||
rt_size_t msg_size,
|
||||
rt_size_t max_msgs,
|
||||
rt_uint8_t flag);
|
||||
rt_err_t rt_mq_delete(rt_mq_t mq);
|
||||
#endif /* RT_USING_HEAP */
|
||||
|
||||
rt_err_t rt_mq_send(rt_mq_t mq, const void *buffer, rt_size_t size);
|
||||
rt_err_t rt_mq_send_interruptible(rt_mq_t mq, const void *buffer, rt_size_t size);
|
||||
rt_err_t rt_mq_send_killable(rt_mq_t mq, const void *buffer, rt_size_t size);
|
||||
rt_err_t rt_mq_send_wait(rt_mq_t mq,
|
||||
const void *buffer,
|
||||
rt_size_t size,
|
||||
rt_int32_t timeout);
|
||||
rt_err_t rt_mq_send_wait_interruptible(rt_mq_t mq,
|
||||
const void *buffer,
|
||||
rt_size_t size,
|
||||
rt_int32_t timeout);
|
||||
rt_err_t rt_mq_send_wait_killable(rt_mq_t mq,
|
||||
const void *buffer,
|
||||
rt_size_t size,
|
||||
rt_int32_t timeout);
|
||||
rt_err_t rt_mq_urgent(rt_mq_t mq, const void *buffer, rt_size_t size);
|
||||
rt_ssize_t rt_mq_recv(rt_mq_t mq,
|
||||
void *buffer,
|
||||
rt_size_t size,
|
||||
rt_int32_t timeout);
|
||||
rt_ssize_t rt_mq_recv_interruptible(rt_mq_t mq,
|
||||
void *buffer,
|
||||
rt_size_t size,
|
||||
rt_int32_t timeout);
|
||||
rt_ssize_t rt_mq_recv_killable(rt_mq_t mq,
|
||||
void *buffer,
|
||||
rt_size_t size,
|
||||
rt_int32_t timeout);
|
||||
rt_err_t rt_mq_control(rt_mq_t mq, int cmd, void *arg);
|
||||
|
||||
#ifdef RT_USING_MESSAGEQUEUE_PRIORITY
|
||||
rt_err_t rt_mq_send_wait_prio(rt_mq_t mq,
|
||||
const void *buffer,
|
||||
rt_size_t size,
|
||||
rt_int32_t prio,
|
||||
rt_int32_t timeout,
|
||||
int suspend_flag);
|
||||
rt_ssize_t rt_mq_recv_prio(rt_mq_t mq,
|
||||
void *buffer,
|
||||
rt_size_t size,
|
||||
rt_int32_t *prio,
|
||||
rt_int32_t timeout,
|
||||
int suspend_flag);
|
||||
#endif /* RT_USING_MESSAGEQUEUE_PRIORITY */
|
||||
#endif /* RT_USING_MESSAGEQUEUE */
|
||||
|
||||
/**@}*/
|
||||
|
||||
/* defunct */
|
||||
void rt_thread_defunct_enqueue(rt_thread_t thread);
|
||||
rt_thread_t rt_thread_defunct_dequeue(void);
|
||||
|
||||
/*
|
||||
* spinlock
|
||||
*/
|
||||
struct rt_spinlock;
|
||||
|
||||
void rt_spin_lock_init(struct rt_spinlock *lock);
|
||||
void rt_spin_lock(struct rt_spinlock *lock);
|
||||
void rt_spin_unlock(struct rt_spinlock *lock);
|
||||
rt_base_t rt_spin_lock_irqsave(struct rt_spinlock *lock);
|
||||
void rt_spin_unlock_irqrestore(struct rt_spinlock *lock, rt_base_t level);
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef RT_USING_DEVICE
|
||||
/**
|
||||
* @addtogroup Device
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* device (I/O) system interface
|
||||
*/
|
||||
rt_device_t rt_device_find(const char *name);
|
||||
|
||||
rt_err_t rt_device_register(rt_device_t dev,
|
||||
const char *name,
|
||||
rt_uint16_t flags);
|
||||
rt_err_t rt_device_unregister(rt_device_t dev);
|
||||
|
||||
#ifdef RT_USING_HEAP
|
||||
rt_device_t rt_device_create(int type, int attach_size);
|
||||
void rt_device_destroy(rt_device_t device);
|
||||
#endif /* RT_USING_HEAP */
|
||||
|
||||
rt_err_t
|
||||
rt_device_set_rx_indicate(rt_device_t dev,
|
||||
rt_err_t (*rx_ind)(rt_device_t dev, rt_size_t size));
|
||||
rt_err_t
|
||||
rt_device_set_tx_complete(rt_device_t dev,
|
||||
rt_err_t (*tx_done)(rt_device_t dev, void *buffer));
|
||||
|
||||
rt_err_t rt_device_init (rt_device_t dev);
|
||||
rt_err_t rt_device_open (rt_device_t dev, rt_uint16_t oflag);
|
||||
rt_err_t rt_device_close(rt_device_t dev);
|
||||
rt_ssize_t rt_device_read(rt_device_t dev,
|
||||
rt_off_t pos,
|
||||
void *buffer,
|
||||
rt_size_t size);
|
||||
rt_ssize_t rt_device_write(rt_device_t dev,
|
||||
rt_off_t pos,
|
||||
const void *buffer,
|
||||
rt_size_t size);
|
||||
rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg);
|
||||
|
||||
/**@}*/
|
||||
#endif /* RT_USING_DEVICE */
|
||||
|
||||
/*
|
||||
* interrupt service
|
||||
*/
|
||||
|
||||
/*
|
||||
* rt_interrupt_enter and rt_interrupt_leave only can be called by BSP
|
||||
*/
|
||||
void rt_interrupt_enter(void);
|
||||
void rt_interrupt_leave(void);
|
||||
|
||||
/**
|
||||
* CPU object
|
||||
*/
|
||||
struct rt_cpu *rt_cpu_self(void);
|
||||
struct rt_cpu *rt_cpu_index(int index);
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
|
||||
/*
|
||||
* smp cpus lock service
|
||||
*/
|
||||
|
||||
rt_base_t rt_cpus_lock(void);
|
||||
void rt_cpus_unlock(rt_base_t level);
|
||||
void rt_cpus_lock_status_restore(struct rt_thread *thread);
|
||||
|
||||
#ifdef RT_USING_DEBUG
|
||||
rt_base_t rt_cpu_get_id(void);
|
||||
#else /* !RT_USING_DEBUG */
|
||||
#define rt_cpu_get_id rt_hw_cpu_id
|
||||
#endif /* RT_USING_DEBUG */
|
||||
|
||||
#else /* !RT_USING_SMP */
|
||||
#define rt_cpu_get_id() (0)
|
||||
|
||||
#endif /* RT_USING_SMP */
|
||||
|
||||
/*
|
||||
* the number of nested interrupts.
|
||||
*/
|
||||
rt_uint8_t rt_interrupt_get_nest(void);
|
||||
|
||||
#ifdef RT_USING_HOOK
|
||||
void rt_interrupt_enter_sethook(void (*hook)(void));
|
||||
void rt_interrupt_leave_sethook(void (*hook)(void));
|
||||
#endif /* RT_USING_HOOK */
|
||||
|
||||
#ifdef RT_USING_COMPONENTS_INIT
|
||||
void rt_components_init(void);
|
||||
void rt_components_board_init(void);
|
||||
#endif /* RT_USING_COMPONENTS_INIT */
|
||||
|
||||
/**
|
||||
* @addtogroup KernelService
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* general kernel service
|
||||
*/
|
||||
#ifndef RT_USING_CONSOLE
|
||||
#define rt_kprintf(...)
|
||||
#define rt_kputs(str)
|
||||
#else
|
||||
int rt_kprintf(const char *fmt, ...);
|
||||
void rt_kputs(const char *str);
|
||||
#endif /* RT_USING_CONSOLE */
|
||||
|
||||
rt_err_t rt_backtrace(void);
|
||||
rt_err_t rt_backtrace_thread(rt_thread_t thread);
|
||||
rt_err_t rt_backtrace_frame(rt_thread_t thread, struct rt_hw_backtrace_frame *frame);
|
||||
rt_err_t rt_backtrace_formatted_print(rt_ubase_t *buffer, long buflen);
|
||||
rt_err_t rt_backtrace_to_buffer(rt_thread_t thread, struct rt_hw_backtrace_frame *frame,
|
||||
long skip, rt_ubase_t *buffer, long buflen);
|
||||
|
||||
#if defined(RT_USING_DEVICE) && defined(RT_USING_CONSOLE)
|
||||
rt_device_t rt_console_set_device(const char *name);
|
||||
rt_device_t rt_console_get_device(void);
|
||||
#ifdef RT_USING_THREADSAFE_PRINTF
|
||||
rt_thread_t rt_console_current_user(void);
|
||||
#else
|
||||
rt_inline void *rt_console_current_user(void) { return RT_NULL; }
|
||||
#endif /* RT_USING_THREADSAFE_PRINTF */
|
||||
#endif /* defined(RT_USING_DEVICE) && defined(RT_USING_CONSOLE) */
|
||||
|
||||
int __rt_ffs(int value);
|
||||
|
||||
void rt_show_version(void);
|
||||
|
||||
#ifdef RT_DEBUGING_ASSERT
|
||||
extern void (*rt_assert_hook)(const char *ex, const char *func, rt_size_t line);
|
||||
void rt_assert_set_hook(void (*hook)(const char *ex, const char *func, rt_size_t line));
|
||||
void rt_assert_handler(const char *ex, const char *func, rt_size_t line);
|
||||
|
||||
#define RT_ASSERT(EX) \
|
||||
if (!(EX)) \
|
||||
{ \
|
||||
rt_assert_handler(#EX, __FUNCTION__, __LINE__); \
|
||||
}
|
||||
#else
|
||||
#define RT_ASSERT(EX)
|
||||
#endif /* RT_DEBUGING_ASSERT */
|
||||
|
||||
#ifdef RT_DEBUGING_CONTEXT
|
||||
/* Macro to check current context */
|
||||
#define RT_DEBUG_NOT_IN_INTERRUPT \
|
||||
do \
|
||||
{ \
|
||||
if (rt_interrupt_get_nest() != 0) \
|
||||
{ \
|
||||
rt_kprintf("Function[%s] shall not be used in ISR\n", __FUNCTION__); \
|
||||
RT_ASSERT(0) \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* "In thread context" means:
|
||||
* 1) the scheduler has been started
|
||||
* 2) not in interrupt context.
|
||||
*/
|
||||
#define RT_DEBUG_IN_THREAD_CONTEXT \
|
||||
do \
|
||||
{ \
|
||||
if (rt_thread_self() == RT_NULL) \
|
||||
{ \
|
||||
rt_kprintf("Function[%s] shall not be used before scheduler start\n", \
|
||||
__FUNCTION__); \
|
||||
RT_ASSERT(0) \
|
||||
} \
|
||||
RT_DEBUG_NOT_IN_INTERRUPT; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* "scheduler available" means:
|
||||
* 1) the scheduler has been started.
|
||||
* 2) not in interrupt context.
|
||||
* 3) scheduler is not locked.
|
||||
*/
|
||||
#define RT_DEBUG_SCHEDULER_AVAILABLE(need_check) \
|
||||
do \
|
||||
{ \
|
||||
if (need_check) \
|
||||
{ \
|
||||
if (rt_critical_level() != 0) \
|
||||
{ \
|
||||
rt_kprintf("Function[%s]: scheduler is not available\n", \
|
||||
__FUNCTION__); \
|
||||
RT_ASSERT(0) \
|
||||
} \
|
||||
RT_DEBUG_IN_THREAD_CONTEXT; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
#else
|
||||
#define RT_DEBUG_NOT_IN_INTERRUPT
|
||||
#define RT_DEBUG_IN_THREAD_CONTEXT
|
||||
#define RT_DEBUG_SCHEDULER_AVAILABLE(need_check)
|
||||
#endif /* RT_DEBUGING_CONTEXT */
|
||||
|
||||
rt_inline rt_bool_t rt_in_thread_context(void)
|
||||
{
|
||||
return rt_thread_self() != RT_NULL && rt_interrupt_get_nest() == 0;
|
||||
}
|
||||
|
||||
/* is scheduler available */
|
||||
rt_inline rt_bool_t rt_scheduler_is_available(void)
|
||||
{
|
||||
return rt_critical_level() == 0 && rt_in_thread_context();
|
||||
}
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
/* is thread bond on core */
|
||||
rt_inline rt_bool_t rt_sched_thread_is_binding(rt_thread_t thread)
|
||||
{
|
||||
if (thread == RT_NULL)
|
||||
{
|
||||
thread = rt_thread_self();
|
||||
}
|
||||
return !thread || RT_SCHED_CTX(thread).bind_cpu != RT_CPUS_NR;
|
||||
}
|
||||
|
||||
#else
|
||||
#define rt_sched_thread_is_binding(thread) (RT_TRUE)
|
||||
#endif
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __RT_THREAD_H__ */
|
228
rt-thread/include/rttypes.h
Normal file
228
rt-thread/include/rttypes.h
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2024-01-18 Shell Separate the basic types from rtdef.h
|
||||
*/
|
||||
|
||||
#ifndef __RT_TYPES_H__
|
||||
#define __RT_TYPES_H__
|
||||
|
||||
#include <rtconfig.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#ifndef RT_USING_NANO
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#if defined(RT_USING_SIGNALS) || defined(RT_USING_SMART)
|
||||
#include <sys/signal.h>
|
||||
#endif /* defined(RT_USING_SIGNALS) || defined(RT_USING_SMART) */
|
||||
#endif /* RT_USING_NANO */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* RT-Thread basic data types definition
|
||||
*/
|
||||
|
||||
typedef int rt_bool_t; /**< boolean type */
|
||||
typedef signed long rt_base_t; /**< Nbit CPU related data type */
|
||||
typedef unsigned long rt_ubase_t; /**< Nbit unsigned CPU related data type */
|
||||
|
||||
#ifndef RT_USING_ARCH_DATA_TYPE
|
||||
#ifdef RT_USING_LIBC
|
||||
typedef int8_t rt_int8_t; /**< 8bit integer type */
|
||||
typedef int16_t rt_int16_t; /**< 16bit integer type */
|
||||
typedef int32_t rt_int32_t; /**< 32bit integer type */
|
||||
typedef uint8_t rt_uint8_t; /**< 8bit unsigned integer type */
|
||||
typedef uint16_t rt_uint16_t; /**< 16bit unsigned integer type */
|
||||
typedef uint32_t rt_uint32_t; /**< 32bit unsigned integer type */
|
||||
typedef int64_t rt_int64_t; /**< 64bit integer type */
|
||||
typedef uint64_t rt_uint64_t; /**< 64bit unsigned integer type */
|
||||
#else
|
||||
typedef signed char rt_int8_t; /**< 8bit integer type */
|
||||
typedef signed short rt_int16_t; /**< 16bit integer type */
|
||||
typedef signed int rt_int32_t; /**< 32bit integer type */
|
||||
typedef unsigned char rt_uint8_t; /**< 8bit unsigned integer type */
|
||||
typedef unsigned short rt_uint16_t; /**< 16bit unsigned integer type */
|
||||
typedef unsigned int rt_uint32_t; /**< 32bit unsigned integer type */
|
||||
#ifdef ARCH_CPU_64BIT
|
||||
typedef signed long rt_int64_t; /**< 64bit integer type */
|
||||
typedef unsigned long rt_uint64_t; /**< 64bit unsigned integer type */
|
||||
#else
|
||||
typedef signed long long rt_int64_t; /**< 64bit integer type */
|
||||
typedef unsigned long long rt_uint64_t; /**< 64bit unsigned integer type */
|
||||
#endif /* ARCH_CPU_64BIT */
|
||||
#endif /* RT_USING_LIBC */
|
||||
#endif /* RT_USING_ARCH_DATA_TYPE */
|
||||
|
||||
#if defined(RT_USING_LIBC) && !defined(RT_USING_NANO)
|
||||
typedef size_t rt_size_t; /**< Type for size number */
|
||||
typedef ssize_t rt_ssize_t; /**< Used for a count of bytes or an error indication */
|
||||
#else
|
||||
typedef rt_ubase_t rt_size_t; /**< Type for size number */
|
||||
typedef rt_base_t rt_ssize_t; /**< Used for a count of bytes or an error indication */
|
||||
#endif /* defined(RT_USING_LIBC) && !defined(RT_USING_NANO) */
|
||||
|
||||
typedef rt_base_t rt_err_t; /**< Type for error number */
|
||||
typedef rt_uint32_t rt_time_t; /**< Type for time stamp */
|
||||
typedef rt_uint32_t rt_tick_t; /**< Type for tick count */
|
||||
typedef rt_base_t rt_flag_t; /**< Type for flags */
|
||||
typedef rt_ubase_t rt_dev_t; /**< Type for device */
|
||||
typedef rt_base_t rt_off_t; /**< Type for offset */
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef rt_base_t rt_atomic_t;
|
||||
#else
|
||||
#if defined(RT_USING_HW_ATOMIC)
|
||||
typedef rt_base_t rt_atomic_t;
|
||||
#elif defined(RT_USING_STDC_ATOMIC)
|
||||
#include <stdatomic.h>
|
||||
typedef atomic_intptr_t rt_atomic_t;
|
||||
#else
|
||||
typedef rt_base_t rt_atomic_t;
|
||||
#endif /* RT_USING_STDC_ATOMIC */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* boolean type definitions */
|
||||
#define RT_TRUE 1 /**< boolean true */
|
||||
#define RT_FALSE 0 /**< boolean fails */
|
||||
|
||||
/* null pointer definition */
|
||||
#define RT_NULL 0
|
||||
|
||||
/**
|
||||
* Double List structure
|
||||
*/
|
||||
struct rt_list_node
|
||||
{
|
||||
struct rt_list_node *next; /**< point to next node. */
|
||||
struct rt_list_node *prev; /**< point to prev node. */
|
||||
};
|
||||
typedef struct rt_list_node rt_list_t; /**< Type for lists. */
|
||||
|
||||
/**
|
||||
* Single List structure
|
||||
*/
|
||||
struct rt_slist_node
|
||||
{
|
||||
struct rt_slist_node *next; /**< point to next node. */
|
||||
};
|
||||
typedef struct rt_slist_node rt_slist_t; /**< Type for single list. */
|
||||
|
||||
/**
|
||||
* Spinlock
|
||||
*/
|
||||
#ifdef RT_USING_SMP
|
||||
#include <cpuport.h> /* for spinlock from arch */
|
||||
|
||||
struct rt_spinlock
|
||||
{
|
||||
rt_hw_spinlock_t lock;
|
||||
#ifdef RT_USING_DEBUG
|
||||
rt_uint32_t critical_level;
|
||||
#endif /* RT_USING_DEBUG */
|
||||
#if defined(RT_DEBUGING_SPINLOCK)
|
||||
void *owner;
|
||||
void *pc;
|
||||
#endif /* RT_DEBUGING_SPINLOCK */
|
||||
};
|
||||
|
||||
#ifndef RT_SPINLOCK_INIT
|
||||
#define RT_SPINLOCK_INIT {{0}} /* can be overridden by cpuport.h */
|
||||
#endif /* RT_SPINLOCK_INIT */
|
||||
|
||||
#else /* !RT_USING_SMP */
|
||||
|
||||
struct rt_spinlock
|
||||
{
|
||||
#ifdef RT_USING_DEBUG
|
||||
rt_uint32_t critical_level;
|
||||
#endif /* RT_USING_DEBUG */
|
||||
rt_ubase_t lock;
|
||||
};
|
||||
#define RT_SPINLOCK_INIT {0}
|
||||
#endif /* RT_USING_SMP */
|
||||
#if defined(RT_DEBUGING_SPINLOCK) && defined(RT_USING_SMP)
|
||||
|
||||
#define __OWNER_MAGIC ((void *)0xdeadbeaf)
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define __GET_RETURN_ADDRESS __builtin_return_address(0)
|
||||
#else /* !__GNUC__ */
|
||||
#define __GET_RETURN_ADDRESS RT_NULL
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#define _SPIN_LOCK_DEBUG_OWNER(lock) \
|
||||
do \
|
||||
{ \
|
||||
struct rt_thread *_curthr = rt_thread_self(); \
|
||||
if (_curthr != RT_NULL) \
|
||||
{ \
|
||||
(lock)->owner = _curthr; \
|
||||
(lock)->pc = __GET_RETURN_ADDRESS; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define _SPIN_UNLOCK_DEBUG_OWNER(lock) \
|
||||
do \
|
||||
{ \
|
||||
(lock)->owner = __OWNER_MAGIC; \
|
||||
(lock)->pc = RT_NULL; \
|
||||
} while (0)
|
||||
|
||||
#else /* !RT_DEBUGING_SPINLOCK */
|
||||
|
||||
#define _SPIN_LOCK_DEBUG_OWNER(lock) RT_UNUSED(lock)
|
||||
#define _SPIN_UNLOCK_DEBUG_OWNER(lock) RT_UNUSED(lock)
|
||||
#endif /* RT_DEBUGING_SPINLOCK */
|
||||
|
||||
#ifdef RT_DEBUGING_CRITICAL
|
||||
#define _SPIN_LOCK_DEBUG_CRITICAL(lock) \
|
||||
do \
|
||||
{ \
|
||||
(lock)->critical_level = rt_critical_level(); \
|
||||
} while (0)
|
||||
|
||||
#define _SPIN_UNLOCK_DEBUG_CRITICAL(lock, critical) \
|
||||
do \
|
||||
{ \
|
||||
(critical) = (lock)->critical_level; \
|
||||
} while (0)
|
||||
|
||||
#else /* !RT_DEBUGING_CRITICAL */
|
||||
#define _SPIN_LOCK_DEBUG_CRITICAL(lock) RT_UNUSED(lock)
|
||||
#define _SPIN_UNLOCK_DEBUG_CRITICAL(lock, critical) do {critical = 0; RT_UNUSED(lock);} while (0)
|
||||
|
||||
#endif /* RT_DEBUGING_CRITICAL */
|
||||
|
||||
#define RT_SPIN_LOCK_DEBUG(lock) \
|
||||
do \
|
||||
{ \
|
||||
_SPIN_LOCK_DEBUG_OWNER(lock); \
|
||||
_SPIN_LOCK_DEBUG_CRITICAL(lock); \
|
||||
} while (0)
|
||||
|
||||
#define RT_SPIN_UNLOCK_DEBUG(lock, critical) \
|
||||
do \
|
||||
{ \
|
||||
_SPIN_UNLOCK_DEBUG_OWNER(lock); \
|
||||
_SPIN_UNLOCK_DEBUG_CRITICAL(lock, critical); \
|
||||
} while (0)
|
||||
|
||||
typedef struct rt_spinlock rt_spinlock_t;
|
||||
|
||||
#define RT_DEFINE_SPINLOCK(x) struct rt_spinlock x = RT_SPINLOCK_INIT
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __RT_TYPES_H__ */
|
Reference in New Issue
Block a user