RT-Thread笔记记录

1、内核视频教程

https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/tutorial/kernel/kernel-video

2、RT-Thread的介绍

image

2.1 开发环境准备

KEIL MDK5.14及以上

2.2 源码获取

https://github.com/RT-Thread/rt-thread/

源码目录说明见下链接:

https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/tutorial/quick-start/src_code_introduction/rtthread_dir

image

2.3 工程源码目录文件

image

2.4 系统初次运行

image

先编译代码,再点击Debug,打开UART1窗口

2.5 RT-Thread系统启动过程

  • 进入Debug,指针停留在\(Sub\)$main()函数 真正的main()函数

  • rt_hw_interrupt_disable() 关中断操作

  • rtthread_startup() rtthread的真正启动函数

  • rt_hw_board_init() 对rtthread硬件平台的初始化

  • rt_show_version() 显示版本号的函数

  • rt_system_timer_init() rtthread

  • rt_system_scheduler_init() 系统调度器初始化

  • rt_system_signal_init() 系统信号机制初始化

  • rt_application_init() 用户在application函数中来创建

  • application函数很重要

  • main.c函数是在application函数中创建的

image

2.5.1 首先先调用系统初始化Systeminit()

2.5.2 调用\(Sub\)$mian()进入真正的main()函数

2.5.3 通过rtthread_startup()完成rt系统相关的初始化

2.5.4 然后调用rt_application_init()函数完成main.c的调用

2.6 通过观察rt_application_init()函数观察main()的建立

image

  • \(sub\)$main()函数对应了真正的main函数

  • \(super\)$main()函数对应了main.c中的main函数

image

在以下图片中的函数作为添加用户的应用代码 便可以

image

3、动态内存堆的使用

image

image

3.1 裸机系统动态内存

下图为裸机动态内存的分配
image

3.2 RTT动态内存

下图为RT-Thread操作系统的动态内存的分配
image

** 程序如下:**

image

实例如下:

image

动态内存使用之前的准备:

  • 首先配置好动态内存分配的区域,有外部RAM可以将外部RAM作为动态内存分配空间,若没有外部RAM,则可以用内部RAM

image

3.3 动态内存堆使用注意

  1. 内存复位

当我们每次申请到新的内存块之后,建议对所申请到的内存块进行清零操作。

  1. 内存泄露

指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

** 注意:**

在使用动态内存时需要注意** rt_malloc需要和rt_free配套使用**

3.4 其他相关API

  1. ** void *rt_realloc(void *rmem,rt_size_t newsize)**

    在已分配内存块的基础上重新分配内存块的大小(增加或减少),在进行重新分配内存块时,原来的内存块数据保持不变。

  2. ** void *rt_calloc(rt_size_t count,rt_size_t size)**

    从内存堆中分配连续内存地址的多个内存块。

4、线程的创建

image

** 线程是最基本的调度单位,描述了一个任务执行的运行环境。**

4.1 线程组成

image

image
线程控制块结构体如下图:
image
image

image

4.2 线程创建

4.2.1 两个API可以创建线程:** rt_thread_init()与rt_thread_create()**

  • rt_thread_init() 静态创建
  • rt_thread_create() 动态创建

4.2.2 一个API可以启动线程:rt_thread_startup()

  • 调用此函数后创建的线程会被加入到线程的就绪队列,执行调度。
    image

5、 跑马灯线程实例

5.1 线程状态切换

image

5.2 系统滴答时钟

image

** 程序中位置:**
image

5.3 GPIO驱动架构操作IO

image

  • void rt_pin_mode() 配置IO口的输出功能(三种输入,两种输出)
  • void rt_pin_write() 配置IO输出的高低电平
  • int rt_pin_read() 都相应的IO口

5.4 线程栈大小分配

image
** 通过命令list_sample**查看

5.5 线程分配技巧

image

6、 线程的时间片轮转调度

6.1 线程优先级

image

6.2 线程时间片

image

6.3 线程调度规则

image

7、空闲线程及两个常用的钩子函数

image

  • 空闲线程的代码在IDLE.c文件中

7.1 空闲线程钩子函数

7.1.1 设置钩子函数

rt_err_t rt_thread_idle_sethook(void(*hook)(void))

7.1.2 删除钩子函数

rt_err_t rt_thread_idle_delhook(void(*hook)(void))

7.2 钩子函数示例代码

7.3 空闲线程钩子函数使用注意

image

7.4 系统调度钩子函数

image

** rt_scheduler_sethook(void(*hook)(struct rt_thread from,struct rt_thread to))

7.5 系统调度钩子函数示例

8、临界区保护

8.1 临界资源

image

8.2 临界区

image

8.3 临界区保护

image

8.3.1 关闭系统调度

image

8.3.2 关闭系统中断

image

8.4 临界区保护示例

9 信号量的使用

9.1 IPC

image

posted @ 2021-07-01 17:01  登云上人间  阅读(8)  评论(0编辑  收藏  举报