1、 多线程的意义,解决多个非相关的程序或函数同时运行的需求,这些程序运行和执行时间都有严格的要求。这样的程序被称为线程(thread)。在DSP中任何独立执行的指令流都被称为线程。
2、 DSP/BIOS中线程分为HWI、SWI、Tasks、Background thread(IDL)。HWI就是ISR,优先级最高,适合200kHz触发的任务;SWI适合100ms或者更大周期的触发任务;Task不同SWI之处在于它在执行过程中能被挂起直到必需资源有效,任务之间可以通过queue、semaphore、mailbox;其它不运行时才运行IDL;HWI和SWI不能
挂起和等待;
3、 DSP中的三种函数。CLK function,片内计数器触发,用HWI_INT14;Periodic function(PRD),SWI的一种;Data notification function,用户用pipe或者host channel(HST)传送数据的函数。
4、 如何选择哪种类型的函数。用HWI触发SWI或者Task;互相依赖的函数或者数据共享请求的用SWI;更为复杂的用Task,SWI比Task更节省内存(memory efficient);PRD用片上定时器的倍数触发或者外部周期性中断;
5、 SWI有14级优先级,加2为PRD;TSK有15级优先级,加1为IDL;
6、 硬件中断不能动态创建,但是ISR可以动态改变;
7、 HWI和SWI用专用的系统中断堆栈(application stack),而每个TSK用各自的stack。没有TSK下,所有线程共用application stack,其可被放在快速存储器中。
8、 HWI函数调用PIP APIs函数,这些函数也是中断函数的一部分
9、 HWI_restore()与HWI_enable的区别。最外层的HWI_disable()调用禁止了中断,最内层的HWI_disable()调用将不作为,HWI_enable一调用中断即被开启,而HWI_restore()必须由最外层的函数调用才会开启中断,因此HWI_restore()比HWI_enable更好。格式{include hwi.h;Unsoldmask;oldmask =HWI_disable();HWI_restore(oldmask);}
10、 中断优先级中数字越大,优先级越高
11、 SWI_create()只能在task内调用,不能再HWI和SWI内调用
12、 增加一个软件优先级,所需的stack size就得增加,因此将SWI设为一个优先级是最节省stack size的。默认的application stack size是256个字。
13、 默认的KNL_swi的SWI应该保持最低优先级,即0
14、 每个SWI都有一个32bit的邮箱,可以作为能否分配一个SWI线程的信号量,用SWI_getmbox可以返回邮箱值,返回值为SWI从就绪队列中退出开始执行前的邮箱值,SWI执行后mailbox值恢复初始值。SWI执行过程中又再次被分派,则mailbox值会改变,但SWI_getmbox读会的值不变。
15、 Pending指就绪态
16、 SWI函数有SWI_post,SWI_or,SWI_inc和SWI_andn,SWI_dec,前三个执行时立即可以分派(post)一个SWI线程,而后两个要等到邮箱值为0才分派。当SWI执行前被触发多次,通常只执行一次,如果想执行被触发的次数就需要用到函数SWI_inc;如果想过个条件同时满足时触发,如两个不同设备准备好数据,则需要用到SWI_andn;当在一个SWI线程中想根据触发事件而执行不同的函数时,需要SWI_or;当需要一个事件有效多次才触发SWI时需要用到SWI_dec。
17、 如果ISR将改变一个数据结构而它正被执行的task访问,则需要在task执行时将中断屏蔽
18、 一个长的ISR通常被分解为两段,第一段为ISR,第二段为SWI,SWI处理不怎么严格的请求。
19、 TSK_setpri在ISR中不能调用,但可以在task和SWI中调用,而用SWI更节省资源,且切换更高效,因为task有独立的stack。
20、 SWI_disable不仅禁止了SWI抢占,也禁止了task抢占
21、 SWI_delete()可以删除一个SWI线程,但只能在task中执行
22、 Task有15个优先级,最低级0保留给IDL
23、 确定一个task所需的堆栈可以先设一个足够大的,在用CCS查看实际占用多少
24、 可以用动态和静态两种方式创建task
25、 TSK_delete可以清除task、释放stack的空间,但不能释放信号量、邮箱和其它被task获得的资源,因而这些动作要在TSK_delete之前运行。当删除一个task,而它拥有其它task所需资源时将发生致命的错误。TSK_delete只能删除动态建立的task
26、 任务有四个状态,为running、ready、blocked和terminated,用TSK_stat函数可以返回任务的状态,如果一个运行的任务被SWI或HWI抢占,返回的状态还是TSK_RUNNING
27、 IDL中不能调用阻塞的函数,如SEM_pend()、TSK_sleep()
28、 运行的TASK变成TSK_BLOCKED,条件是调用了SEM_pend()、TSK_sleep()函数,一般是为了等待IO操作或者共享数据的准备
29、 TSK_yield函数是正在执行的函数主动把CPU让给就绪队列里的task,就绪队列都是同优先级的task,主动让出的task排到队列的最后,如果它的优先级也可队列里的一样,队列是先进先出
30、 用TSK_checkstacks和TSK_stat函数可以看stack大小以防堆栈溢出