浏览代码

[DM] Extended drivers MISC interface

1. RT_FIELD_PREP: prepare a bitfield element.
2. RT_FIELD_GET: extract a bitfield element.
3. rt_offsetof: member offset of a struct
4. rt_upper_32_bits: high 32 bits of value.
5. rt_lower_32_bits: lower 32 bits of value.
6. rt_upper_16_bits: high 16 bits of value.
7. rt_lower_16_bits: lower 16 bits of value.
8. rt_max_t: fix type of max(...).
9. rt_ilog2: integer logarithm base 2.

Signed-off-by: GuEe-GUI <2991707448@qq.com>
GuEe-GUI 11 月之前
父节点
当前提交
802a6ed2ca
共有 3 个文件被更改,包括 50 次插入1 次删除
  1. 32 0
      components/drivers/include/drivers/misc.h
  2. 1 0
      include/rtthread.h
  3. 17 1
      libcpu/aarch64/common/cpuport.c

+ 32 - 0
components/drivers/include/drivers/misc.h

@@ -12,6 +12,7 @@
 #define __MISC_H__
 
 #include <rtdef.h>
+#include <cpuport.h>
 
 #ifdef ARCH_CPU_64BIT
 #define RT_BITS_PER_LONG 64
@@ -33,6 +34,9 @@
             (((__x) - ((__d) / 2)) / (__d));    \
 })
 
+#define RT_FIELD_PREP(mask, val)    (((rt_uint64_t)(val) << (__rt_ffsl((mask)) - 1)) & (mask))
+#define RT_FIELD_GET(mask, val)     (((val) & (mask)) >> (__rt_ffsl((mask)) - 1))
+
 #define RT_BIT(n)               (1UL << (n))
 #define RT_BIT_ULL(n)           (1ULL << (n))
 #define RT_BIT_MASK(nr)         (1UL << ((nr) % RT_BITS_PER_LONG))
@@ -48,6 +52,13 @@
 
 #define RT_ARRAY_SIZE(arr)      (sizeof(arr) / sizeof(arr[0]))
 
+#define rt_offsetof(s, field)   ((rt_size_t)&((s *)0)->field)
+
+#define rt_upper_32_bits(n)     ((rt_uint32_t)(((n) >> 16) >> 16))
+#define rt_lower_32_bits(n)     ((rt_uint32_t)((n) & 0xffffffff))
+#define rt_upper_16_bits(n)     ((rt_uint16_t)((n) >> 16))
+#define rt_lower_16_bits(n)     ((rt_uint16_t)((n) & 0xffff))
+
 #define rt_min(x, y)            \
 ({                              \
     typeof(x) _x = (x);         \
@@ -71,6 +82,13 @@
     _x < _y ? _x: _y;           \
 })
 
+#define rt_max_t(type, x, y)    \
+({                              \
+    type _x = (x);              \
+    type _y = (y);              \
+    _x > _y ? _x: _y;           \
+})
+
 #define rt_clamp(val, lo, hi)   rt_min((typeof(val))rt_max(val, lo), hi)
 
 #define rt_do_div(n, base)              \
@@ -83,4 +101,18 @@
     _rem;                               \
 })
 
+#ifndef rt_ilog2
+rt_inline int rt_ilog2(rt_ubase_t v)
+{
+    int l = 0;
+
+    while ((1UL << l) < v)
+    {
+        l++;
+    }
+
+    return l;
+}
+#endif /* !rt_ilog2 */
+
 #endif /* __MISC_H__ */

+ 1 - 0
include/rtthread.h

@@ -787,6 +787,7 @@ rt_device_t rt_console_get_device(void);
 #endif /* defined(RT_USING_DEVICE) && defined(RT_USING_CONSOLE) */
 
 int __rt_ffs(int value);
+unsigned long __rt_ffsl(unsigned long value);
 
 void rt_show_version(void);
 

+ 17 - 1
libcpu/aarch64/common/cpuport.c

@@ -40,4 +40,20 @@ int __rt_ffs(int value)
 #endif
 }
 
-#endif /* RT_USING_CPU_FFS */
+unsigned long __rt_ffsl(unsigned long value)
+{
+#ifdef __GNUC__
+    return __builtin_ffsl(value);
+#else
+    if (!value)
+    {
+        return 0;
+    }
+
+    __asm__ volatile ("rbit %0, %0" : "+r" (value));
+
+    return __rt_clz(value);
+#endif
+}
+
+#endif /* RT_USING_CPU_FFS */