中断服务程序

【TencentOS tiny】深度源码分析(2)——调度器

百般思念 提交于 2019-12-01 13:43:37
温馨提示:本文不描述与浮点相关的寄存器的内容,如需了解自行查阅(毕竟我自己也不懂) 调度器的基本概念 TencentOS tiny 中提供的任务调度器是基于优先级的全抢占式调度,在系统运行过程中,当有比当前任务优先级更高的任务就绪时,当前任务将立刻被 切出 ,高优先级任务 抢占 处理器运行。 TencentOS tiny 内核中也允许创建相同优先级的任务。相同优先级的任务采用时间片轮转方式进行调度(也就是通常说的分时调度器),时间片轮转调度仅在当前系统中 无更高优先级就绪任务 的情况下才有效。 为了保证系统的实时性,系统尽最大可能地保证高优先级的任务得以运行。任务调度的原则是一旦任务状态发生了改变,并且当前运行的任务优先级小于优先级队列中任务最高优先级时,立刻进行任务切换(除非当前系统处于中断处理程序中或禁止任务切换的状态)。 调度器是操作系统的 核心 ,其主要功能就是 实现任务的切换 ,即从就绪列表里面 找到 优先级最高的任务,然后去 执行 该任务。 启动调度器 调度器的启动由 cpu_sched_start 函数来完成,它会被 tos_knl_start 函数调用,这个函数中主要做两件事,首先通过 readyqueue_highest_ready_task_get 函数获取当前系统中处于最高优先级的就绪任务,并且将它赋值给指向当前任务控制块的指针 k_curr_task

STM32之串口DMA接收不定长数据

风流意气都作罢 提交于 2019-12-01 13:37:59
STM32之串口DMA接收不定长数据 引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口中断,在中断中读取数据就行了! 中断就是打断程序正常运行,怎么能保证高效呢?经常把主程序打断,主程序还要不要运行了? 同学B:串口可以配置成用DMA的方式接收数据,等接收完毕就可以去读取了! 这个同学是对的,我们可以使用DMA去接收数据,不过DMA需要定长才能产生接收中断,如何接收不定长的数据呢? DMA简介 题外话:其实,上面的问题是很有必要思考一下的,不断思考,才能进步。 什么是DMA DMA :全称Direct Memory Access,即直接存储器访问 DMA 传输将数据从一个地址空间复制到另外一个地址空间。CPU只需初始化DMA即可,传输动作本身是由 DMA 控制器来实现和完成。典型的例子就是移动一个外部内存的区块到芯片内部更快的内存区。这样的操作并没有让处理器参与处理,CPU可以干其他事情,当DMA传输完成的时候产生一个中断,告诉CPU我已经完成了,然后CPU知道了就可以去处理数据了,这样子提高了CPU的利用率,因为CPU是大脑,主要做数据运算的工作,而不是去搬运数据。DMA 传输对于高效能嵌入式系统算法和网络是很重要的。 在STM32的DMA资源 STM32F1系列

从0开始学FreeRTOS-(任务调度)-4

岁酱吖の 提交于 2019-12-01 10:20:53
大家晚上好,我是杰杰,最近挺忙的,好久没有更新了,今天周末就吐血更新一下吧! 前言 FreeRTOS 是一个是实时内核,任务是程序执行的最小单位,也是调度器处理的基本单位,移植了 FreeRTOS ,则避免不了对任务的管理,在多个任务运行的时候,任务切换显得尤为重要。而任务切换的效率会决定了系统的稳定性与效率。 FreeRTOS 的任务切换是干嘛的呢, rtos 的实际是永远运行的是具有最高优先级的运行态任务,而那些之前在就绪态的任务怎么变成运行态使其得以运行呢,这就是我们 FreeRTOS 任务切换要做的事情,它要做的是找到最高优先级的就绪态任务,并且让它获得cpu的使用权,这样,它就能从就绪态变成运行态,这样子,整个系统的实时性就会很好,响应也会很好,而不会让程序阻塞卡死。 要知道怎么实现任务切换,那就要知道任务切换的机制,在不同的 cpu(mcu) 中,触发的方式可能会不一样,现在是以Cortex-M3为例来讲讲任务的切换。为了大家能看懂本文,我就抛转引玉一下, 引用《Cortex-M3权威指南-中文版》的部分语句(如涉及侵权,请联系杰杰删除) SVC 和 PendSV SVC(系统服务调用,亦简称系统调用)和 PendSV ( Pended System Call ,可悬起系统调用),它们多用于在操作系统之上的软件开发中。 SVC 用于产生系统函数的调用请求。例如

