汇编
汇编.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)用作链接寄存器,用于存储子程序调用时的返回地址。如果返回地址存储在堆栈上,它也可以用作通用寄存器。 在异常处理模式...
杂项
杂项检查是否否是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)
系统定时器
系统定时器跳跃表 跳跃表是一种“随机”的数据结构,在很大的可能性下,它会得到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) }} 第一行设置了特殊符号’.’,这是位置计数器。如果您没有以其他方式指定输出部分...
调度
调度初始化 根据支持的最大优先级,初始化不同的链表 123456789for (offset = 0; offset < RT_THREAD_PRIORITY_MAX; offset ++){ rt_list_init(&rt_thread_priority_table[offset]);} 初始化就绪优先级组 优先级>32, 初始化线程就绪表 位图 软件实现 RT-Thread的位图调度算法分析 一种新的高效的寻找字节最低非0位的有效算法 硬件实现 1234567891011121314151617181920212223__asm int __rt_ffs(int value){ CMP r0, #0x00 // 比较寄存器r0和0,设置条件标志 BEQ exit // 如果r0等于0(即输入值为0),则跳转到exit标签 RBIT r0, r0 // 反转r0中的位,最低位变为最高位,最高位变为最低位 CLZ r...
预编译命令
预编译命令123456789101112131415161718192021#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 ...
内核对象
内核对象内核对象管理架构RT-Thread 采用内核对象管理系统来访问 / 管理所有内核对象,内核对象包含了内核中绝大部分设施,这些内核对象可以是静态分配的静态对象,也可以是从系统内存堆中分配的动态对象。 通过这种内核对象的设计方式,RT-Thread 做到了不依赖于具体的内存分配方式,系统的灵活性得到极大的提高。 RT-Thread 内核对象包括:线程,信号量,互斥量,事件,邮箱,消息队列和定时器,内存池,设备驱动等。对象容器中包含了每类内核对象的信息,包括对象类型,大小等。对象容器给每类内核对象分配了一个链表,所有的内核对象都被链接到该链表上,RT-Thread 的内核对象容器及链表如下图所示: 下图则显示了 RT-Thread 中各类内核对象的派生和继承关系。对于每一种具体内核对象和对象控制块,除了基本结构外,还有自己的扩展属性(私有属性),例如,对于线程控制块,在基类对象基础上进行扩展,增加了线程状态、优先级等属性。这些属性在基类对象的操作中不会用到,只有在与具体线程相关的操作中才会使用。因此从面向对象的观点,可以认为每一种具体对象是抽象对象的派生,继承了基本...
pipe
pipepipe: 匿名管道。pipe 是一种 IPC 机制,他的作用是用作有血缘进程间完成数据传递,只能从一端写入,从另外一端读出。为了解决 pipe 的弊端,linux 又引入了 mkfifo(实名管道)。 创建管道12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455rt_pipe_t *rt_pipe_create(constchar *name, intbufsz){ //分配管道内存,初始化锁,初始化等待队列,初始化条件变量 rt_mutex_init(&pipe->lock, name, RT_IPC_FLAG_FIFO); rt_wqueue_init(&pipe->reader_queue); rt_wqueue_init(&pipe->writer_queue); rt_condvar_init(&pipe->waitf...
内存管理
内存管理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...







