当前位置: 首页 > wzjs >正文

龙岩做网站公司有哪些青岛seo青岛黑八网络最强

龙岩做网站公司有哪些,青岛seo青岛黑八网络最强,朋友叫我去柬埔寨做彩票网站推广,太仓企业网站建设价格前言 中断可以说是操作系统最重要的部分,其实前面的讲解我们也看到了,操作系统不是每时每刻都在运行的程序,很多时候都触发了中断之后进行处理,操作系统是由中断驱动的;关于中断我前面的文章有提到过: https://blog.csdn.net/qq_45731845/article/details/146291274 RTOS的中断…

前言

  中断可以说是操作系统最重要的部分,其实前面的讲解我们也看到了,操作系统不是每时每刻都在运行的程序,很多时候都触发了中断之后进行处理,操作系统是由中断驱动的;关于中断我前面的文章有提到过:
https://blog.csdn.net/qq_45731845/article/details/146291274

RTOS的中断管理

  首先要把中断优先级设置为4:即没有响应优先级 都是抢占优先级
RTOS的中断管理除了涉及到了中断优先级配置的寄存器,这几个寄存器也同样重要
在这里插入图片描述

  1. 受RTOS的中断和不受RTOS的中断
    我们可以配置哪些中断优先级受RTOS管理 哪些中断优先级不受RTOS管理
        // 优先级数小于5的不归FreeRTOS管理#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
    
    • 为什么还要有不受RTOS管理的中断呢?
        除了什么硬件异常啊之类的,我们试想这样一个场景:假设我有一个电机的传感器要求每100us采集一次数据–这项工作去抽象成一个任务去做是不可能的,延时的处理是放在sysTickHandler中的,不可能把这个时钟配置的这么快,而且用任务处理时效性也不是很好(做不到100us精确延时)
      假设我们设置一个定时器中断不受RTOS的中断管理,就可以通过配置定时器和中断处理函数做到这件事了
  2. 相关的函数
  • 什么是临界区与临界资源?
    临界资源:是指一次仅允许一个进程或线程访问的共享资源,如果多个进程/线程同时访问,可能会导致数据不一致或竞态条件
    临界区: 访问临界资源的代码叫做临界区
  • taskENTER_CRITICAL与对应的ISR(在临界区进入中断)
    实际上taskENTER_CRITICAL就是通过写BASEPRI寄存器来暂时屏蔽对受RTOS管理的中断的响应
    void vPortEnterCritical( void )
    {portDISABLE_INTERRUPTS();uxCriticalNesting++;            // 这个修改全局变量是为了支持嵌套if( uxCriticalNesting == 1 ){configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );}
    }
    static portFORCE_INLINE void vPortRaiseBASEPRI( void )
    {uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;  // 这个宏跟我们设置的configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY宏相关的哟__asm{/* Set BASEPRI to the max syscall priority to effect a critical* section. *//* *INDENT-OFF* */msr basepri, ulNewBASEPRIdsbisb/* *INDENT-ON* */}
    }
    
      对应的ISR函数版本,为啥这么做我想是因为在中断里不想去修改全局变量uxCriticalNesting去进行嵌套吧,而是需要我们手动处理状态
    static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void )
    {uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;__asm{/* Set BASEPRI to the max syscall priority to effect a critical* section. *//* *INDENT-OFF* */mrs ulReturn, baseprimsr basepri, ulNewBASEPRIdsbisb/* *INDENT-ON* */}return ulReturn;
    }
    
  • dsb与isb指令
    dsb和isb和我们前面讲的内存屏障有关,作用就是确保后面所有的函数都是用的bssepri的新值(毕竟我们的CPU和编译器有时候会优化指令执行顺序,从而引起不可知的错误)
    • dsb
      ​确保所有内存访问指令(如 LDR/STR)在屏障前完成,再执行后续指令。
      解决多级流水线或总线乱序执行导致的数据同步问题
    • isb
      清空处理器流水线,确保后续指令从内存重新预取,使用最新的寄存器或内存值。
      解决指令预取导致的上下文不一致问题。
  • xxFromISR探究
    我们随便找一个FromISR就会发现进入中断服务函数做的第一件事往往是调用portASSERT_IF_INTERRUPT_PRIORITY_INVALID();函数
    BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue,BaseType_t * const pxHigherPriorityTaskWoken )
    {BaseType_t xReturn;UBaseType_t uxSavedInterruptStatus;Queue_t * const pxQueue = xQueue;configASSERT( pxQueue );configASSERT( pxQueue->uxItemSize == 0 );configASSERT( !( ( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) && ( pxQueue->u.xSemaphore.xMutexHolder != NULL ) ) );portASSERT_IF_INTERRUPT_PRIORITY_INVALID();/**.....*/
    }
    

