STM32F103和AIR32F103的FreeRTOS中断优先级

关于 Arm Cortex M 系列内核的中断优先级

Cortex M 的中断和优先级

首先要区分开 中断中断优先级 这是两个不同的东西, 不要搞混了

  • 对于 Cortex-M0 和 Cortex-M0+ 内核, 除了系统内建中断外, 支持最多 32 个中断
  • 对于 Cortex-M3 内核, 除了 16 个内核中断外, 支持最多 240 个中断
  • 有8-bit的优先级, M0是固定的 2-bit, 即4个优先级, M3/M4 至少需要实现3-bit, 即大于等于8个优先级

厂商的实现

  • STM32 F1 只使用了其中的 84个中断, 包括 16个内核中断和 68 个可屏蔽中断
  • STM32 F1 实现了 4-bit 的优先级, 具有16级可编程的中断优先级.
  • STM32F103系列, 只使用了60个可屏蔽中断

优先级的数值和优先级的关系

The most important fact to know is that Cortex-M uses the “reversed” priority numbering scheme for interrupts, where priority zero corresponds to the highest urgency interrupt and higher numerical values of priority correspond to lower urgency. This numbering scheme poses a constant threat of confusion

注意,Cortex-M 对中断优先级编号的方案, 数值是倒序的, 优先级0对应最高优先级, 数值越大对应的优先级越低.

NVIC(Nested Vectored Interrupt Controller) 中的中断优先级配置

The number of priority levels in the Arm Cortex-M core is configurable, meaning that various silicon vendors can implement different number of priority bits in their chips. However, there is a minimum number of interrupt priority bits that need to be implemented, which is 2 bits in Arm Cortex-M0/M0+ and 3 bits in Arm Cortex-M3/M4.

Cortex-M 内核的中断优先级数量不全是固定的, Cortex-M0/M0+ 是固定的2-bit, Cortex-M3/M4 至少需要3-bit, 各个厂商可以在芯片产品里根据需要实现不同的优先级位数.

上图是 NVIC 优先级寄存器中的位表示方法. 优先级的有效数值是左对齐的, 如果直接往寄存器写值, 需要对应地左移.

CMSIS 中的中断优先级

CMSIS(Cortex Microcontroller Software Interface Standard) 是面向 Cortex M 的通用底层实现, 在标准的 CMSIS 实现中提供了函数 NVIC_SetPriority(IRQn, priority) 用于设置中断优先级. 这个函数中的 priority 不需要左移, 在函数里已经根据 __NVIC_PRIO_BITS 自动处理了. 例如 调用 NVIC_SetPriority(7, 6) 对于 3-bit 优先级的 Cortex-M, 会将 IRQ#7 的优先级设为 1100,0000, 对于4-bit 优先级的 Cortex-M, 会将 IRQ#7 的优先级设为 0110,0000.

抢占优先级 Preempt Priority 和 子优先级 Supbpriority

优先级被分成两类

  • Preemption Priorities, 抢占优先级
  • Sub Priorities, 子优先级

这两种优先级的区别

  • 更高的抢占优先级中断 可以打断 正在进行的低抢占优先级中断
  • 抢占优先级相同的中断, 高子优先级 不可以打断 低子优先级的中断
  • 抢占优先级相同的中断, 中断同时发生时, 子优先级高的先执行
  • 抢占优先级和子优先级都一样时, 哪个中断先发生哪个就先执行

在大多数应用中, 建议将所有优先级bits分配给preempt priority group, 不使用 Supbpriority. 避免使中断优先级之间的关系复杂化. 一些第三方代码库(例如STM32的驱动库)会将优先级组配置为非标准, 建议在初始化此类驱动库后, 通过调用CMSIS函数 NVIC_SetPriorityGrouping(0U) 显式地将优先级分组重新设置为默认值.

使用库函数void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)设置优先级组, 参数是以下宏定义

#define NVIC_PriorityGroup_0         ((uint32_t)0x700)
#define NVIC_PriorityGroup_1         ((uint32_t)0x600)
#define NVIC_PriorityGroup_2         ((uint32_t)0x500)
#define NVIC_PriorityGroup_3         ((uint32_t)0x400)
#define NVIC_PriorityGroup_4         ((uint32_t)0x300)

下面的表格是宏定义对应的抢占优先级和子优先级的拆分关系, 以及拆分后的优先级取值范围

