首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

verilog程序

3)    中断级任务切换函数
①    该函数由OSIntExit()和OSExIntExit()调用,它若在时钟中断ISR中发现有高优先级任务等特的时候信号到来,则需要在中断退出后并不返回被中断的,的而是直接调度就绪的高高优先级任务执行.这样做的目的主要是能够尽快的让优先级高的任务得到响应,进而保证系统的实时性。
OSIntCtxSw
        LDR     R0, OS_TaskSwHook      ; OSTaskSwHook();
        MOV     LR, PC
        BX      R0
        LDR     R4, OS_PrioCur          ; OSPrioCur = OSPrioHighRdy
        LDR     R5, OS_PrioHighRdy
        LDRB    R6,[R5]
        STRB    R6,[R4]        
        LDR     R4,OS_TCBCur            ; OSTCBCur  = OSTCBHighRdy;
        LDR     R6,OS_TCBHighRdy
        LDR     R6,[R6]
        STR     R6,[R4]
        LDR     SP,[R6]                 ; SP = OSTCBHighRdy->OSTCBStkPtr;
                                        ; RESTORE NEW TASK'S CONTEXT
        LDMFD   SP!, {R4}               ; Pop new task's CPSR
        MSR     SPSR_cxsf, R4
        LDMFD   SP!, {R0-R12,LR,PC}^    ; Pop new task's context
②    两种形式的中断程序
OS_CPU_IRQ_ISR
        STMFD   SP!, {R1-R3}                   ; PUSH WORKING REGISTERS ONTO IRQ STACK
        MOV     R1, SP                         ; Save   IRQ stack pointer
        ADD     SP, SP,#12                     ; Adjust IRQ stack pointer
        SUB     R2, LR,#4                      ; Adjust PC for return address to task
        MRS     R3, SPSR                       ; Copy SPSR (i.e. interrupted task's CPSR) to R3
        MSR     CPSR_c, #(NO_INT | SVC32_MODE) ; Change to SVC mode
                                               ; SAVE TASK'S CONTEXT ONTO TASK'S STACK
        STMFD   SP!, {R2}                      ; Push task's Return PC
        STMFD   SP!, {LR}                      ; Push task's LR
        STMFD   SP!, {R4-R12}                  ; Push task's R12-R4
        LDMFD   R1!, {R4-R6}                   ; Move task's R1-R3 from IRQ stack to SVC stack
        STMFD   SP!, {R4-R6}
        STMFD   SP!, {R0}                      ; Push task's R0    onto task's stack
        STMFD   SP!, {R3}                      ; Push task's CPSR (i.e. IRQ's SPSR)                                             
        LDR     R0,   OS_IntNesting            ; OSIntNesting++;
        LDRB    R1, [R0]
        ADD     R1, R1,#1
        STRB    R1, [R0]
        CMP     R1, #1                         ; if (OSIntNesting == 1) {
        BNE     OS_CPU_IRQ_ISR_1
        LDR     R4,  OS_TCBCur                 ; OSTCBCur->OSTCBStkPtr = SP
        LDR     R5, [R4]
        STR     SP, [R5]                       ; }
OS_CPU_IRQ_ISR_1
        MSR     CPSR_c, #(NO_INT | IRQ32_MODE) ; Change to IRQ mode (to use the IRQ stack to handle interrupt)
        LDR     R0,  OS_CPU_IRQ_ISR_Handler    ; OS_CPU_IRQ_ISR_Handler();
        MOV     LR, PC
        BX      R0         
        MSR     CPSR_c, #(NO_INT | SVC32_MODE) ; Change to SVC mode
        LDR     R0,  OS_IntExit                ; OSIntExit();
        MOV     LR, PC
        BX      R0                             ; RESTORE NEW TASK'S CONTEXT
        LDMFD   SP!, {R4}                      ; Pop new task's CPSR
        MSR     SPSR_cxsf, R4
        LDMFD   SP!, {R0-R12,LR,PC}^           ; Pop new task's context
        RSEG CODE:CODE:NOROOT(2)
        CODE32
