内核对象
内核对象内核对象管理架构RT-Thread 采用内核对象管理系统来访问 / 管理所有内核对象,内核对象包含了内核中绝大部分设施,这些内核对象可以是静态分配的静态对象,也可以是从系统内存堆中分配的动态对象。 通过这种内核对象的设计方式,RT-Thread 做到了不依赖于具体的内存分配方式,系统的灵活性得到极大的提高。 RT-Thread 内核对象包括:线程,信号量,互斥量,事件,邮箱,消息队列和定时器,内存池,设备驱动等。对象容器中包含了每类内核对象的信息,包括对象类型,大小等。对象容器给每类内核对象分配了一个链表,所有的内核对象都被链接到该链表上,RT-Thread 的内核对象容器及链表如下图所示: 下图则显示了 RT-Thread 中各类内核对象的派生和继承关系。对于每一种具体内核对象和对象控制块,除了基本结构外,还有自己的扩展属性(私有属性),例如,对于线程控制块,在基类对象基础上进行扩展,增加了线程状态、优先级等属性。这些属性在基类对象的操作中不会用到,只有在与具体线程相关的操作中才会使用。因此从面向对象的观点,可以认为每一种具体对象是抽象对象的派生,继承了基本...
内存管理
内存管理https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/memory/memory 初始化1.rt_system_heap_init 对堆开始地址与结束地址进行内存对齐 在ART-PI中将所有剩余ROM划分给堆使用 断言堆设置是否正常 根据配置的内存策略 使用 _MEM_INIT 初始化多线程争用锁 小内存管理算法 小内存算法在分配内存的时候,随着内存碎片的增多,分配速度会越来越慢,当总的内存太大的时候,内存碎片的数量可能会更多,此时这种算法就会变得不再适用。 小内存管理算法主要针对系统资源比较少,一般用于小于 2MB 内存空间的系统 每个内存对象的起始12字节不可使用,设置为堆系统的配置 1234567891011121314151617//这是一个掩码,用于将内存地址的最低位清零。在 RTT 的内存管理中,内存块的地址的最低位被用作标记该内存块是否被使用。#define MEM_MASK 0xffff...
宏
宏编译警告宏1234/* compile time assertion */#define RT_STATIC_ASSERT(name, expn) typedef char _static_assert_##name[(expn)?1:-1]expn:判断条件;当条件不满足时;数组的长度初始化为-1,即编译报错; 用#waring 编译判断更为合理 宏过载123456789101112131415#define __MSH_GET_MACRO(_1, _2, _3, _FUN, ...) _FUN/** * @ingroup msh * * This macro exports a command to module shell. * * @param command is the name of the command. * @param desc is the description of the command, which will show in help list. * @param opt This is an option, enter any conten...
工作队列
工作队列工作队列内部有一个工作链表(worklist),链表上有多个工作项(work item)节点,我们可以将工作项简单理解为函数,因此工作链表上就存储着一系列待执行的函数。而且工作队列内有个线程一直在轮询工作链表,每次都从工作链表中取出一个工作项,并执行其相关联的函数。当工作队列为空时,线程会被挂起。 1234567891011121314151617181920212223242526272829303132333435363738394041424344/* workqueue implementation */struct rt_workqueue{ rt_list_t work_list; rt_list_t delayed_list; struct rt_work *work_current; /* current work */ struct rt_semaphore sem; rt_thread_t work_thread; struct rt_spinlock spinlock;}...
杂项
杂项检查是否否是2的幂 检查sz_blk是否是2的幂。原理如下: 如果一个数是2的幂,那么它的二进制表示中只有一个位是1,其余都是0。例如,2(10),4(100),8(1000)等。当我们从这个数中减去1时,所有从最右边的1开始到最左边的所有位都会翻转。例如,4(100)减去1变成3(011)。因此,如果一个数是2的幂,那么这个数与它自己减去1的结果进行位与运算,会得到0。因为没有位同时在两个数中都是1。反之,如果一个数不是2的幂,那么它至少有一个位不是1,这样减去1之后,至少有一个位在两个数中都是1,位与运算的结果不为0。这个技巧在编程中经常被用来快速检查一个数是否是2的幂,因为它比循环或递归方法更高效。 1#define IS_POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0)
数据结构
数据结构 二叉搜索树、B树、B+树、AVL树、红黑树 树堆(Treap)和红黑树(RB-Tree)各有哪些优劣?
汇编
汇编.s文件https://zhuanlan.zhihu.com/p/98888285 汇编指令BX BX指令:在ARM汇编语言中,BX指令用于跳转到指令中所指定的目标地址。这个目标地址可以是ARM指令,也可以是Thumb指令。BX指令的格式为:BX {条件} 目标地址。这个指令的特点是它可以改变处理器的状态,从ARM状态切换到Thumb状态,或者从Thumb状态切换到ARM状态。这种状态切换的功能使得BX指令在实现子程序调用和处理器工作状态切换时非常有用。 LR链接寄存器 LR链接寄存器:在ARM架构中,链接寄存器(Link Register,简称LR)通常用于存储子程序返回地址。当执行BL(带返回的跳转指令)或BLX(带返回和状态切换的跳转指令)时,处理器会将下一条指令的地址保存到LR中。然后,当子程序执行完毕后,可以通过将LR的内容加载到程序计数器(PC)中,从而返回到调用者。这种机制使得子程序的调用和返回变得非常方便和高效。 在用户模式下,LR(或R14)用作链接寄存器,用于存储子程序调用时的返回地址。如果返回地址存储在堆栈上,它也可以用作通用寄存器。 在异常处理模式...
系统定时器
系统定时器跳跃表 跳跃表是一种“随机”的数据结构,在很大的可能性下,它会得到O(log(N))的时间复杂度,而旧的列表得到O(N)。此外,当将RT_TIMER_SKIP_LIST_LEVEL设置为1时,它将与旧的双链表相同,无论是时间还是空间复杂性。基准测试表明,当RT_TIMER_SKIP_LIST_LEVEL为3时,当有100个计时器时,随机插入新计时器的平均时间比旧计时器快2倍,当有200个计时器时快3倍。但是,它恢复已弃用的函数rt_system_timer_init。bsp必须在系统启动时调用它。 定时器跳表 (Skip List) 算法在前面介绍定时器的工作方式的时候说过,系统新创建并激活的定时器都会按照以超时时间排序的方式插入到 rt_timer_list 链表中,也就是说 t_timer_list 链表是一个有序链表,RT-Thread 中使用了跳表算法来加快搜索链表元素的速度。 跳表是一种基于并联链表的数据结构,实现简单,插入、删除、查找的时间复杂度均为 O(log n)。跳表是链表的一种,但它在链表的基础上增加了 “跳跃” 功能,正是这个功能,使得在查找元素...
线程
线程线程创建 初始化上下文信息 将栈初始化为 #号 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit){ struct stack_frame *stack_frame; rt_uint8_t *stk; unsignedlong i; stk = stack_addr + sizeof(rt_uint32_t); ...
链接文件
链接文件参考链接https://home.cs.colorado.edu/~main/cs1300/doc/gnu/ld_toc.html _stext 和 _etext stext 和 _etext 符号通常用于表示内核代码段的开始和结束位置。 1234//定义了一个符号。这个符号的值等于当前的位置计数器(.),也就是 .text 段的起始地址。_stext = .;//定义了一个符号。这个符号的值等于当前的位置计数器(.),也就是 .text 段的结束地址。_etext = .; “.”与”*符号作用1234567891011121314151617SECTIONS{ . = 0x10000; .text : { *(.text) } . = 0x8000000; .data : { *(.data) } .bss : { *(.bss) }} 第一行设置了特殊符号’.’,这是位置计数器。如果您没有以其他方式指定输出部分...