最新免费av在线观看,亚洲综合一区成人在线,中文字幕精品无码一区二区三区,中文人妻av高清一区二区,中文字幕乱偷无码av先锋

登錄 免費注冊 首頁 | 行業(yè)黑名單 | 幫助
維庫電子市場網(wǎng)
技術(shù)交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術(shù) | 電源技術(shù) | 測控之家 | EMC技術(shù) | ARM技術(shù) | EDA技術(shù) | PCB技術(shù) | 嵌入式系統(tǒng)
驅(qū)動編程 | 集成電路 | 器件替換 | 模擬技術(shù) | 新手園地 | 單 片 機 | DSP技術(shù) | MCU技術(shù) | IC 設(shè)計 | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe

請教:44B0X在跑uc/os時,硬件連續(xù)兩次重新啟動的問題

作者:碧水長天 欄目:ARM技術(shù)
請教:44B0X在跑uc/os時,硬件連續(xù)兩次重新啟動的問題
44B0X在跑uc/os時,硬件連續(xù)兩次重新啟動的疑惑

問題描述:

44B0X開發(fā)板在移植好uc/os-ii之后,我創(chuàng)建了兩個任務(wù)task1和task2,優(yōu)先級分別為0和1。

其中,main函數(shù)從串口輸出字符串“uc/os is running”

task1從串口輸出字符串“task1”之后,被掛起1個時鐘節(jié)拍,task2從串口輸出字符串“task2”后,被掛起1個時鐘節(jié)拍。

空閑任務(wù)idletask中,我在其hook函數(shù)中添加了從串口輸出字符串“idletask”的代碼。

系統(tǒng)以RTC的中斷為系統(tǒng)的時鐘節(jié)拍中斷,禁用FIQ,使用IRQ,非矢量中斷模式,時鐘節(jié)拍數(shù)為每秒1個。


運行時,從串口檢測到輸入信息如下:

uc/os is running
task1                     //首先運行task1,該輸出正常
task2                     //task1被掛起后,task2工作,該輸出正常
idletask                  //task1和task2均被掛起,于是os運行空閑任務(wù),該輸出正常
idletask
idletask
task1                     //第一個時鐘中斷來臨,OS進(jìn)行一次任務(wù)調(diào)度,于是運行task1,輸出字符串后task1被掛起
task2                    

uc/os is running         //系統(tǒng)重新啟動,我在44binit.s中的reset入口地址開始處加了蜂鳴器開啟的指令,能證明PC重新從0X0啟動
task1
task2
idletask
idletask
idletask
task1                    //和第一次運行一樣
task2

uc/os is running         //系統(tǒng)重新啟動,我在44binit.s中的reset入口地址開始處加了蜂鳴器開啟的指令,能證明PC重新從0X0啟動
task1
task2
idletask        //之后一直運行空閑任務(wù),task1、task2都不再被調(diào)度了....
idletask
idletask
idletask
idletask
idletask
idletask
idletask
idletask
idletask
idletask
idletask
...

這個問題困擾我好幾天了,請教高人,指點一下在下,謝謝。

* - 本貼最后修改時間:2005-11-29 22:23:13 修改者:碧水長天

2樓: >>參與討論
碧水長天
唉,高手好象都很忙
自己頂一下,希望有高手點撥一下,這個問題困擾我一個星期多了,

在第2個時鐘節(jié)拍中斷到來之前,我關(guān)掉全局中斷,但執(zhí)行到了task2中的OSTimeDly(1)語句后板子又重新啟動....



3樓: >>參與討論
碧水長天
上代碼,請高手看看,尤其是中斷安裝代碼,謝謝
//1 main.c代碼


#include "..\inc\option.h"
#include "..\inc\def.h"
#include "..\inc\44b.h"
#include "..\inc\44blib.h"

#include "..\mylcd\lcd320.h"
#include "..\myip\hardware.h"

#include "..\ucos\includes.h"


#define IRQ_VECTOR_OFFSET    (0x18)

#define  RTC_OR_TIME0 0

volatile static int isrCount = 0;        // tick counter