OS_CPU_FIQ_ISR
        STMFD   SP!, {R1-R3}                   ; PUSH WORKING REGISTERS ONTO FIQ STACK
        MOV     R1, SP                         ; Save   FIQ stack pointer
        ADD     SP, SP,#12                     ; Adjust FIQ stack pointer
        SUB     R2, LR,#4                      ; Adjust PC for return address to task
        MRS     R3, SPSR                       ; Copy SPSR (i.e. interrupted task's CPSR) to R3
        MSR     CPSR_c, #(NO_INT | SVC32_MODE) ; Change to SVC mode
                                               ; SAVE TASK'S CONTEXT ONTO TASK'S STACK
        STMFD   SP!, {R2}                      ; Push task's Return PC
        STMFD   SP!, {LR}                      ; Push task's LR
        STMFD   SP!, {R4-R12}                  ; Push task's R12-R4
        LDMFD   R1!, {R4-R6}                   ; Move task's R1-R3 from FIQ stack to SVC stack
        STMFD   SP!, {R4-R6}
        STMFD   SP!, {R0}                      ; Push task's R0    onto task's stack
        STMFD   SP!, {R3}                      ; Push task's CPSR (i.e. FIQ's SPSR)
                                               ; HANDLE NESTING COUNTER
        LDR     R0, OS_IntNesting              ; OSIntNesting++;
        LDRB    R1, [R0]
        ADD     R1, R1,#1
        STRB    R1, [R0]
        CMP     R1, #1                         ; if (OSIntNesting == 1){
        BNE     OS_CPU_FIQ_ISR_1
        LDR     R4, OS_TCBCur                  ; OSTCBCur->OSTCBStkPtr = SP
        LDR     R5, [R4]
        STR     SP, [R5]                       ; }
OS_CPU_FIQ_ISR_1
        MSR     CPSR_c, #(NO_INT | FIQ32_MODE) ; Change to FIQ mode (to use the FIQ stack to handle interrupt)
        LDR     R0, ??OS_CPU_FIQ_ISR_Handler   ; OS_CPU_FIQ_ISR_Handler();
        MOV     LR, PC
        BX      R0
        MSR     CPSR_c, #(NO_INT | SVC32_MODE) ; Change to SVC mode
        LDR     R0,  OS_IntExit                 ; OSIntExit();
        MOV     LR, PC
        BX      R0                             ; RESTORE NEW TASK'S CONTEXT
        LDMFD   SP!, {R4}                      ; Pop new task's CPSR
        MSR     SPSR_cxsf, R4
        LDMFD   SP!, {R0-R12,LR,PC}^           ; Pop new task's context
4)    OSStartHighRdy()函数
该函数是在OSStart()多任务启动后,负责从最高优先级任务的TCB控制块中获得该任务的堆栈指针SP通过SP依次将CPU现场恢复。这时系统就将控制权交给用户创建的该任务进程,直到该任务被阻塞或者被更高优先级的任务抢占CPU。该函数仅仅在多任务启动时被执行一次,用来启动第一个也即最高优先级任务。
OSStartHighRdy  
        MSR     CPSR_cxsf, #0xD3        ; Switch to SVC mode with IRQ and FIQ disabled
        LDR     R0, ??OS_TaskSwHook     ; OSTaskSwHook();
        MOV     LR, PC
        BX      R0
        LDR     R4,  OS_Running         ; OSRunning = TRUE
        MOV     R5, #1
        STRB    R5, [R4]
                                        ; SWITCH TO HIGHEST PRIORITY TASK
        LDR     R4,  OS_TCBHighRdy      ;    Get highest priority task TCB address
        LDR     R4, [R4]                ;    get stack pointer
        LDR     SP, [R4]                ;    switch to the new stack
        LDR     R4,  [SP], #4           ;    pop new task's CPSR
        MSR     SPSR_cxsf,R4
        LDMFD   SP!, {R0-R12,LR,PC}^    ;    pop new task's context     