从单片机到操作系统⑦——深入了解FreeRTOS的延时机制

半世苍凉 提交于 2019-12-01 10:20:50
没研究过操作系统的源码都不算学过操作系统 FreeRTOS 时间管理 时间管理包括两个方面:系统节拍以及任务延时管理。 系统节拍: 在前面的文章也讲得很多,想要系统正常运行,那么时钟节拍是必不可少的, FreeRTOS 的时钟节拍通常由 SysTick 提供,它周期性的产生定时中断,所谓的时钟节拍管理的核心就是这个定时中断的服务程序。 FreeRTOS 的时钟节拍isr中核心的工作就是调用 vTaskIncrementTick() 函数。具体见上之前的文章。 延时管理 FreeRTOS提供了两个系统延时函数: 相对延时函数 vTaskDelay() 绝对延时函数 vTaskDelayUntil() 。 这些延时函数可不像我们以前用裸机写代码的延时函数操作系统不允许CPU在死等消耗着时间,因为这样效率太低了。 同时,要告诫学操作系统的同学,千万别用裸机的思想去学操作系统。 任务延时 任务可能需要延时,两种情况,一种是任务被 vTaskDelay 或者 vTaskDelayUntil 延时,另外一种情况就是任务等待事件(比如等待某个信号量、或者某个消息队列)时候指定了 timeout (即最多等待timeout时间,如果等待的事件还没发生,则不再继续等待),在每个任务的循环中都必须要有阻塞的情况出现,否则比该任务优先级低的任务就永远无法运行。 相对延时与绝对延时的区别 相对延时

从0开始学FreeRTOS-(任务调度)-4

杀马特。学长 韩版系。学妹 提交于 2019-12-01 10:19:26
大家晚上好,我是杰杰,最近挺忙的,好久没有更新了,今天周末就吐血更新一下吧! # 前言 `FreeRTOS`是一个是实时内核,任务是程序执行的最小单位,也是调度器处理的基本单位,移植了`FreeRTOS`,则避免不了对任务的管理,在多个任务运行的时候,任务切换显得尤为重要。而任务切换的效率会决定了系统的稳定性与效率。 `FreeRTOS`的任务切换是干嘛的呢,`rtos`的实际是永远运行的是具有最高优先级的运行态任务,而那些之前在就绪态的任务怎么变成运行态使其得以运行呢,这就是我们`FreeRTOS`任务切换要做的事情,它要做的是找到最高优先级的就绪态任务,并且让它获得cpu的使用权,这样,它就能从就绪态变成运行态,这样子,整个系统的实时性就会很好,响应也会很好,而不会让程序阻塞卡死。 要知道怎么实现任务切换,那就要知道任务切换的机制,在不同的`cpu(mcu)`中,触发的方式可能会不一样,现在是以Cortex-M3为例来讲讲任务的切换。为了大家能看懂本文,我就抛转引玉一下,`引用《Cortex-M3权威指南-中文版》的部分语句(如涉及侵权,请联系杰杰删除)` # SVC 和 PendSV SVC(系统服务调用,亦简称系统调用)和 `PendSV`(`Pended System Call`,可悬起系统调用),它们多用于在操作系统之上的软件开发中。`SVC`

进程上下文与中断上下文

对着背影说爱祢 提交于 2019-12-01 06:39:45
进程上下文与中断上下文 https://www.cnblogs.com/alantu2018/p/8461094.html 有进程上下文切换 也有 模式切换 不通的切换的损耗是不一样的 上下文切换时 堆栈信息 寄存器信息 用户信息都得切换 其实代价还是很高的. 1、前言   最近在学习linux内核方面的知识,经常会看到用户空间与内核空间及进程上下文与中断上下文。看着很熟悉,半天又说不出到底是怎么回事,有什么区别。看书过程经常被感觉欺骗,似懂非懂的感觉,很是不爽,今天好好结合书和网上的资料总结一下,加深理解。 2、用户空间与内核空间      我们知道现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操心系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核,保证内核的安全,操心系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。针对linux操作系统而言,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为内核空间,而将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为用户空间。每个进程可以通过系统调用进入内核,因此,Linux内核由系统内的所有进程共享

【转帖】Linux 内核系统架构