//中斷向量的安裝
unsigned int ISR_Install(unsigned int offset, void *pf_ISR)
{
    unsigned int pOldEntry;

    // _ISR_STARTADDRESS :0x7ffff00
    offset += _ISR_STARTADDRESS;   //offset = HandleIRQ(0x7ffff18)

    // 舊的中斷服務(wù)的入口地址
    pOldEntry = *((unsigned int *)offset); //
    
    //將OSTICKISR的入口地址賦給offset所指向的內(nèi)容
    *((unsigned int *)offset) = (unsigned int)pf_ISR;  
    
    return pOldEntry;
}

#if  RTC_OR_TIME0  //tick中斷切換,為1則選擇RTC中斷,為0則選擇timer0中斷
//tick初始化,設(shè)置tick中斷,使能tick中斷服務(wù)
void tick_init(unsigned CHAR div)
{
    rRTCCON = (unsigned CHAR)1; //RTC讀寫使能,1/32768,不復(fù)位

    rTICNT = (unsigned CHAR)(div | 0x80); //tick = 0x80/div

    rRTCCON = (unsigned CHAR)0;  //禁止讀寫RTC

    rI_ISPC = (unsigned int)(0x01 << 20);  //清除TICNT的pending
    
    rINTMSK &= (unsigned int)(~(0x01 << 20));  //允許TICNT的中斷服務(wù)
}


void tick_hook(void)   //清除中斷請求標(biāo)志,OSTickISR調(diào)用                      
{
    rI_ISPC =((unsigned int)1) << 20;    
    isrCount++;        
}

#else

//保證div
void tick_init(unsigned CHAR div)
{
    
    rTCFG0=0x00f;            //Timer0,死區(qū)時間長度為0,預(yù)分頻值為0x0f
    rTCFG1=0x04;            //中斷模式,mux=1/32
    rTCNTB0=(U16) 250 * div;//tick_cyc = div * (250*1/(60 000/15/32)) = 2 * div ms
    rTCON=0x02;                //手動更新Timer0的設(shè)置
    rTCON=0x09;                //自動重載,啟動定時器
    
    rI_ISPC = (unsigned int)(0x01 << 13);  //清除TICNT的pending
    
    rINTMSK &= (unsigned int)(~(0x01 << 13));  //允許TICNT的中斷服務(wù)
}

void tick_hook(void)   //清除中斷請求標(biāo)志,OSTickISR調(diào)用                      
{
    rI_ISPC =((unsigned int)1) << 13;    
    isrCount++;        
}

#endif


//中斷控制初始化
void intcon_init(void)
{
    rINTMOD = 0;            // 所有中斷均為IRQ方式
    rI_ISPC = 0x7ffffff;    // 清除所有中斷請求
    rINTCON = 0x05;            // //非矢量中斷,IRQ使能,FIQ禁用
}

//全局中斷開關(guān)控制
void globle_int_enable(unsigned CHAR bEnabled)
{
    if(bEnabled)
        rINTMSK &= ~(((unsigned int)0x01) << 26);
    else
        rINTMSK |= ((unsigned int)0x01) << 26;
}


void sys_init(void)
{
    PortInit();//設(shè)置端口功能,LCD
    globle_int_enable(0);  //關(guān)全局中斷
    intcon_init();  //中斷初始化
            
    //Uart_Select(0);
    //Uart_Init(0, 57600); //串口選擇和初始化
            
    //InitNic(0); //0號網(wǎng)卡初始化
    
    //LCD_Init();    //LCD顯示初始化
    //LCD_ChangeMode(DspTxtMode); //顯示模式為文本模式
    
    ISR_Install(IRQ_VECTOR_OFFSET, (void *)OSTickISR); //安裝tick中斷服務(wù)程序
}


//-----------------主函數(shù)開始------------------

#define    N_TASKS            5                // 任務(wù)數(shù)
#define    TASK_STK_SIZE    512                // 任務(wù)?臻g大小

OS_STK    TaskStk[N_TASKS][TASK_STK_SIZE];// 開辟任務(wù)棧,5*512*32/8 bytes

void Task1(void *);
void Task2(void *);

extern int Image$$RO$$Limit;
extern int Image$$RW$$Base;

