前言:
刚刚抽筋点了保存发布,结果要审核,那就分开写个续好了。
内容:
signal
信号是异步通知task的一种机制,HISR是不可以接收信号的,但是可以发送信号。
TCB中与signal相关数据结构包括active_signal,enable_signal(这是一个掩码,如果为0则不执行signal_handler),(*signal_handler),主要有两个函数,一个是send_signals()和signal_shell(),其中send_signals()函数主要是区分发送信号给自己还是给其他的task,如果发给自己就直接执行signal_shell(),如果发送至其他task(处于suspend或ready但没有占用处理器的状态),target task必须要释放占用的protect,因为在signal_handler中可能会去请求protect资源,这样就会发生死锁,当前task执行TCT_protect_switch()函数,与请求protect()函数前半部分一致,调用schedule_protect()让target task释放占用的protect资源。
在target stack处建立solicited stack,其中PC = &signal_shell,保存target task的status和tc_statck_ptr,根据当前的状态,如果是ready或pure_suspend,则返回,否则就resume_task()唤醒target task,根据返回值确定是否进入schedule()。
在send_signal中应用protect来保护共享数据,而到了protect_switch中应用关中断来保护,中间有一个数据保护的真空期,因此要两次确认target task没有再占用protect资源
suspend/resume
对于task状态改变的操作主要有suspend和resume函数,其中suspend将一个task挂起,当挂起自己时会control_to_system,finished和terminated状态的转变也是利用suspend函数,resume函数用来将task唤醒,并返回一个标志是否需要context switch
线程同步
应用里可以使用到的线程同步有两种方式,semaphore和event groups,semaphore与linux中的一直,但是NU中并没有对优先级反转有处理
event groups是一个32bit的数据结构,可以标记32个事件,操作包括set和retrieve,set event时会唤醒suspend list上的所有task,最后在对相应bit consume,retrieve去请求event,如果失败则挂起在suspend list上,只有拿到event后才会对consume
线程通信
NU中支持的线程通信方式包括queue,pipe,mailbox,这里queue和pipe的机制基本相同,只是queue是按32bit操作,pipe是按照字节访问,但是代码里也做了对齐,mailbox是一种信箱机制,信箱的大小为4*32bit,使用的好处就是执行速度快
内存管理
NU并没有使用到虚拟内存管理,直接访问物理地址,有两种建立内存池的方法,动态内存管理和静态内存管理,动态内存管理采用的分配策略是first-fit和释放后内存融合,静态内存管理是每次分配固定大小的内存块,这样可能会引起内存的利用率降低,但是不会引起内存外部碎片
1. 中断向量表的reset地址为0x0,直接跳转至INT_Initialize()
2. Low_bit_set[256]用来快速计算优先级的表,其中放的是对应优先级数值第一个不为0的数,例如当前最高priority=17,则low_bit_set[17] = 0,17 = 0x11第一个不为0的位是第0位
3. HISR不会suspend,没有time slice即同优先级的HISR依次执行,不会接收信号,只可以被中断,如果激活了更高优先级的HISR则当前HISR被抢占。
4. 当中断发生时,ARM硬件完成的工作包括:
i. 保存中断前的CPSR至SPSR_irq_mode
ii.保存中断时PC值至lr_irq_mode
iii.切换至irq mode,屏蔽irq bit,set arm mode
iv. 将PC指向irq_entry(0x18)
5. time slice只有在被中断里才会保存下来,即一个task被中断后执行了LISR和HISR后,重新schedule到task,其time slice是之前剩下的时间片,当task主动让出处理器时,比如self-suspend,send_signal,resume高优先级的task时,会将time slice重新置为预设值
6. 在control_to_system里有clear protect的动作
7. TMD_Timer_Start记录的是当前timer_active_list上顶端timer的remaining_time,当发生start_timer,stop_timer或timer expired时都会去更新这个值
8. 所有的system call都要用system_protect来保护,因为其中有对于重要全局变量的访问
9. TCB中有一个suspend_protect,用来记录task在suspend前拥有的是什么样类型的protect,例如一个请求Dynamic memory的task suspend在dm_suspend_list上,在挂起前将dm_protect保存至suspend_protect中,因为一个task在suspend前必须释放所持有的protect,所以只能利用suspend_protect标记之前占有的是dm_protect,当timeout发生时,重新获得dm_protect去执行cleanup函数,做清理工作将task从dm_suspend_list上移除,resume一个task时会将suspend_protect清空。
10. 一个HISR中可以send_signal,suspend其他task,请求protect资源,这些动作都有可能使HISR让出处理器给低优先级的task去执行,都是调用TCC_schedule_protect(),目的是避免deadlock
11. deadlock产生的四个必要条件 (必考)
i.互斥条件:资源同一时间只可以被一个进程访问
ii.请求与保持条件:当进程请求新资源阻塞时,不释放已经占有的资源
iii.不剥夺条件:进程在占有资源时,未使用完之前,不可以被强行剥夺
iv. 循环等待条件:若干进程形成一种头尾相接的循环等待资源关系
12. 优先级反转(priority inversion)(必考)
产生原因:三个task,优先级关系是taskA>taskB>taskC,taskC占有互斥sem,当taskA执行时申请sem,suspend,此时taskB被唤醒,继续执行,则taskC无法释放sem,导致高优先级的taskA无法执行,而低优先级的taskB一直执行下去
解决方法:
i.disable interrupt (影响OS的实时性)
ii.disable preemption (影响实时性)
iii.优先级继承
在运行时,taskA请求低优先级taskC已经占有的sem,则将taskC的优先级提升至taskA相同
iv. 优先级天花板
在未运行的情况下,首先估计会使用到sem的task,然后将所有的task优先级升高至这些task中的最高 优先级。
13. 在TCT_schedule_Protected的代码中,在control_to_thread前开关了一次中断,这样可以节省一次上下文切换,让中断在当前task上发生,而不是切换至占有protect的task在发生中断。
14. 当task被中断后抢占,不会释放protect资源,因此在LISR中不可以使用与Protect相关的系统调用,只可以使用activate_HISR(),它是用中断来保证原子访问的。
15. protect的嵌套利用unprotect_specific()和set_current_protect()来实现,同时system_protect一般作为第二个protect去申请,因为system_protect保护了内核中全局的数据结构,粒度较大,因此要尽量减少持有的时间
16. 第一次中断的上下文保存在task stack,嵌套的中断上下文保存在system stack,因为中断嵌套发生在LISR中,此时sp值已经更新为system stack ptr
17. protect() send_signal(), suspend()都有为了防止deadlock让持有protect的task执行,直到释放protect的机制
18. 在调用terminate task时,如果task是suspend要调用cleanup函数,要利用suspend_protect保护,同时不会与system_protect形成死锁
19. queue和pipe,按照FIFO的模式发送message,在变长模式下,如果taskA的message较大suspend,则taskB即使有空间也必须suspend在taskA后面。
20.resume返回true的条件
i.当前priority_list上只有target_task一个
ii.target_task的优先级高于TCD_Highest_priority
iii.确定当前task是可抢占的
iv. 当前线程是一个task,如果是NULL则是在初始化里面,初始化还未完成不应该schedule,如果在 HISR里,因为HISR的优先级总是高于task的,因此也不会发生抢占
21. Dynamic memory的数据结构使用双向链表是为了可以进行融合操作
22. first-fit策略必须使用相邻融合的内存管理方法,但是仍会造成50%的浪费
23. TCD_current_thread == NULL,如果当前开着中断则是schedule,如果是关中断则是INT_initialize
24. 如果申请protect,TCD_current_thread == NULL,protect中直接跳过,因为这是在初始化中,初始化使用关中断来保护的
25.如果一个HISR suspend了,则下一次LISR触发HISR时,就无法处理了
- 委托学习笔记后续:泛型委托及委托中所涉及到匿名方法、Lambda表达式
引言: 最初学习c#时,感觉委托.事件这块很难,其中在学习的过程中还写了一篇学习笔记:委托.事件学习笔记.今天重新温故委托.事件,并且把最近学习到和委托相关的匿名方法.Lambda表达式及泛型委托记录 ...
- nucleus plus学习总结
前言: 最近一直都在看nucleus plus,之前看过一些linux内核的一些东西,但都是停留在文字上,代码看的很少,这个nucleus plus内核的代码量不大,看过source code ...
- sql 入门经典(第五版) Ryan Stephens 学习笔记 后续——存储引擎
一.引擎基础 1 查看系统支持的存储引擎 show engines; 2 查看表使用的存储引擎两种方法: a.show table status from database_name where na ...
- [Django]模型学习记录篇--基础
模型学习记录篇,仅仅自己学习时做的记录!!! 实现模型变更的三个步骤: 修改你的模型(在models.py文件中). 运行python manage.py makemigrations ,为这些修改创 ...
- linq学习笔记
最近在学习linq的一些基础知识,看了c#高级编程及阅读了园子内部几篇优秀的博文,有所体会,感觉应该记录下来,作为以后复习使用.都是一些最基础的知识,大致分为三个部分:linq预备知识:linq查询: ...
- STM32学习笔记(四) RCC外设的学习和理解
RCC时钟模块并不好理解,初次接触我也是一头雾水,而且我真正掌握它的时候也比较晚,是我在学习uC/os-II,需要分析时钟时才有了深刻认识.但在学习中我却一定要把放在了前列,因为这是整个嵌入式最重要的 ...
- python开发学习-day01 (python安装与版本、字符串、字典、运算符、文件)
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- 新手学习.net编程计划-1
.NET是一个庞大的学习体系,对于新手来说会感觉无从下手.学习知识必须从入门的基础学起,才能更好地掌握.学习.net也是如此,最基础的莫过于了解.net平台,以及掌握.net的基础语法C#. 本计划是 ...
- spark学习
大数据学习纲要,主要针对spark的相关知识的学习,后续会涉及其他大数据相关框架及语言. 1 spark入门: 2.spark 实战部分 3.spark源码解析
随机推荐
- 【C++11新特性】 C++11智能指针之weak_ptr
如题,我们今天要讲的是C++11引入的三种智能指针中的最后一个:weak_ptr.在学习weak_ptr之前最好对shared_ptr有所了解.如果你还不知道shared_ptr是何物,可以看看我的另 ...
- 谷歌已经对Android的开源严防死守
上周,沸沸扬扬的Android垄断案把Google又一次推向了风口浪尖,在这次的垄断案中,Google被欧盟起诉赔偿50亿美元,被起诉的其中一个原因是Google对外宣称Android是开放的,但其实 ...
- php str_pad()函数 语法
php str_pad()函数 语法 str_pad()函数怎么用? php str_pad()函数用于把字符串填充到指定长度,语法是str_pad(string,length,pad_string, ...
- hdu 2732 Leapin' Lizards (最大流 拆点建图)
Problem Description Your platoon of wandering lizards has entered a strange room in the labyrinth yo ...
- AT2070 Card Game for Three(组合数学)
传送门 解题思路 前面的思路还是很好想的,就是要枚举最后一个\(a\)在哪出现算贡献,之后我先想的容斥,结果彻底偏了..后来调了很久发现自己傻逼了,似乎不能容斥,终于走上正轨23333.首先可以写出一 ...
- 使用selenium+BeautifulSoup 抓取京东商城手机信息
1.准备工作: chromedriver 传送门:国内:http://npm.taobao.org/mirrors/chromedriver/ vpn: selenium BeautifulSo ...
- vux使用方法
# 使用vux及vuex-i18n需要做的工作 ### 1.首先需要安装vux ### 2.需要安装vux-loader ### 3.需要安装vuex ### 4.需要安装vuex-i18n ### ...
- kubernetes安装部署
1.根据系统内核情况,选择对应的ali云上的镜像,作为仓库的路径指向来配置k8s https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes- ...
- fat32转ntfs ,Win7系统提示对于目标文件系统文件过大解决教程
系统之家 发布时间:18-05-3117:56 很多Win7用户在复制较大的文件时,系统会弹出窗口提示“对于目标文件系统,文件XXX过大”,出现这种情况的原因是FAT32的文件系统不支持复制大于4g的 ...
- 《单词的减法》state1~state17(第一遍学习记录)
单词的减法 2016.05.18 state 1 accordingly 因此,相应地,对应地 advisory 顾问的,劝告的 annoy 打扰,干扰,使恼怒 anticipate/particip ...