一、IO口
1、使用的时候打开时钟,若该IO被当做外设的端口需要使能复用时钟。
2、若该端口被当做外部中断引脚也需要打开复用时钟。
二、读操作
1、当读寄存器付给某个变量时,注意这个变量的类型,一般为unsigned int 32位的,如果类型不对在移位操作的时候将得不到正确的结果。
2、这个变量可以定义为volatile类型。
三、中断
1、异常处理在主堆栈中,如果中断嵌套太深,注意堆栈的使用情况。
2、软件中断,手动设置中断 写STIR寄存器。
3、SVC和PENDSV(系统服务调用、可悬起的系统服务)
SVC和PENDSV主要配合操作系统的调用,SVC用于用户呼叫调用系统函数,如果在操作系统中不会让用户程序直接访问硬件而是通过系统函数。SVC的请求要求必须立即响应,如果有更高的优先级在执行则会返回一个fault。
PENDSV,悬起系统服务和中断挂起一样,OS使用它可以缓期执行一个异常直到其他重要的任务完成后在执行,在OS中用在上下文的切换(任务间的切换),比较好的解决了OS实时性的问题。
触发上下文切换的源:① 系统调用 ② systick异常执行任务的切换 。任务切换期间是禁止中断的。在ucosII中用的systick当做系统时钟,在systick中断时进行任务的切换。
假如在执行一个中断的ISR,这时来了一个systick异常(优先级高于ISR)要进行任务的切换,那么ISR的响应将会被延迟,具体的延迟时间没法估计,对实时性是致命的。
假如systick异常进行任务切换之前会判断当前系统中有没有ISR在执行,如果没有ISR在执行任务切换,这样任务的切换会至少延迟一个以上的systick周期,当ISR与systick中断的周期接近时将会引起共振。
PENDSV解决了这个问题,如果有ISR,PENDSV会在systick异常后把任务的切换延迟进行不会再等待下一个systick异常。但是需要将PENDSV异常的优先级设置为最低的优先级。
现在好了,如果ISR正在执行期间来了一个systick异常,systick异常会置位NVIC中的PENDSv位挂起PENDSV异常,在PENDSV异常中进行任务的切换,PENDSV会等到其他ISR执行完后再执行任务的切换。
UCOSII中,进程级的任务切换和中断中的任务切换,OS都会挂起PENDSV,在PENDSV的ISR中执行任务的切换,任务切换都是用汇编写的,在OS_CPU_A.asm文件中
OSCtxSw
LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
LDR R1, =NVIC_PENDSVSET
STR R1, [R0]
BX LR
LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
LDR R1, =NVIC_PENDSVSET
STR R1, [R0]
BX LR