int Main(int argc, CHAR **argv)
{
    int    task_1 = 0, task_2 = 0;

    sys_init();    //系統(tǒng)初始化,含端口,中斷,串口,網(wǎng)卡,LCD控制
    
    //Uart_Printf("\n***************uc/os v2.51*************************");
    //Uart_Printf("\n*************** for 44b0x  ************************");
    Uart_Printf("\nuc/os is running");
    OSInit();
    OSTaskCreate(Task1, &task_1, &TaskStk[0][TASK_STK_SIZE-1], 1);
    OSTaskCreate(Task2, &task_2, &TaskStk[1][TASK_STK_SIZE-1], 2);
    OSStart();

    return 0;
}


void Task1(void * pParam)
{    

#if RTC_OR_TIME0
    tick_init(63);    //tick節(jié)拍初始化,2 ticks /s
#else
     tick_init(250);        //tick節(jié)拍初始化,2 ticks /s
#endif

     globle_int_enable(1);    //全局中斷開
     
     while(1)    
     {        
        OSSchedLock();             
        Uart_Printf( "\ntask1" );        &
4樓: >>參與討論
PandaFeng
re:
把編譯器的優(yōu)化選項關(guān)掉。

接管 Undefined,PrefetchAbort, DataAbort
看看哪一個有中斷,分析寄存器的值,可以縮小查找范圍

把其中的一個任務(wù)先去掉

祝你好運





5樓: >>參與討論
碧水長天
謝謝樓上的兄弟的指點,我再上OS_CPU_A.S文件,也許關(guān)鍵代碼有錯

該代碼原自網(wǎng)友YJ的移植,我研讀了好幾遍并部分做了注釋,尤其在OSIntCtxSW部分,未發(fā)現(xiàn)問題,也許我忽略了某些地方,請高手指點,萬分感謝!


      AREA    |subr|, CODE, READONLY

;/***********************************************************************
; 函數(shù): OSStartHighRdy
; 作用:在OS開始時調(diào)用優(yōu)先級最高的就緒任務(wù)
; 參數(shù): void
; 數(shù)出:  None
; 返回:  void
; 注意:  在OSStart()中調(diào)用
;*********************************************************************/
    EXPORT     OSStartHighRdy  ;聲明此函數(shù)被其他文件使用
    IMPORT    OSTaskSwHook    ;聲明此函數(shù)/參量在其他文件中定義
    IMPORT  OSTCBHighRdy    
    IMPORT  OSRunning  
OSStartHighRdy  ;使就緒表中任務(wù)最高的優(yōu)先級的任務(wù)開始運行
;********************************************************
;調(diào)用用戶定義的OSTaskSwHook()函數(shù)
;OSRunning = Ture
;得到將要運行的這個最高優(yōu)先級任務(wù)的堆棧指針
;從該任務(wù)(上一行提到的任務(wù))堆棧中恢復(fù)所有CPU寄存器
;執(zhí)行中斷返回指令
;***********************************************************
        BL     OSTaskSwHook             ; 調(diào)用用戶的Hook函數(shù),空函數(shù)

        LDR     r4,=OSRunning            ; 聲明多任務(wù)OS開始運行
        MOV     r5, #1                   
        STRB     r5, [r4]                 ; OSRunning = true(0000 0001b)
                                         ;get the highrdy's TCB pointer
        LDR     r4, =OSTCBHighRdy        ; 得到最高優(yōu)先級任務(wù)的任務(wù)塊地址
        LDR     r4, [r4]                 ; 任務(wù)塊中的第一個參數(shù)即任務(wù)的堆棧
        LDR     sp, [r4]                 ; 切換到新任務(wù)的堆棧
                                               
        LDMFD     sp!, {r4}                ;從新任務(wù)堆棧中讀取第一個參數(shù)(CPSR)到(r4)        
        MSR     cpsr_cxsf, r4            ;再傳給cpsr,相當(dāng)于從任務(wù)堆棧恢復(fù)CPSR,CPU切換到該任務(wù)所在的模式        
        LDMFD     sp!, {r0-r12,lr,pc}      ;依次恢復(fù)該任務(wù)r0~r12,lr,pc燃拇嫫鰨琍C切換到該任務(wù)

     
;/***********************************************************************
; Function: OS_TASK_SW
; Purpose: 任務(wù)級切換
; Parameters: void
; Outputs:  None
; Returns:  void
; Notes:
;    The whole function is executed in CRITICAL state. See OSSched().
;   On entry, OSTCBCur and OSPrioCur hold the current TCB and priority
;   and OSTCBHighRdy and OSPrioHighRdy contain the same for the task
;   to be SWITCHed to.
;   在進(jìn)入時,
;   The following code assumes that the virtual MEMORY is directly
;   mapped into  physical MEMORY. If this is not true, the cache must
;   be flushed at context SWITCH to avoid address aliasing.
;
;*********************************************************************/
        EXPORT     OSCtxSw
        IMPORT    OSPrioCur
        IMPORT    OSPrioHighRdy
        IMPORT    OSTCBCur
        IMPORT    OSTaskSwHook
        IMPORT    OSTCBHighRdy
        
OSCtxSw
;******************************************
;保存CPU寄存器
;在當(dāng)前任務(wù)控制塊中保存當(dāng)前任務(wù)的堆棧指針
;調(diào)用OSTaskSwHook()
;OSTCBCur = OSTCBHighRdy
;OSPrioCur = OSPriHighRdy
;得到將要開始運行的任務(wù)的堆棧指針
;從新任務(wù)的任務(wù)堆棧中恢復(fù)處理器所有寄存器的值
;執(zhí)行中斷返回指令
;******************************************保存CPU寄存器
        STMFD     sp!, {lr}                ; PUSH pc (lr is actually be PUSHed in place of PC)
                                          ;OS_Sched()調(diào)用OSCtxSw到這里之后,lr的值就是pc的值,
                                          ;因為是任務(wù)級調(diào)用而非異常
        STMFD     sp!, {r0-r12,lr}         ; PUSH lr & register file

        MRS     r4, cpsr                 ;通過MRS指令將cpsr入棧
        STMFD     sp!, {r4}                ; PUSH current psr
                                         ; 被掛起的當(dāng)前任務(wù)的寄存器保存完畢,下面接著保存該任務(wù)的堆棧指針
                     &nbs
6樓: >>參與討論
碧水長天
優(yōu)化策略如下:
Optimization Level: MINIMUM
Optimization Criterion: for time (for space也選過,情況依舊)

也寫了abort異常的處理,但是板子并沒有運行到abort的ISR,而是在OS中直接重新啟動,即從0X0開始運行。

另外還有一個問題,在axd中的調(diào)試中,在44binit.s的堆棧初始化子程序中(即 執(zhí)行bl        InitStacks然后進(jìn)入InitStacks代碼),有時連續(xù)運行會出錯,單步運行則從來不會出錯。

也讓我有時很迷惑。

7樓: >>參與討論
PandaFeng
可能與硬件有關(guān)
把系統(tǒng)時鐘頻率調(diào)低一點。

改一下代碼段的起始地址,看看現(xiàn)象有沒有不同?

最好測一下RAM。


8樓: >>參與討論
碧水長天
謝謝PandaFeng站友的提示
今天我按UC/OS的教材的測試步驟重新測試了一些OS,建立一個測試任務(wù)TestTask,在不掛接節(jié)拍中斷時,當(dāng)TestTask任務(wù)調(diào)用OSTimeDly()函數(shù)掛起自身時,OS能調(diào)度而進(jìn)入空閑任務(wù),這就說明OSCtxSW()函數(shù)正常,而OSIntCtxSW()函數(shù)屬于前者的一部分,因此也應(yīng)該正常。

當(dāng)按上面的代碼初始化中斷和安裝好中斷之后,程序能進(jìn)入OSTickISR,我在OSTickISR用點亮LED和B . 指令觀察,發(fā)現(xiàn)系統(tǒng)在兩種情況下崩潰(表現(xiàn)現(xiàn)象為程序重ROM的0X0啟動):

1.在運行OSIntCtxSW的恢復(fù)任務(wù)的PC指針時;

2.當(dāng)不執(zhí)行OSIntCtxSW,即在BL    OSIntExit返回后,在OSTickISR的最后一條指令恢復(fù)PC指針時;

初步認(rèn)為是OSTickISR可能有問題。但是一條一條研讀,未發(fā)現(xiàn)問題。


在這里,我注意到一個異常,請大蝦指點。

1.44BINIT.S中初始化各模式的堆棧之后,在執(zhí)行MOV PC,LR之前,我在AXD。(連上44B0X開發(fā)板后使用AXD調(diào)試)中觀察當(dāng)前模式下的CPSR和SPSR,發(fā)現(xiàn)CPSR突然被改成IRQ模式!而SPSR仍然是SVC模式意味著進(jìn)入MAIN后,CPSR卻仍然是IRQ模式,那么,在任務(wù)級別的切換OSCtxSW,可能不會發(fā)生問題,若進(jìn)入了OSTickISR,那么就可能發(fā)生問題了,過程描述請見下面初始化代碼,尤其是最后面兩條匯編指令。

;****************************************************
;*    The function for initializing stack                *
;****************************************************
InitStacks
    ;Don't use DRAM,such as stmfd,ldmfd......
    ;SVCstack is initialized before
    ;Under toolkit ver 2.50, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'

    mrs        r0,cpsr
    bic        r0,r0,#MODEMASK
    orr        r1,r0,#UNDEFMODE|NOINT
    msr        cpsr_cxsf,r1        ;UndefMode
    ldr        sp,=UndefStack
    
    orr        r1,r0,#ABORTMODE|NOINT
    msr        cpsr_cxsf,r1             ;AbortMode
    ldr        sp,=AbortStack

    orr        r1,r0,#IRQMODE|NOINT
    msr        cpsr_cxsf,r1             ;IRQMode
    ldr        sp,=IRQStack
    
    orr        r1,r0,#FIQMODE|NOINT
    msr        cpsr_cxsf,r1             ;FIQMode
    ldr        sp,=FIQStack

    bic        r0,r0,#MODEMASK|NOINT
    orr        r1,r0,#SVCMODE
    msr        cpsr_cxsf,r1             ;執(zhí)行完此語句后,CPSR和SPSR都是SVC模式

    ldr        sp,=SVCStack          ;  而執(zhí)行完此語句后,CPSR突然變成了IRQ模式!!
    
(有時執(zhí)行到main卻發(fā)現(xiàn)CPSR和SPSR都是SVC模式)。

    ;USER mode is not initialized.
    ;當(dāng)
    mov        pc,lr ;The LR register may be not valid for the mode changes.



這樣,執(zhí)行到MAIN后,CPSR仍然是IRQ模式!!
如果進(jìn)入OSTickISR,那么將可能導(dǎo)致問題,不知道我分析得對否?

我下次將用SWI指令調(diào)用任務(wù)切換函數(shù),將進(jìn)入main后的模式定為user模式。
不知道這樣是否可以。

唉,這個問題,困擾我好久了,uc/os沒搞定,很多樂趣無法享受得到。我還想玩uc/linux呢。

盼望有高人能點醒我這個arm小菜鳥。

也謝謝所有關(guān)注過這個問題的站友!


9樓: >>參與討論
PandaFeng
是否打開了某個中斷,而有沒有設(shè)向量。
是否打開了某個中斷源,而又沒有設(shè)向量。
當(dāng)發(fā)生中斷時,向量地址又為0,所以產(chǎn)生了"Reset"。
從沒有產(chǎn)生Abort中斷,可以推想。

watchdog 的可能性較大。

10樓: >>參與討論
碧水長天
謝謝PandaFeng和斑竹及其他關(guān)注的站友,今天有新的進(jìn)展
PandaFeng您好,謝謝您的指點。
在44BINIT.s中,WDT在第2條指令就開始了禁止的操作,各中斷也禁止了,只有task1中初始化時鐘節(jié)拍中斷之后才開全局中斷。

如下:
;****************************************************
;*    START                                            *
;****************************************************
ResetHandler
    ldr        r0,=WTCON        ;watch dog disable
    ldr        r1,=0x0         
    str        r1,[r0]

    ldr        r0,=INTMSK
    ldr        r1,=0x07ffffff  ;all interrupt disable
    str        r1,[r0]

...

  另外,請您分析一下這個現(xiàn)象:

   今天下午在一次AXD調(diào)試中,我發(fā)現(xiàn)44BINIT.s在初始化堆棧(BL InitStacks)之后,CPSR保持為SVC模式不變,于是一路全速執(zhí)行,發(fā)現(xiàn)測試任務(wù)和系統(tǒng)的空閑任務(wù)能正常切換(看LED輸出結(jié)果),和前面一個帖子預(yù)期的一樣。這就意味著,OS能正常使用了。這就證明我的軟件部分是正確的。

   于是燒錄到FLASH里去,卻崩潰了,情況和先前描述的一樣。

   再進(jìn)入axd環(huán)境,單步觀察44BINIT.s中的InitStacks的代碼,發(fā)現(xiàn)在最后初始化SVC堆棧完成之后,CPSR仍然莫名其妙改變成了IRQ模式,這樣,一直執(zhí)行到MAIN,仍然是IRQ模式,當(dāng)發(fā)生真正的時鐘中斷時,系統(tǒng)就崩潰了。

   為什么44Binit.s初始化堆棧會出現(xiàn)CPSR異常改變的現(xiàn)象呢?????

  請看下圖:注意橢圓框起來的內(nèi)容
http://file.21ic.com.cn/upload/img/200511/200512217231635492.jpg







* - 本貼最后修改時間:2005-12-2 17:24:53 修改者:碧水長天

11樓: >>參與討論
PandaFeng
不太清楚
或許是被FLASH的啟動代碼影響了。

我一直用IAR 的IDE,ADS 才用過兩三個星期,而且是一年前的事了。
對它并不熟悉。

燒錄到FLASH里后崩潰了,是否指BOOT代碼都不能通過嗎?

單純的點燈程序?qū)懙?a target="_blank" href="http://www.udpf.com.cn/stock-ic/FLASH.html">FLASH里,正常嗎?

其實,我是假定ucos是正常的,因為沒有產(chǎn)生abort。
在我的調(diào)試中,數(shù)據(jù)稍有異常,abort 中斷是很容易產(chǎn)生的。

下面是IAR DEBUG前對44B寄存器寫的值,可以參考一下。
AXD也有相關(guān)的設(shè)置,只是命令名不同。
例如:
__writeMEMORY32(0x11110112, 0x01c80000, "MEMORY");
相當(dāng)于rBWSCON = 0x11110112;

順便說一下,IAR Embedded Workbench IDE 很好用。

{
    __message "Init memery\n";
    
    __writeMEMORY32(0x00000001, 0x1C00000, "MEMORY");
    __writeMEMORY32(0x07FFFFFF, 0x1E0000C, "MEMORY");
    __writeMEMORY32(0x00000000, 0x1D30000, "MEMORY");
    __writeMEMORY32(0x80001B1B, 0x1C40000, "MEMORY");
    __writeMEMORY32(0x11110112, 0x01c80000, "MEMORY");
    __writeMEMORY32(0x00000600, 0x01c80004, "MEMORY");
    __writeMEMORY32(0x00007ffc, 0x01c80008, "MEMORY");
    __writeMEMORY32(0x00007ffc, 0x01c8000c, "MEMORY");
    __writeMEMORY32(0x00007ffc, 0x01c80010, "MEMORY");
    __writeMEMORY32(0x00007ffc, 0x01c80014, "MEMORY");
    __writeMEMORY32(0x00007ffc, 0x01c80018, "MEMORY");
    __writeMEMORY32(0x00018000, 0x01c8001c, "MEMORY");
    __writeMEMORY32(0x00018000, 0x01c80020, "MEMORY");
    __writeMEMORY32(0x0086041a, 0x01c80024, "MEMORY");
    __writeMEMORY32(0x00000010, 0x01C80028, "MEMORY");
    __writeMEMORY32(0x00000020, 0x01C8002C, "MEMORY");
    __writeMEMORY32(0x00000020, 0x01C80030, "MEMORY");
    __writeMEMORY32(0x00018021, 0x01D80000, "MEMORY");
    __message "Init Completed\n";
}

參與討論
昵稱:
討論內(nèi)容:
 
 
相關(guān)帖子
ATMEL的 ARM可以申請免費樣片嗎?
用了BOOTLOADER后ucos-ii不能正常工作
我該如何選型?ARM9方案
ARM1.2 Error一問
不好意思,發(fā)錯地方了。要發(fā)在51哪兒的
免費注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點此進(jìn)入


Copyright © 1998-2006 www.udpf.com.cn 浙ICP證030469號