自由分配的内存(堆)起始地址为RAM的起始地址加上RW+ZI段后的地址区域。html
编译出的program size分为:数组
实际占用空间状况为:数据结构
板子上电后默认从flash启动,启动以后会将RW段中的RW-data(初始化的全局变量)搬运到RAM中,但不会搬运RO段,即CPU的执行代码从flash中读取,另外根据编译器给出的ZI地址和大小,分配出ZI段,并将这块RAM区域清零。动态内存堆为未使用的RAM空间,应用程序申请和释放的内存都来自该空间
架构
char *ptr; ptr = rt_malloc(10); if (ptr != RT_NULL) { rt_memset(ptr, 0, 10); rt_kprintf("malloc success\n"); rt_free(ptr); ptr = RT_NULL; }
RT-Thread中,线程由三部分组成:线程代码(入口函数)、线程控制块、线程堆栈app
无限循环结构 void thread_entry(void *parameter) { while(1) { /* 等待事件发生 */ /* 处理事件 */ } } 顺序执行结构 void thread_entry(void *parameter) { /* 事务1处理 */ /* 事务2处理 */ /* 事务3处理 */ }
操做系统管理线程的一个数据结构。存放线程的一些信息,好比优先级、线程名称、线程状态等等,也包括线程与线程之间链接用的链表结构,线程等待时间集合等ide
struct rt_thread; struct rt_thread *rt_thread_t;
每一个线程都有独立的栈空间,线程切换时,系统会将当前线程的上下文保存在线程栈中,当线程要恢复运行时,再从线程栈中读取上下文信息,恢复线程的运行。线程上下文是指线程执行时的环境,各个变量和数据包括全部的寄存器变量,堆栈信息,内存信息等。线程栈在形式上是一段连续的内存空间,能够经过定义一个数组或者申请一段动态内存来做为线程的栈
建立线程:函数
建立静态线程 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_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_err_t rt_thread_startup(rt_thread_t thread) 调用此函数后建立的线程会被加入到线程的就绪队列,执行调度 rt_err_t thread_static_init() { rt_err_t result; result = rt_thread_init(&thread, "test", thread_entry, RT_NULL, &thread_stack[0], sizeof(thread_stack), THREAD_PRIORITY, 10); if (result == RT_EOK) rt_thread_startup(&thread); else tc_stat(TC_STAT_END | TC_STAT_FAILED); return result; } int thread_dynamic_init() { rt_thread_t tid; tid = rt_thread_create("test", thread_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); if (tid != RT_NULL) rt_thread_startup(tid); else tc_stat(TC_STAT_END | TC_STAT_FAILED); return 0; } rt_thread_delay(15); // 根据时钟频率决定。时钟频率100HZ,那么一次delay 10ms.此处就未150ms rt_thread_sleep(15); rt_thread_mdelay(15); // delay 15ms
区别:ui
心跳时钟由硬件定时器的定时中断产生。称之为系统滴答或者时钟节拍。其频率须要根据CPU的处理能力来决定。始终街拍使得内核能够将线程延时若干个时钟节拍,以及线程等待时间发生时,超时的依据。频率越快,内核函数介入系统运行的几率越大,内核占用的处理器时间就越长,系统的负荷就越大。频率越小,时间处理精度又不够。在stm32平台上通常设置系统滴答频率为100HZ,即每一个滴答的时间是10ms。在rtconfig.h中的RT_TICK_PER_SECOND宏,就是表明的HZ数操作系统
#include <rt_device.h> IO初始化 void rt_pin_mode(rt_base_t pin, rt_base_t mode) PIN_MODE_OUTPUT PIN_MODE_INPUT PIN_MODE_INPUT_PULLUP PIN_MODE_INPUT_PULLDOWN PIN_MODE_OUTPUT_OD IO写入 void rt_pin_write(rt_base_t pin, rt_base_t value) PIN_HIGH PIN_LOW IO读出 int rt_pin_read(rt_base_t pin) 首先经过看drv_gpio.c中的宏,得知咱们设置的芯片有多少个脚。再看__STM32_PIN(2, E, 4).那么这里传入2,就表示要操做PE4引脚
使用msh中的命令:list_thread。列出当前全部线程的栈使用状况
能够先将线程栈大小设置一个固定值(好比2048),在线程运行时经过该命令查看线程栈的使用状况,了解线程栈使用的实际状况,根据状况设置合理的大小。通常将线程栈最大使用量设置为70%线程
分别描述了线程竞争处理器资源的能力和持有处理器时间长短的能力。RT-Thread最大支持256个优先级,数值越小优先级越高,0为最高优先级,最低优先级保留给空闲线程idle。能够经过rt_config.h中的RT_THREAD_PRIORITY_MAX宏,修改最大支持的优先级。针对STM32默认设置最大支持32个优先级。具体应用中,线程总数不受限制,能建立的线程总数之和具体硬件平台的内存有关
只有在相同优先级的就绪态线程中起做用,时间片起到约束线程单次运行时长的做用,其单位是一个系统街拍(OS Tick)
当有高优先级线程处于就绪态后,就会发生任务调度
相同优先级的线程,操做系统按照时间片大小轮流调度线程,时间片起到约束线程单次运行时长的做用。保证同优先级任务轮流占有处理器
特殊的系统线程,具备最低的优先级。系统中无其余就绪线程可运行时,调度器将调度到空闲线程。空闲线程负责一些系统资源回收以及将一些处于关闭态的线程从线程调度列表中移除的动做。空闲线程在形式上是一个无限循环结构,且永远不被挂起。在RT-Thread实时操做系统中空闲线程向用户提供了钩子函数,空闲线程钩子函数能够在系统空闲的时候,执行一些非紧急事务,例如系统运行指示灯闪烁,CPU使用率统计等等
rt_err_t rt_thread_idle_sethook(void(*hook)(void)) rt_err rt_thread_idle_delhook(void(*hook)(void))
注意:
系统上下文切换是最广泛的时间,若是用户想知道在某一个时刻发生了什么样的线程切换,RT-Thread提供了一个系统调度钩子函数,这个钩子函数在系统进行任务切换时运行,经过这个钩子函数,能够了解到系统任务调度时的信息
rt_scheduler_sethook(void(*hook)(struct rt_thread *from, struct rt_thread *to))
本文做者: CrazyCatJack
本文连接: https://www.cnblogs.com/CrazyCatJack/p/14408835.html
版权声明:本博客全部文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
关注博主:若是您以为该文章对您有帮助,能够点击文章右下角推荐一下,您的支持将成为我最大的动力!