这个函数干了什么呢?–就是查看调用该函数的中断的优先级是不是受FreeRTOS管理

```Cvoid vPortValidateInterruptPriority( void )
{uint32_t ulCurrentInterrupt;uint8_t ucCurrentPriority;// 得到当前中断的中断号ulCurrentInterrupt = vPortGetIPSR();// portFIRST_USER_INTERRUPT_NUMBER是16 因为前15个都是系统异常if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ){// 通过寄存器得到中断优先级ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );// ucMaxSysCallPriority的值在xPortStartScheduler时被配置了,配置为//ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;}
}
```
  1. 为什么FreeRTOS要区分带中断的API和不带中断的API
  • 在中断里不能延时 阻塞,毕竟你总不能在中断里vTaskDelay()多久
  • vPortValidateInterruptPriority函数
    验证中断优先级:确保中断的优先级符合 FreeRTOS 的要求,特别是 configMAX_SYSCALL_INTERRUPT_PRIORITY 的要求,避免高优先级中断调用不安全的 FreeRTOS API 函数。

Linux的中断管理

  1. 用户态与内核态
    在这里插入图片描述
  • 用户态和内核态分别是什么?为什么要区分?
    • 用户态: 应用程序拥有有限的系统资源访问权限,只能在操作系统划定的特定空间内运行
    • 内核态: 拥有最高权限,可直接操作硬件、管理内存、调度进程等
    • 为什么要区分: 安全性 / 稳定性(一个应用崩溃不影响其他) / 提高性能
  • 用户态切换内核态的方式?
    • 系统调用: fork() / read() / write()
    • 异常:比如缺页异常
    • 外设中断
  • 用户态如何访问内核态资源?
    • 系统调用
    • 库函数 : malloc() / printf()
    • shell : cat / …
  • 切换过程会保存那些信息
    • 保存用户态信息:将用户态的寄存器信息保存到内核栈中。
    • 切换到内核栈:设置堆栈指针寄存器为内核栈的地址。
    • 执行内核态程序:加载中断处理程序的地址到寄存器,开始执行内核态程序。
    • 恢复用户态
  1. 系统调用
  • 系统调用是什么?
    在系统调用时会触发一个特殊的中断,CPU此时就会从用户态切换内核态 不同的系统调用有不同的系统调用号 从而执行不同的处理
    系统调用并不直接返回错误码,而是将错误码放入一个名为errno的全局变量中。通常用一个负的返回值来表明错误。返回一个0值通常表明成功。
    在这里插入图片描述

  • 系统调用的具体步骤

    • 设置参数(用户态)
    • 触发系统调用 int 0x80 此时用户态会切换到内核态
    • 内核检查传入参数的合法性
    • 根据系统调用号找到处理程序并运行
    • 返回参数
  • 减少系统调用的次数

    • 合并系统调用: read/write—>readv / writev
    • 避免拷贝: read/write–>mmap
    • 缓存数据
  1. Linux的上半/下半部中断
  • 为什么要区分上/下半部
      中断作为异步执行,其时间应该越短越好 所以只在中断里做必须执行的部分 而把剩下的部分"推迟"处理就好,从而平衡实时性与系统响应能力,减少中断屏蔽时间

  • 下半部的实现 tasklet / softirq / workqueue
    下半部在执行的时候是开中断的 可以被打断的
    概括性总结
    因为软中断和tasklet还是在中断上下文 所以不能睡眠 但是workqueue就是个线程 是可以阻塞和睡眠的
    在这里插入图片描述

    • 软中断
      软中断是一个数组 在编译期间就被确定了的
      软中断在设计上要求支持重入(多个CPU同时调用都没问题)
      通过do_softirq()来执行软中断
      在这里插入图片描述

      • do_softirq()的时机
        中断退出的时候,会唤醒并调用软中断
        raise_softirq是会处理软中断
        ksoftirqd线程:避免大量的软中断导致用户态啥也不做
    • tasklet函数
      tasklet是通过软中断实现的,不过它有了新的定义:那就是不可能多个CPU同时运行一个tasklet函数怎么做到的 通过一个原子变量进行计数
      在这里插入图片描述

      tasklet本身就是在中断执行完的时候通过tasklet_schedule()添加到本CPU链表的尾部
      在这里插入图片描述

      tasklet_action来执行中断
      在这里插入图片描述

      • tasklet_action的调用时机—同软中断
    • workqueue
      对于tasklet和软中断,都不能睡眠,这在有时候可太不好用了
      工作队列的话是吧工作推后,交给一个内核线程去执行—内核线程就可以正常被CPU调度了 这样的话就可以去执行一些阻塞之类的操作了
      一般每隔CPU都有一个线程专门处理工作队列–循环遍历链表
      在这里插入图片描述

      但因为是依次遍历 所以如果我们任务前面有非常耗时的任务就得等待了–此时我们可以创建一个新的线程专门处理我们的中断下半部任务

  • 中断的处理流程
    cpu接受中断->保存中断上下文跳转到中断处理例程->执行中断上半部(并在最后调用软中断)->执行中断下半部->恢复中断上下文。

    irqreturn_t my_isr(int irq, void *dev_id) {/.../tasklet_schedule(&my_tasklet); // 触发下半部return IRQ_HANDLED;
    }
    
  • 中断处理函数的注册
    中断的申请request_irq的正确位置:应该是在第一次打开 、硬件被告知终端之前

    if (request_irq(irq, my_isr, IRQF_SHARED, "my_device", dev)) {printk("注册中断失败\n");return -EIO;
    }
    
  • 中断处理函数编写的注意事项

    • 尽量短小
    • 不要休眠与阻塞
    • 中断的返回值: 裸机没有返回值 / Linux内核中必须正确返回irqreturn_t
  1. 内核线程与用户线程
    用户线程是在用户空间的 每个线程是独立的拥有自己的用户空间
    而内核线程是在内核空间 共享内存的
    在这里插入图片描述

