RT-THREAD官网内核视频笔记十六讲(1-12)V1.0(箭指320)

视频摘自
https://www.rt-thread.org/page/video.html
https://www.bilibili.com/video/av79513262?p=1

第二讲 MDK裸机系统动态内存配置和使用

board.c -> rt_system_heap_init((void)*HEAP_BEGIN,(void*)HEAP_END)

动态内存空间 64K RAM ->动态内存空间

Image$$RW_IRAM1$$ZI$$limit

内存起始地址
Map文件 : RW段+ZI段 RW+ZI

p=(char*)rt_malloc(10);
rt_free(p)

动态内存管理实例:分配动态内存空间
dynmem_sample 1<<i
p = rt_malloc(10);

rt = memset(p,0,10);

内存复位:清零操作
内存泄露:Memory Leak
rt_malloc 和 rt_free缓解到系统中去,rt_malloc和rt_free配合使用。

void *rt_realloc(void *rmem,rt_size_t newsize); //数据保持不变
rt_calloc(rt_size_t count ,rt_size_t size);  //count 块 count*size 空间

第三讲:线程的创建

RT-Thread线程三部曲:(1)线程代码(入口函数)(2)线程控制块(3)线程堆栈
线程代码(1)无线循环(2)顺序执行结构
线程控制块:数据结构 优先级 链表结构
创建线程必须有线程控制块:
创建线程:

rt_err_t rt_thread_init(struct rt_thread *thread
										const char *name,
										void (*entry)(void *parameter), //函数指针
										void *parameter,  //传入相关参数
										void *stack_start, //栈起始地址
										rt_uint32_t stack_size,//大小
										rt_uint8_t priority,//优先级
										rt_uint32_t tick)

实例化如下:

rt_thread_init(&thread2,
							"thread2",
							thread2_entry,
							RT_NULL,
							&thread2_stack[0],
							sizeof(thread2_stack),
							THREAD_PRIORITY-1,
							THREAD_TIMER_SLICE
							);

动态线程

rt_thread_t rt_thread_create(const char *name, //线程名称
				void  (*entry)(void *parameter),
				void *parameter,
				rt_uint32_t stack_size;
				rt_uint8_t priority,
				rt_uint32_t tick)

启动线程 rt_thread_startup()

tid1 = rt_thread_create("thread1",thread1_entry,RT_NULL,SIZE,PRIORITY,SLICE);

rt_thread_create不成功->0
thread2 1-9
静态需要栈和大小
静态线程VS动态线程
先定义 运行效率
线程状态切换
系统心跳时钟:Systick来完成的
RT_TICK_PER_SECOND SysTick_Handler.
drv_gpio.c 栈空间分配技巧。

第五讲 线程的时间片轮询调度

线程时间片轮询调度,优先级,时间片
STM32默认设置最大支持32个优先级,0为最高优先级。用户可以通过rt_config.h中的RT_THREAD_PRIORITY_MAX 线程时间片。
时间优先级抢占调度,时间片轮询调度 timeslice_sample.c

第六讲 空闲线程及两个常用的钩子函数

系统线程
空闲线程->永不循环->永不挂起
用户线程
Kernel->idle.c 空闲线程入口代码
空闲线程钩子函数
设置钩子函数

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

删除钩子函数

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

(1)设置空闲线程钩子(可以设置4个)

rt_thread_idle_sethook(idle_hook);

临界区保护 使用注意

rt_thread_delay()
rt_sem_take()

空闲线程可以设置多个函数,钩子函数指针,多个空间线程。
(2)系统调度函数(只能设置一个)

rt_schedule_sethook(void(*hook)(struct rt_thread *form,struct rt_thread*to))

设置调度器钩子函数 rt_scheduler_sethook(hook_of_scheduler);
from->name,to->name;

static void hook_of_scheduler(struct rt_thread*from,struct rt_thread*to)

第七讲:临界区保护
共享资源 变量 缓冲区
访问(操作)临界资源的代码称为临界区,我们每次只允许一个线程进入临界。
临界资源(Crttical Section)
关系系统调度保护临界区(1)禁止调度(2)关闭中断
互斥性保护临界区,信号量、互斥量
1.禁止调度 把调度器锁住
调度器上锁:

rt_enter_critical()

调度器解锁:

rt_exit_critical();

2.关闭中断
关闭中断

level = rt_hw_interrupt_disable();

/使能中断/

rt_hw_interrupt_enable(level);

第八讲:信号量的使用

线程和ISR
线程间通信(Internal Process Communication IPC)
IPC机制 信号量 互斥量 事件 邮箱 消息队列
需求:(1)同步(2)互斥(3)数据交互
信号量控制块

struct rt_semaphore
{
	struct_ipc_object parent;
	rt_uint16_t value;
}

定义静态信号量:struct rt_semaphore static_sem
定义动态信号量:rt_sem_t,dynamic_sem
信号量控制块 信号量
信号量API
rt_sem_t_sem函数 rt_err_t信号量为零不可用
释放信号量,信号量示例
动态信号量 RT_IPC_FLAG_FIFO
创建两个线程,信号量创建,线程中,中断中调用尝试take

第九讲 生产者 消费者问题

信号量用于解决生产者、消费者问题模型
在这里插入图片描述
示例代码:信号量 product&cosumer
1.初始化三个信号量 &sem_lock(互斥关系)二值信号量 sem_empty sem_full
2.创建生产者线程 互斥 同步
生产者互斥操作、缓冲区,流程:互斥
(1)获取一个空位empty
(2)上锁lock
(3)修改
(4)释放 release(&sem_lock)
(5)发布一个满位(sem_full)
创建生产者和消费者线程 同步中包含一个互斥
消费者线程(1)获取一个满位(2)上锁、操作、解锁(3)释放一个空位
第十讲-互斥量的使用
互斥量 互斥访问的IPC对象,二值信号量
互斥量LOCKER和UNLOCKER
互斥量控制块(数据结构)

struct rt_mutex
{
	struct rt_ipc_object parent;
	rt_uint16_t value;
	rt_uint8_t original_priority;
	rt_uint8_t hold;
	struct rt_thread *owner;
}

定义静态互斥量

struct_mutex static_mutex

定义动态变量

rt_mutex dynamic_mutex

互斥量的操作
初始化与脱离
创建与删除
init(rt_mutex mutex,const char *name,rt_uint8_t flag)
创建与删除
共享资源 线程1 线程2

rt_mutex_take(dynamic_mutex,RT_WATITING_FOREVER)
{
	number1++;
	rt_thread_mdelay(10);
	number2++;
	rt_mutex_release(dynamic_mutex);
}

1.信号量强调运行步骤,互斥量强调 许可和权限 信号量存在优先级反转的问题。

线程的优先级翻转

RT-THREAD 互斥量优先级继承算法
继承优先级继承,释放共享优先级
一个互斥量,三个线程 创建互斥锁

mutex = rt_mutex_create("mutex",RT_IPC_FLAG_FIFIO);

优先级翻转现象提醒:共享资源进行互斥代码应该尽可能短,低优先级快执行,释放共享资源。
P12 事件集的使用
事件集(1)特定事件唤醒事件(2)任意单个事件唤醒事件(3)多个事件同时发生才能唤醒事件
信号量:一对一线程同步 、
一对多,多对多,多对一 事件集合
逻辑或:独立型同步:线程与任何事件之一发生同步,只要有一个条件发生,即满足条件
事件集合控制块

struct rt_event
{
	struct rt_ipc_object parent;
	rt uint32_t set;
}

typedef struct rt_event *rt_event_t;
定义静态事件集合:

struct rt_event static_evt

定义动态事件集合:

rt_event_t dynamic_evt

初始化与脱离

rt_event_init(rt_event_t event,const char*name,rt_uint8_t flag)

事件集合使用示例
初始化事件对象

result = rt_event_init(&event,="event",RT_IPC_FLAG_FIFO)

创建两个线程(1)发送事件(2)接收事件

rt_event_recv(&event,
						EVENT_FLAG3|EVENT_FLAG5
						RT_EVENT_OR|RT_EVENT_FLAG_CLEAR
						RT_WAITING_FOREVER
						&e);

挂起,在接收事件,延时及挂起,最后这个流程比较烂。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值