复习一下RTOS吧,本文完全参考RT_thread官方教程

1.内存
  1. 栈stack:由编译器自动分配释放 比如 int a
  2. 堆heap:由程序员分配和释放 比如 malloc函数
  3. 动态内存空间:rt_system_heap_init(begin_addr,end_addr)
  4. 动态内存申请
    char p;
    p=(char
    )rt_malloc(10);
    rt_free( p);
  5. 内存复位:申请到的内存块,清零操作,确保没有东西在里面:
    rt_memset(p,0,10);
  6. 内存泄漏解决方案:
    malloc和free配套使用
2.线程
  1. 三部分组成:线程代码(入口函数),线程控制块,线程堆栈
  2. 入口函数:
    void rtread_enter(viod *parameter)
    {
    }
  3. 动态线程的创建:rt_rtread_create();
  4. 详细参数
1
2
3
4
5
6
7
 rt_thread_t rt_thread_create(const char *name,
void (*entry)(void *parameter),
void *parameter, //参数
rt_uint_t stack_size,
rt_uint8_t stack_size,
rt_uint8_t priority,
rt_uint32_t tick)
  1. 启动线程:
    rt_err_t rt_thread_startup(rt_thread_t thread)
3.状态切换
  1. 就绪到挂起:suspend
    挂起到关闭:delete,detach
    运行到关闭:exit
    4.系统时钟
  2. 系统滴答定时器:心跳 100hz
    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq();
    systick_cofing 滴答的频率第二个参数100
    5.gpio的架构
  3. void rt_pin_mode(rt_base_pin,mode)
    6.延时的api:
  4. rt_thread_delay(50)
    rt_thread_mdelay(500)
    rt_rtthread_sleep(50)
7.事件片及优先级
  1. 时间片参数:持有处理器时间长短的能力 时钟节拍为单位
    优先级相同的情况下,时间片长占cpu时间长
  2. 优先级:线程竞争处理器资源的能力 256
    最大设置:RT_THREAD_PRIORITY_MAX宏
    stm32:32个
8.空闲线程和钩子函数
  1. 空闲线程:系统线程,最低优先级
    资源回收,移除关闭线程 idle.C

  2. 钩子函数:让系统在空闲线程的时候执行一些非紧急的事务,比如让LED灯闪烁等
    设置:rt_err_t rt_thread_idle_sethook(void(*hook)(void))
    删除:rt_err_t rt_thread_idle_delhook(void(*hook)(void))
    钩子函数不能够被挂起

  3. 系统调度钩子函数:任务切换时运行,打印调度信息
    rt_scheduler_sethook(void(*hook)(struct rt_thread *from,struct rt_thread *to)
    rt_err_t rt_thread_idle_delhook(void(*hook)(void))

    9. 临界
  4. 临界资源:一次仅允许一个线程访问的共享资源,他可以是一个具体的硬件设备,也可以是变量,缓冲区

  5. 临界区:每个线程中访问(操作)临界资源的那段代码称为临界区,我们只允许一个线程进入临界区

  6. 两种保护方式:
    1:关闭系统调度保护临界区:把调度器锁住,不让进行调度
    rt_enter_critical();

    rt_exit_critical();

    2:关闭中断保护临界区:任务调度都是建立在中断的基础上的
    rt_base_t lever;
    lever = rt_hw_interrupt_disable();
    rt_hw_interrupt_enable();

    10.IPC

    进程间通信
    信号量,互斥量,事件,邮箱,消息队列

11.信号量

停车厂管理

  1. 控制块定义
1
2
3
4
5
6
7
8
9
10
struct rt_semaphore
{
struct rt_ipc_object parent;
rt_uint16_t value;
};
typedef struct rt_semaphore *rt_sem_t;

静态:struct rt_semaphore static_sem
动态:rt_sem_t dynamic_sem

  1. 静态信号量的操作初始化与脱离
1
2
3
4
rt_err_t rt_sem_init(rt_sem_t    sem,   //信号量指针
const char *name, //信号量名称
rt_uint32_t value, //初始值
rt_uint8_t flag); //标志

flag:
RT_IPC_FLAG_FIFO 先进先出排队
RT_IPC_FALG_PRIO 优先级排队

1
rt_err_t rt_sem_detach(rt_sem_t sem);
  1. 动态信号量的创建与删除
1
2
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);
  1. 获取信号量
1
2
rt_err_t rt_sem_take(rt_sem_t sem, rt_int32_t time);
rt_err_t rt_sem_trytake(rt_sem_t sem);
  1. 释放
1
rt_err_t rt_sem_release(rt_sem_t sem);
12.生产和消费者关系

生产者和消费者关系:同步2个信号量和互斥1个信号量
空,满
两只手:空位一手放东西,满位一手告诉对方是否可以拿

13.互斥量的使用:

线程间的互斥访问

  1. 互斥量控制块:
1
2
3
4
5
6
7
8
9
10
11
struct rt_mutex
{
struct rt_ipc_object parent;
rt_unint16_t value;
rt_uint8_t original_priority;
rt_uint8_t hold;
struct rt_thread *owner;
}
定义静态:struct _rt_mutex static_mutex
定义动态:rt_mutex_t dynamic_mutex

  1. 注意:只有由持有他的线程释放!
14.线程的优先级翻转

高优先级的线程,用到的资源是低优先级的资源。则先去执行低优先级的任务,然后又更加优先级,去执行中优先级的任务。

15.优先级继承:

把低优先级任务的优先级提高和高优先级任务的优先级一样。

16.事件集event

一个32位的数,每一位代表一个信号量,接收事件位有:与或方式

17.邮箱mailbox

一个线程往邮箱里发送数据or地址,另一个线程从邮箱中拿出来使用。

18.消息队列:

对邮箱的扩展,接收来自线程和中断服务例程的不固定长度消息,并保存在自己内存,其他线程可以从消息队列中读取消息并进行处理。

  1. 链表头,链表尾,空闲链表。
    紧急消息放在消息头,一般消息放空闲链表。
  2. 消息队列控制块:struct rt_messsagequeue
    19.软件定时器:系统节拍(os tick)
    中断环境:HARDTIMER模式
    TIMER线程:SOFTTIMER模式
    20.内存池
    内存资源分配.