2.    多任务应用程序的编写
1)    C语言入口函数
函数Main()为C语言入口函数,所有C程序从这里开始运行,在该函数中进行如下操作:
③    调用函数ARMTaskgetInit初始化ARM处理器
④    调用OSInit初始化系统
⑤    调用OSTaskCreat函数创建任务:Task1和Task2
⑥    调用ARMTaskgetStart函数启动时钟节拍中断
⑦    调用OSStart启动系统任务调度
#include “config.h”
OS_STK  TaskStartStk[TASK_STK_SIZE];
OS_STK  TaskStk[TASK_STK_SIZE];
int Main(void){
    OSInit();
    OSTaskCreate(Task1,(void*)0,&TaskStartStk[TASK_STK_SIZE-1],0);
    OSStart();
    return();
}
2)    任务处理函数
①    Task1
void Task1(void *pdata){
    pdata=pdata;
    TargetInit();
    For(;;){
        OSTimeDly(OS_TICKS_PER_SEC/50);
        If(GetKey()!=KEY1)    {
            continue;
        }
        OSTaskCreate(Task2,(void *)0,&TaskStk[TASK_STK_SIZE-1],10);
        While(GetKey()!=0)    {
            OSTimeDly(OS_TICKS_PER_SEC/50);
}
}
}
②    Task2
void Task2(void *pdata){
        pdata=pdata;
        BeeMoo();
OSTimeDly(OS_TICKS_PER_SEC/8);
        BeeMoo();
OSTimeDly(OS_TICKS_PER_SEC/4);
        BeeMoo();
OSTimeDly(OS_TICKS_PER_SEC/8);
        OSTaskDel(OS_PRIO_SELF);
}
我的博客:http://blog.eccn.com/u/qianmin/index.htm
静静等待春天的到来! 

verilog程序

///////////////////////////////////////////////
// RS232
异步数据接收模块 baudClk8x/8,8,n,1
// 2002-2005
///////////////////////////////////////////////
module UartRec(
rst, //
异步复位
rxd, //
串行数据
baudClk8x, //8X
波特率时钟
irq, //
中断请求
dataOut //
数据输出
);
input rst,rxd,baudClk8x;
output irq;
output[7:0] dataOut;
parameter idle_state=0 , verifyStartBit_state=1,
startBitOk_state=2, bit0_state=3,
bit1_state=4 , bit2_state=5,
bit3_state=6 , bit4_state=7,
bit5_state=8 , bit6_state=9,
bit7_state=10 ;
reg [3:0] bitState; //
接收状态机
reg [7:0] shifter; //
移位寄存器
reg [7:0] dataOut; //
输出锁存器
reg [2:0] bitCounter; //
采样计数器
reg irq;

always @(posedge rst or posedge baudClk8x)
begin
if(rst)
begin
bitState<=4'd0;//idle_state;
bitCounter<=3'd0;
shifter<=8'd0;
end
else
begin
if(bitState==4'd0)//idle_state
begin
if(!rxd)
begin
bitState<=bitState+1;
bitCounter<=3'd0;
end
end
else if(bitState==4'd1)//verifyStartBit_state:
begin
if(bitCounter==3'd3)
begin
if(!rxd) //
校验起始位是否依然有效
bitState<=bitState+1;//4'd2 bit 0 state
else
bitState<=4'd0; //idle_state;

bitCounter<=3'd0;
end
else
bitCounter<=bitCounter+1;
end
else if(bitState==4'd10)//bit7_state
begin
if(bitCounter==3'd7) //
返回初始状态,不检查停止位
begin
bitCounter<=3'd0;
bitState<=4'd0;
end
else
bitCounter<=bitCounter+1;
end

else //bitState=2~9 8
个数据位接收
begin
if(bitCounter==3'd7)
begin
shifter<={rxd,shifter[7:1]};
bitCounter<=3'd0;
bitState<=bitState+1;
end
else
bitCounter<=bitCounter+1;
end
end
end

always @(posedge rst or negedge baudClk8x)
begin
if(rst)
begin
dataOut<=0;
irq<=0;
end
else if(bitState==4'd10)
begin
dataOut<=shifter;
irq<=1;
end
else
irq<=0;

end
endmodule

返回列表