NVIC_PriorityGroup NVIC_
IRQChannelPreemptionPriority
NVIC_
IRQChannelSubPriority
Description
NVIC_PriorityGroup_0 0 0-15 0 bits for pre-emption priority
4 bits for subpriority
NVIC_PriorityGroup_1 0-1 0-7 1 bits for pre-emption priority
3 bits for subpriority
NVIC_PriorityGroup_2 0-3 0-3 2 bits for pre-emption priority
2 bits for subpriority
NVIC_PriorityGroup_3 0-7 0-1 3 bits for pre-emption priority
1 bits for subpriority
NVIC_PriorityGroup_4 0-15 0 4 bits for pre-emption priority
0 bits for subpriority

中断优先级由抢占优先级和子优先级共同组成, NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority表示抢占优先级, NVIC_InitStruct->NVIC_IRQChannelSubPriority表示子优先级

系统运行后先调用函数void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)设置中断优先级分组

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

整个系统执行过程中,只设置一次中断分组.

针对每个中断,void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)设置对应的抢占优先级和响应优先级

NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);

FreeRTOS优先级设置

对于 STM32F103, FreeRTOSConfig.h 中需要配置 configKERNEL_INTERRUPT_PRIORITY 和 configMAX_SYSCALL_INTERRUPT_PRIORITY, 另外在 FreeRTOS 调度启动前调用函数NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 )将全部优先级设为抢占优先级.

configKERNEL_INTERRUPT_PRIORITY

  • 设置 FreeRTOS 内核本身使用的中断优先级, 因为FreeRTOS内核中断不应当抢占用户使用的中断, 因此一般定义为硬件最低优先级
  • 对于STM32F103, 优先级总共4-bit, 在字节的最高位, bit[7:4], 全一表示的最低优先级, 所以在 FreeRTOSConfig.h 中将其设置为 0B1111xxxx 的任一个值就行 [240, 255]
  • 对于AIR32F103, 优先级总共3-bit, 字节最高位 bit[7:5], 所以设置为 0B111xxxxx 的任一个值就行 [160, 255]

configMAX_SYSCALL_INTERRUPT_PRIORITY

设置可以在中断服务程序中, 调用中断安全的FreeRTOS API函数的最高中断优先级.

FreeRTOS 中断嵌套方案将可用的中断优先级分成2组: 被 FreeRTOS 临界区覆盖的, 和不会被覆盖的(这些中断是无法被屏蔽的), 优先级高于配置值的中断, 不受FreeRTOS管控, 在 FreeRTOS 中无法通过进入临界区屏蔽这些中断, 因此也不能在这些中断中调用 FreeRTOS API, 否则系统会有崩溃的风险

例如将这个优先级设置为5, 那么如果有一个中断优先级等于4, 在这个中断中调用了FreeRTOS API, 则系统会有崩溃的风险, 如果使能了configASSERT宏, 会触发断言失败.

在STM32中要保证所有的优先级设置为可抢占优先级, 具体实现方式是在 FreeRTOS 启动前, 调用函数NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4)

STM32使用了中断优先级寄存器中的4位, bit[7:4], 如果设置优先级为5, 对应的二进制值为0x101,

  • 对应STM32使用的 bit[7:4] 就是0x0101, 剩余的 bit[3:0] 可以设置成任何值, 但为了兼容,最好将他们设置成1. 因此就是0x0101 1111 = 0x5F = 95
  • 对应AIR32/MH32使用的是 bit[7:5] 就是0x101, 剩余的 bit[4:0] 可以设置成任何值, 设成全1就是0x1011 1111 = 0xBF = 191
/* AIR32F103 only use 3 bits(bit[7:5]) for priority */

/* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255
(lowest) to 0 (1?) (highest). */
/* equivalent to 0xFF (0x111x xxxx, x=1), or priority 7. */
#define configKERNEL_INTERRUPT_PRIORITY     255
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
/* equivalent to 0xBF (0x101x xxxx, x=1), or priority 5. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY  191

链接

  • FreeRTOS的中断说明 http://www.openrtos.net/RTOS-Cortex-M3-M4.html
  • Cutting Through the Confusion with Arm Cortex-M Interrupt Priorities
  • A Beginner’s Guide on Interrupt Latency - and Interrupt Latency of the Arm Cortex-M processors
本文转载于网络 如有侵权请联系删除

相关文章

  • 使用Gradle部署jar包到Maven中央库

    Maven作为目前Java界最好的Dependency管理系统,把jar包托管到Maven中央库,然后通过MavenDependency使用是目前业界各种第三方库的普遍做法,如果,你想把自己开发的一些库分享给别人使用,也可以遵循这样的套路。Gradle可以看做是升级版的Maven,其使用了Maven最优秀的Dependency管理系统,但是,又规避了Maven的buildpipeline的刻板和xml格式配置文件等缺点,可以说是目前Java界最好的构建工具。下面就来说说,如何使用Gradle把自己开发的jar包部署到Maven中央库中。Part1:为自己的项目注册Maven中央库账号在http://oss.sonatype.orgz注册账号,(注:Sonatype是Maven中央库的管理系统),注册之后获得用户名,密码。后面的build脚本会用得上。在Sonatype的JIRA系统中,创建一个issue(选择Project:CommunitySupport-OpenSourceProjectRepositoryHosting;IssueType:NewProject),告诉Sonaty

  • CA数字认证系统为何要用NTP时钟服务器?

    CA数字认证系统为何要用NTP时钟服务器?答:1、CA系统各个设备众多,计算机网络中各主机和服务器等网络设备的时间基本处于无序的状态。随着计算机网络应用的不断涌现,计算机的时间同步问题成为愈来愈重要的事情。以Unix系统为例,时间的准确性几乎影响到所有的文件操作。如果一台机器时间不准确,例如在从时间超前的机器上建立一个文件,用ls查看一下,以当前时间减去所显示的文件修改时间会得一个负值,这一问题对于网络文件服务器是一场灾难,文件的可靠性将不复存在。为避免产生本机错误,可从网络上获取时间,这个命令就是rdate,这样系统时钟便可与公共源同步了。但是一旦这一公共时间源出现差错就将产生多米诺效应,与其同步的所有机器的时间因此全都错误。2、另外当涉及到网络上的安全设备时,同步问题就更为重要了。这些设备所生成的日志必须要反映出准确的时间。尤其是在处理繁忙数据的时候,如果时间不同步,几乎不可能将来自不同源的日志关联起来。一旦日志文件不相关连,安全相关工具就会毫无用处。不同步的网络意味着企业不得不花费大量时间手动跟踪安全事件。现在让我们来看看如何才能同步网络,并使得安全日志能呈现出准确地时间。3、I

  • AtCoder Beginner Contest 165 A ~~D

    A水题:#include<bits/stdc++.h> usingnamespacestd; intmain(){ intk; cin>>k; inta,b; cin>>a>>b; for(inti=1;;i++){ if(i*k>b){ cout<<"NG"<<endl; break; } if(i*k>=a&&i*k<=b){ cout<<"OK"<<endl; break; } } return0; }复制B水题:#include<bits/stdc++.h> usingnamespacestd; typedeflonglongll; intmain(){ llx; cin>>x; llsum=100; lltot=0; while(sum<x){ llres=sum*0.01; //cout<<res<<&qu

  • 数 学 专 业 劝 退 指 南

    随着这两天各地陆续公布高考分数线,填报志愿这个“人生大事”也马上要开始了,很多图灵的学生读者留言表示对选择专业有些疑虑,其中有个比较深刻的例子。问:我数学成绩好,感觉自己也比较喜欢数学,那我应不应选择数学专业?这是个好问题,想当年小编的一位高中同学成绩优秀,数学考到了145。于是,自信满满地填报了某985的数学系,先是经历了「无挂科不大学」的宿命,再是大二留级,最后换了专业重读一年才毕业,一个典型的“翻车”案例。 虽然小编对这个问题无法作出权威的解答,但秉着对读者负责的态度,我们还是对数学这个带有迷之诱惑的专业来简单地讲解一下吧。相信世上有很多人都对数学有恐惧,同样也有很多人对数学充满渴望。人类天生就对一些未知的事物有求知欲,有人是对数学的渴望,有人是对艺术的渴望。但很多人把这种渴望当做了“喜欢”,却没有付出追求知识的努力和行动。所以他们永远只停留在口头上的“我喜欢数学”,“我喜欢艺术”而已。「数学成绩好」,真的是「数学好」吗?这个问题有点「咬文嚼字」,以传统的角度来看,一个人的数学好坏通常有两种世俗的判断方法:第一是数学成绩。数学是一个基础科学,我们从认字识数开始到进入大学,成绩是量

  • 用Carthage手动导入ReactiveCocoa

    前言ReactiveCocoa用GitHub推荐的方式比较麻烦,尝试改用Carthage进行导入官方的方法方法使用工具:carthage生成.framework文件。 安装carthage方式1:brewinstallcarthage 安装carthage方式2:下载pkg文件https://github.com/Carthage/Carthage/releases 安装成功查看版本号:carthageversion假设已经安装成功,现在把GitHub上的ReactiveObjC生成.framework文件。1:在桌面新建个空文件夹RAC_Lib,用命令CD到此目录下; 2:在RAC_Lib文件夹内新建名为Cartfile的空白文件(touchCartfile); 3:打开Cartfile文件里面配置你要下载的(一个或多个)开源库,这里最低下载2.5版,并保存文件。 github"ReactiveCocoa/ReactiveObjC">=2.5 4:在命令行执行命令carthageupdate让它自动下载并生成.framework导入并使用参考链接:https

  • GDB 调试笔记

    GDB是一个由GNU开源组织发布的*.nix下的、基于命令行的一款比较知名的程序调试工具。GDB有着相当多的命令,但是常用的只有大概十个左右。gdb命令一般可以使用gdbprogram或者使用gdbprogrmacore。如果想对正在执行的进程进行调试,则可以使用gdb-p123。常见命令命令解释示例file<文件名>加载被调试的可执行程序文件。因为一般都在被调试程序所在目录下执行GDB,因而文本名不需要带路径。(gdb)filegdb-samplerrun的简写,运行被调试的程序。如果此前没有下过断点,则执行完整个程序;如果有断点,则程序暂停在第一个可用断点处。(gdb)rcContinue的简写,继续执行被调试程序,直至下一个断点或程序结束。(gdb)cb<行号>b<函数名称>b\*<函数名称>b\*<代码地址>d[编号]b:Breakpoint的简写,设置断点。两可以使用“行号”“函数名称”“执行地址”等方式指定断点位置。其中在函数名称前面加“\*”符号表示将断点设置在“由编译器生成的prolog代码处”。如果不了解汇编

  • Sublime 部分问题解决

    安装包管理器将控制台界面(console)调出(在view选项中),使用如下命令安装包控制器。importurllib.request,os;pf='PackageControl.sublime-package';ipp=sublime.installed_packages_path();urllib.request.install_opener(urllib.request.build_opener(urllib.request.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib.request.urlopen('http://sublime.wbond.net/'+pf.replace('','%20')).read())复制成功后会在Preferences选项中看到PackageSettings合PackageControl。配置代理Preferences-PackageSettings-PackageCont

  • Jenkins Area Meetup 2019 北京首站沙龙精彩回顾(附PPT)

    2019年5月19日,首都天气晴朗,万里无云,100多名Jenkins用户同时相聚在北五环的北辰泰岳大厦,2019年首次JenkinsAreaMeetup线下聚会在这里举行。本次JenkinsAreaMeetup举办相当成功,现场站无虚席,多位Jenkins技术大牛、JenkinsAmbassador带来诸多Jenkins干货,让我们来一起看看本次JenkinsAreaMeetup有哪些亮点。 如何学好Jenkins的第一堂课?京东工程效率专家、DevOps标准核心编写专家、JenkinsAmbassador石雪峰老师首先带来“Day1:Jenkins的第一堂课”的精彩分享。▲京东工程效率专家、DevOps标准核心编写专家石雪峰在JenkinsAreaMeetup2019·北京沙龙上分享如何自动化推进应用在环境栈中的无差别发布?如何权限控制/审批应用在不同环境中发布?如何提高应用的平均部署实践/恢复时间?针对上述痛点,阿里巴巴技术专家郝树伟此次为现场Jenkins用户带来“GitOps:Kubernentes下多集群环境下的高效CI/CD实践分享”▲阿里巴巴技术专家郝树伟在Jenkin

  • 美国调查显示未来10年公众或逐渐放弃隐私

    点击标题下「大数据文摘」可快捷关注 美国皮尤互联网项目本周四发布了关于未来隐私状况的调查报告。报告结果显示,专家认为,目前我们正生活在一个受到持续监控的时代里,我们将大量个人信息放置在互联网上,而许多企业收集、追踪这些信息,并利用这些信息赚钱。皮尤与美国依隆大学“梦想互联网”中心合作进行了这一调查。调查访问了2500多名专家,而问题则是他们认为到2025年在线隐私保护的状况将会是怎样。这些专家中包括大学教授、研究人员、未来学家、政治决策者,以及大公司的领袖。关于“到2025年,是否会出现安全、被普遍接受并信赖的隐私权基础设施”的问题,45%的受访者认为答案是肯定的,而另55%则给出了否定的判断。他们认为,政府和企业缺乏自我监督的动力,开发可用的全球系统将存在挑战,而个人用户也不太关心自己的隐私权。依隆大学“梦想互联网”中心主管杰娜·安德森(JannaAnderson)表示:“大部分专家认为,企业和政府没有动力去加强隐私保护。这部分是由于,有证据表明,个人用户会为了些微利益,例如一杯咖啡,而放弃自己的个人信息。”未来10年,用户分享的个人信息将会越来越多。目前,所有在线购物、搜索引擎搜索

  • 定位div到窗口固定位置

    代码来自网络~/*任意位置浮动固定层*/ /*调用: 1无参数调用:默认浮动在右下角 $("#id").floatdiv(); 2内置固定位置浮动 //右下角 $("#id").floatdiv("rightbottom"); //左下角 $("#id").floatdiv("leftbottom"); //右下角 $("#id").floatdiv("rightbottom"); //左上角 $("#id").floatdiv("lefttop"); //右上角 $("#id").floatdiv("righttop"); //居中 $("#id").floatdiv("middle"); 另外新添加了四个新的固定位置方法 middletop(居中置顶)、middlebottom(居中置低)、leftmiddle、righ

  • 《码处高效:Java开发手册》之代码风格

    流水淡,碧天长,鸿雁成行。编码风格,简捷清爽,反引无限风光。   在美剧《硅谷》中有这样一个经典镜头,主人公Richard与同为开发工程师的女友闹分手,理由是两人对缩进方式有着截然不同的编程习惯,互相鄙视对方的代码风格。Richard认为"onetabsavesfourspaces”,缩进使用Tab键操作更快,更节省存储空间,而女友坚持使用空格缩进,连续四次敲击空格的声音,把Richard折磨到几近崩溃,认为这是种精神折磨。Richard觉得难以相处,吵完架下楼梯时,不小心摔倒了还淡定地说,"Ijusttriedtogodownthestairsfourstepsatatime”(这只是表达我的立场而已)。Tab键和空恪键的争议在现实编程中确实存在。除此之外,在其他代码风格上,也存在不同的处理方式,往往是谁也说服不了谁,都站在自身“完全正确”的立场上,试图说服对方。这在团队开发效率上,往往是一个巨大的内耗,无休止的争论与最后的收益是成反比的。所以我们认为一致性很重要,就像交通规则一样,我国规定靠右行驶,有些国家则规定靠左行驶,并没有绝对的优劣之分,但是在同一个国家或地区内必须要有统

  • Hibernate-Validator 5.1.0.Final 无法解析自定义占位符的问题

    最近在做一个小项目,想使用Hibernate-validator来做后台数据的验证,在pom中: <!--hibernate--> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>${hibernate.validator.version}</version> </dependency> <dependency> <groupId>

  • 1176: 零起点学算法83——核反应堆

    1176:零起点学算法83——核反应堆 TimeLimit:1Sec  MemoryLimit:32MB  64bitIOFormat:%lldSubmitted:2075  Accepted:551[Submit][Status][WebBoard] Description 某核反应堆有两类事件发生:高能质点碰击核子时,质点被吸收,放出3个高能质点和1个低能质点;低能质点碰击核子时,质点被吸收,放出2个高能质点和1个低能质点。假定开始的时候(0微秒)只有一个高能质点射入核反应堆,每一微秒引起一个事件发生(对于一个事件,当前存在的所有质点都会撞击核子),试确定n微秒时高能质点和低能质点的数目。   Input 输入含有一些整数n(0≤n≤33),以微秒为单位,若n为-1表示处理结束。(注意是多组测试)   Output 分别输出n微秒时刻高能质点和低能质点的数量,高能质点与低能质点数量之间以逗号空格分隔。每个输出占一行。   SampleInput   52 -1复

  • 说一说inline-block的奇葩之处

    今天本来想聊一下margin和padding,但是当我给div加了一个display:inline-block之后,发现一个问题: .box_demo{border:1pxsolid#333;width:80px;display:inline-block;}复制 <divclass="box_demo"> box1 </div> <divclass="box_demo"> box2 </div>复制   发现没有,中间赫然有着4px的间距!!之前居然一直都没有注意到!!! 我想着是不是只有block元素才有的问题,看了一下inline元素,依然存在这个问题,这个引起了我的注意,在网上搜罗了一番,渐渐发现,这确实是一个坑。   称   号:“inline-block元素间间隙问题”。 现   象:如上。 产生原因:换行、空格导致。 解决办法:(1)去掉换行;         优点:此解法soeasy;缺点:代码洁癖者哭了;      (2)使

  • &lt;JAVA&gt;字节流,字符流

     在程序中所有的数据都是以流的方式进行传输或者保存的,程序需要数据的时候需要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流。   可以通过下面的输入输出流关系图表示这种方式。 字节流:   字节流主要操作byte类型数据,以byte数组为准,主要操作类是OutputStream类和InputStream类。 其中OutputStream类是一个抽象类,如若要使用此类,首先就必须要通过子类来实例化对象。假设现在要操作的事一个文件,则可以使用FileOutputStream类,通过向上转型后,可以为OutputStream实例化,在OutputStream类中的主要操作方法如下: 1publicvoidclose()throwsIOException//关闭输出流 2publicvoidflush()throwsIOException//刷新缓冲区 3publicvoidwrite(byte[]b)throwsIOException//将一个byte数组写入数据流 4publicvoidwrite(byte[]b,intoff,intlen)throwsIOE

  • Jupyter

    JupyterNotebook(此前被称为IPythonnotebook)是一个交互式笔记本,支持运行40多种编程语言。 JupyterNotebook的本质是一个Web应用程序,便于创建和共享文学化程序文档,支持实时代码,数学方程,可视化和markdown。用途包括:数据清理和转换,数值模拟,统计建模,机器学习等等。 架构 Jupyter组件 Jupyter包含以下组件: JupyterNotebook和Notebook文件格式 JupyterQt控制台 内核消息协议(kernelmessagingprotocol) 许多其他组件 内核 JupyterNotebook与IPython终端共享同一个内核。 内核进程可以同时连接到多个前端。在这种情况下,不同的前端访问的是同一个变量。 这个设计可以满足以下两种需求: 相同内核不同前端,用以支持,快速开发新的前端 相同前端不同内核,用以支持,新的开发语言 快捷键 JupyterNotebook有两种键盘输入模式。编辑模式,允许你往单元中键入代码或文本;这时的单元框线是绿色的。命令模式,键盘输入运行程序命令;这时的单元框线是灰色。

  • AVL树&amp;红黑树

    在认识AVL树和红黑树之前,不妨来回顾一下二叉搜索树。 二叉搜索树BinarySearchTree 二叉搜索树,也称有序二叉树、排序二叉树,是指一颗空树或者具有下列性质的二叉树: 左子树上所有结点的值均小于它的根结点的值; 右子树上所有结点的值均大于它的根结点的值; 以此类推:左、右子树也分别为二叉搜索树(重复性) 且二叉搜索树的中序遍历是升序排列。 二叉搜索树在极端的情况下,会退化成一个链表。   这样的话查询的时间复杂度就变成了O(n)了。 我们知道二叉搜索树的查询效率只与树的高度有关,所以要保证效率,就得想办法让二叉搜索树的左右子树高度尽可能地平衡。 这时候就引入了另外一种数据结构:平衡搜索二叉树,而AVL树和红黑树就是平衡搜索二叉树的一种。   AVL树 AVL树,是一种自平衡的树,要求左右子树的高度绝对值不能大于1。它也具备二叉搜索树的特征。 在AVL树中,有一个重要的概念 BalanceFactor(平衡因子):左右子树高度差的绝对值。 AVL树是通过旋转操作来进行平衡(四种) 1.左旋 右右子树->左旋   2.右旋 左左子树

  • 推荐几个Laravel 后台管理系统

    小编推荐几个Laravel后台管理系统 由百牛信息技术bainiu.ltd整理发布于博客园 一、不容错过的Laravel后台管理扩展包——Voyager 简介Voyager是一个你不容错过的Laravel后台管理扩展包,提供了CRUD操作、媒体管理、菜单构建、数据管理等操作。 官网:https://the-control-group.github.io/voyager/ Github:https://github.com/the-control-group/voyager 视频演示:https://devdojo.com/episode/laravel-admin-package-voyager 安装使用创建完新的Laravel应用后就可以在根目录下通过以下命令引入Voyager扩展包: composerrequiretcg/voyager接下来创建一个新的数据库并将数据库认证信息添加到.env文件: DB_HOST=localhostDB_DATABASE=homesteadDB_USERNAME=homesteadDB_PASSWORD=secret然后注册Voyager服务提供者

  • bug:margin塌陷

    margin塌陷:两个嵌套的div,内部div的margin-top失效,内部对于外部的div并没有产生一个margin值,而是外部的div相对于上面的div产生了一个margin值。 弥补方法:   1.在父级div添加border-top:1pxsolid#rrggbb;   思考:采用这种解决方案,貌似会被产品经理揍死~~~,平白无故多了一像素,不能忍。     2.BFC:blockformatcontext块级格式化上下文,创建了BFC的元素就是一个独立的盒子,不过只有Block-levelbox可以参与创建BFC,它规定了内部的Block-levelBox如何布局,并且与这个独立盒子里的布局不受外部影响,当然它也不会影响到外面的元素。      如何触发一个盒子的bfc?      position:absolute;      display:inline-block; &

  • 组装电脑基础知识之CPU风冷散热器

    前言 本系列文章是为准备自己组装台式机的小伙伴写的关于中央处理器CPU、主板、显卡等部分的参考资料。 一、简介 CPU散热器是安装在CPU上协助CPU在运转时进行散热的零件,保证CPU能够稳定运行。而风冷散热器,是通过与CPU接触的传热底座进行导热,再由风扇扰动空气起到散热的作用。 提示:CPU温度过高时,会影响CPU的工作频率,从而影响性能。 二、参数 1、分类 侧吹式散热器(塔式):是目前常见的一种散热器样式,塔式散热器一般是单向侧吹,不会扰乱机箱中风道,将CPU的发热量直接吹出机箱后面的预留散热孔,这种侧吹式散热器适合组建机箱风道,散热效果要优于下压式散热器。 下压式散热器:散热器风扇朝下吹,存在扰乱机箱风道的情况,适合发热量小的平台,加上由于通常体积小且不占用空间,所以是迷你机箱的福音。 2、热管 热管是一种传热元件,它充分利用了热传导原理与相变介质的快速热传递性质,透过热管将发热物体的热量迅速传递到热源外,其导热能力超过任何已知金属。 为了增加热管的防腐防锈能力,会在热管上镀一层镍进行保护。 3、散热器底座 散热器底座是指跟CPU接触导热的部分,为了达到更好的散热效果,就

  • JVM的艺术—类加载器篇(二)

    分享是价值的传递,喜欢就点个赞 引言 今天我们继续来深入的剖析类加载器的内容。上节课我们讲了类加载器的基本内容,没看过的小伙伴请加关注。今天我们继续。 什么是定义类加载器和初始化类加载器? 定义类加载器:假设我们的某一个类是由ExtClassLoader加载的,那么ExtClassLoader称为该类的定义类加载器 初始化加载器:能够返回Class对象引用的都叫做该类的初始类加载器,比如类A是由我们的ExtClassLoader加载,那么 ExtClassLoader是该类的定义类加载器,也是该类的初始类加载器,而我们的AppClassLoader也能返回我们A类的引用 那么AppClassLoader也是该类的初始类加载器。 什么是类加载器的双亲委派模型? 上篇文章我们提到了类加载器的双亲委派模型,也可以称为双亲委托模型。今天这篇文章我们就来把这个概念给讲明白。 概念:用一种简单的方式去描述双亲委托的概念。可以分为两个部分去理解 1委托: jvm加载类的时候是通过双亲委派的方式去加载,自下而上的去委托。 自定义类加载器需要加载类时,先委托应用类加载器去加载,然后应用类加

相关推荐

推荐阅读