孤街浪徒 提交于 2019-11-30 06:21:18
Linux 内核系统架构 描述Linux内核的文章已经有上亿字了 但是对于初学者,还是应该多学习多看,毕竟上亿字不能一下子就明白的。 即使看了所有的Linux 内核文章,估计也还不是很明白,这时候,还是需要fucking the code. 28年前(1991年8月26日)Linus公开Linux的代码,开启了一个伟大的时代。这篇文章从进程调度,内存管理,设备驱动,文件系统,网络等方面讲解Linux内核系统架构。Linux的系统架构是一个经典的设计,它优秀的分层和模块化,融合了数量繁多的设备和不同的物理架构,让世界各地的内核开发者能够高效并行工作。先来看看Linus在多年前公开Linux的邮件。 "Hello everybody out there using minix - I’m doing a (free) operating system (just a hobby, won’t be big and professional like gnu) for 386(486) AT clones. This has been brewing since april, and is starting to get ready. I’d like any feedback on things people like/dislike in minix, as my OS

I/O模型之阻塞(在中断基础上------jz2440)

江枫思渺然 提交于 2019-11-30 04:25:20
1 阻塞: 在应用层调用read函数的时候,如果硬件中的数据没有准备好,此时进程会进入休眠状态,当硬件的数据准备好的时候会给驱动发送中断。驱动收到中断之后,唤醒休眠的进程。这个被唤醒的进程在driver_read读取硬件的数据,并把数据 返回到用户空间。(模型中断) 可以使用队列,把整个进程进入到队列中,使进程进入阻塞的状态,当有数据产生的时候,产生中断,唤醒在队列中的进程,从而读取数据. 队列: wait_queue_head_t wq //定义等待队列头 init_waitqueue_head(&wq) //初始化等待队列头 wait_event(wq, condition) //不可中断的等待态 wait_event_interruptible (wq, condition)//可中断的等待态(当产生中断信号就可以唤醒) 参数: @wq :等待对列头 @condition :如果条件为假表示可休眠,如果为真表示不休眠 返回值:成功返回0,失败返回错误码 wake_up(&wq) wake_up_interruptible(&wq) 唤醒休眠 condition = 1; 分析:wake_up_interruptible()唤醒后,wait_event_interruptible(wq, condition)宏,自身再检查“condition”这个条件以决定是返回还是继续休眠

关于STM32F中按键中断分析

南笙酒味 提交于 2019-11-30 03:05:40
  在按键学习中,我们有用到查询的方法来判断按键事件是否发生,这种查询按键事件适用于程序工作量较少的情况下,一旦程序中工作量较大较多,则势必影响程序运行的效率,为了简化程序中控制的功能模块的执行时间,引入中断控制就很有必要,,一旦有中断时间发生,则程序立马跳转到中断向量的执行程序中,执行完成后就恢复到正常的程序状态。   在STM32F中采用中断控制器NVIC来设定中断。按照中断初始化配置的结构体文件,我们需要在NVIC初始化结构体配置如下:   void EXti_PB12_Config(void)   {   //定义结构体   GPIO_InitTypeDef GPIO_InitStructure;   EXTI_InitTypeDef EXTI_InitStructure;   //开启外设时钟   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);   NVIC_Configuration();   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   GPIO_Init(GPIOB, &GPIO_InitStructure);   //

CPU上下文切换

风流意气都作罢 提交于 2019-11-29 16:51:42
进程在竞争 CPU 的时候并没有真正运行,为什么还会导致系统的负载升高呢?CPU 上下文切换就是罪魁祸首。 我们都知道,Linux 是一个多任务操作系统,它支持远大于 CPU 数量的任务同时运行。当然,这些任务实际上并不是真的在同时运行,而是因为系统在很短的时间内,将 CPU 轮流分配给它们,造成多任务同时运行的错觉。 而在每个任务运行前,CPU 都需要知道任务从哪里加载、又从哪里开始运行,也就是说,需要系统事先帮它设置好CPU 寄存器和程序计数器(Program Counter,PC)。 CPU 寄存器,是 CPU 内置的容量小、但速度极快的内存。而程序计数器,则是用来存储 CPU 正在执行的指令位置、或者即将执行的下一条指令位置。它们都是 CPU 在运行任何任务前,必须的依赖环境,因此也被叫做 CPU 上下文 。 知道了什么是 CPU 上下文,我想你也很容易理解 CPU 上下文切换 。 CPU 上下文切换,就是先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来, 然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。 而这些保存下来的上下文,会存储在系统内核中,并在任务重新调度执行时再次加载进来。这样就能保证任务原来的状态不受影响,让任务看起来还是连续运行。 根据任务的不同 ,CPU