我们前面讲过每个线程都是有自己的task_struct的 不管你是哪个属于哪个进程
在这里插入图片描述

ianr

http://www.dtcms.com/wzjs/791804.html

相关文章:

  • 那个视频网站好汕头市澄海建设局门户网站
  • 网站项目运营方案顺德网站建设找顺的
  • 电脑可以做服务器部署网站吗网页设计策划方案
  • 网站建设经理岗位职责wordpress退出登录界面
  • 排名轻松seo 网站翻页大图网站
  • 网站建设与网页设计的论文心悦做宠物的网站
  • 推荐个2021能看的网站免费网站制作公司怎么运营
  • 白银市建设管理处网站公司网站维护教程
  • 汕头网站排名优化报价福州网站开发公司
  • 行业门户网站营销案例北京建设工程交易网站官网
  • 公司网站怎么做百度竞价北京计算机编程培训学校
  • 昆山网站制作哪家强做一手房有哪些网站比较好啊
  • 建站服务论坛金融投资网站 php源码
  • 摄像头做直播网站杭州上城区抖音seo渠道
  • 企业网站建设费是无形资产吗查工程建设不良记录免费的网站
  • 济宁北湖建设集团网站如何上传网页到网站
  • 兰州新区建设银行网站专业app开发设计的公司
  • 南阳网站建设网站建设什么打王思聪
  • 二维码制作网站链接给个网站2022年手机上能用的
  • 做竞价的网站怎么编辑网页
  • 果洛州商城网站建设湖南公司响应式网站建设价位
  • 宠物网站建设进度表建设网站的个人心得体会
  • 网站域名怎样注销长春建站网站
  • 网站模板商城创意logo一键生成器软件免费
  • 网站建设 网站邢台专业网站建设公司
  • 福建建设注册管理中心网站站开发技术培训
  • 精选赣州网站建设wordpress qq登录
  • wordpress 做一个视频站企业解决方案英文
  • cms三合一网站源码做羽毛球网站
  • 做外贸必应网站产品曝光社区app网站模板下载