打印

关于usosII中断的理解和疑惑,DMA为例 (s3c2440,ADS),帮帮忙!

[复制链接]
1990|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
whws007|  楼主 | 2011-11-23 11:34 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
假设UCOS中有3个任务,Task0,Task1,Task2(IIS任务),Task3,优先级为Task0>Task1>Task2(IIS任务)>Task3:
1.优先级最高的任务Task0的延时(OSTimeDely)或者说暂停时间要大于后边所有任务的执行时间之和?
2.OSIntEnter()和OSIntExit()的是否ucos中断时必须用,以及它们的放置位置,是否要根据自己程序的实际情况而定,不能照搬课本(如下图):(我在做这个实验时用没用,程序都能正常执行)
以下面程序为例,
a)如果把OSIntEnter()和OSIntExit()加在DMA2_IIS_End()中断服务程序中如下,中断返回时返回到while(!Tx_flag);语句处,如果在    OSIntExit(); 中发生了任务调度,切换到高优先级去执行,则while(!Tx_flag);以下的代码就无法执行,DMA2和IIS就无法关闭。
b)如果把OSIntEnter()和OSIntExit()加在void Start_IIS_DMA2(volatile unsigned char *start_addr, unsigned int play_size)程序中的前后,OSIntExit();根据任务就续表情况来切换任务,1)如果没有发生切换返回时OSTimeDly();函数也要检测就续表,根据情况来切换任务,这两个函数执行的动作不就重复了吗?
                    2)如果发生了任务切换,假如切换到了Task1,Task2中的OSTimeDly();就没有执行,任务Task2在就续表中还是显示已经就绪,也没有暂停延时,当Task1任务执行完时,再次发生任务调度切换,由于Task2已就绪,此时就有可能再次执行Task2,如此循环Task3就没有执行的机会,不知道OSIntEnter()和OSIntExit()是不是必须有,还是尽量不要?

void  DMA2_IIS_End(void)
{
    OSIntEnter()
    ClearPending(BIT_DMA2); //清除中断标志位
     
     rINTMSK &= ~(BIT_DMA2); //开中断,以等待下次中断
     
     Tx_flag=1;
     OSIntExit();
   
}
[localimg=118,150]1[/localimg]
3.在UCOS-II下用中断函数不要加__irq,注意函数声明和定义中都不能要。
4.还有OS_ENTER_CRITICAL()和OS_ENTER_CRITICAL(),应该放什么地方,是不是UCOS中断时也必须用到?
5.之前按网上说的方法,UCOS移植裸机DMA中断(IIS音频用到),一直不成功,要么死机要任务切换不出来,还有进入不了中断,后来莫名其妙的就好了。或者说是把IIS音频初始化,和DMA及其中断初始化都加入到ucos的while循环中,程序就好了,还有问题的根源可能在于中断服务子程序带有关键字__irq,把此关键字去掉,无论是声明中还是定义中,此方法可能应该不具有通用性,还得再测试。UCOS中断问题困扰我好多天,一直没搞明白。
//主函数中IIS任务Task3
void Task3(void *pdata)
{
    int i;
   
   // MMU_Init();
    IIS_DMA2_Int_Init();
while(1)
     {  
        Speaking_wav();//语音提示
        OSTimeDly(OS_TICKS_PER_SEC);
      }
}
//IIS程序
#include "config.h"
#include "WindowsXP_Wav.h"
#define L3C  (1<<4)              //GPB4 = L3CLOCK
#define L3D  (1<<3)              //GPB3 = L3DATA
#define L3M  (1<<2)              //GPB2 = L3MODE
#define  downloadAddress ((volatile unsigned char *)0x31000000) //声音数据保存地址
//unsigned int downloadAddress=0x31000000;
void  DMA2_IIS_End(void);
int Tx_flag;
//GPIO设置为IIS功能管脚
void IIS_PortSetting(void)
{
   
     //配置L3接口总线,GPB2:L3MODE, GPB3:L3DATA, GPB4:L3CLOCK   
  rGPBUP  = rGPBUP  & ~(0x7<<2) | (0x7<<2);   //GPB[4:2] 上拉电阻无效   
  rGPBCON = rGPBCON & ~(0x3f<<4) | (0x15<<4); //GPB[4:2] 输出   
  rGPBDAT = 0x1e4;                            //起始状态 : L3M=H, L3C=H
            
     // I2SSDO:GPE4 I2SSDI:GPE3 CDCLK:GPE2 I2SSCLK:GPE1 I2SLRCK:GPE0
  rGPEUP  = rGPEUP  | 0x1f;    //GPE[4:0] 上拉电阻无效
  rGPECON = rGPECON & ~(0x3ff) | 0x2aa;   //GPE[4:0]配置为I2SSDO:I2SSDI:CDCLK:I2SSCLK:I2SLRCK
}   
void WriteL3(unsigned char data, int mode)   
{   
     int i,j;   
     if(mode == 1)   
     {   
         rGPBDAT = rGPBDAT&(~(L3D | L3M |L3C)) |L3C;    //地址模式,根据手册L3M为LOW,L3C为high   
      
     }  
     else
     {   
         
     rGPBDAT = rGPBDAT & (~(L3D |L3M |L3C)) | (L3M|L3C); //数据模式 L3M为高   
   
     }   
     delay(10);                                          //tsu(L3) > 190ns
     //传输数据   
     for(i=0;i<8;i++)                    //数据传输中L3MODE为低,8个L3CLOCK脉冲
     {
         if(data&0x01)   
         {   
        
    rGPBDAT &= ~L3C;            //L3C=L
    rGPBDAT |= L3D;             //L3D=H              
       delay(10);                  
    rGPBDAT |= L3C;             //L3C=H
    rGPBDAT |= L3D;             //L3D=H            
    delay(10);     
         }   
         else
         {
         
          rGPBDAT &= ~L3C;            //L3C=L
    rGPBDAT &= ~L3D;            //L3D=L
    delay(10);     
    rGPBDAT |= L3C;             //L3C=H
    rGPBDAT &= ~L3D;            //L3D=L                 
        delay(10);     
         }
     data>>=1;
     }
     rGPBDAT = rGPBDAT & ~(L3D | L3M | L3C) | (L3C | L3M);          //L3M=H,L3C=H   
   
}      
//配置UDA1341
unsigned UDA1341_Init(void)
{
   
  int sound_volume=35; //音量,数据越小音量越大
     WriteL3(0x16,1);      
     WriteL3(0x60,0); // 0,1 ,10,000,0  复位   
         
     WriteL3(0x16,1);   
     WriteL3(0x10,0);  //0,0,01, 000,0 : 状态0, 384fs,IIS,no DC-filtering   
         
     WriteL3(0x16,1);   
     WriteL3(0xc1,0);           //1,0,0,0, 0,0,01:状态1,                                    
                                 //Gain of DAC 6 dB,Gain of ADC 0dB,ADC non-inverting,   
                                 //DAC non-inverting,Single speed playback,ADC-Off DAC-On   
                                 
     WriteL3(0x14,1 );         //DATA0  (000101xx+00)
     WriteL3(sound_volume,0); //1,0,0,0, 0,0,01 ,音量调节 数据越小音量越大                          
}

//开启IIS
void Start_IIS_DMA2(volatile unsigned char *start_addr, unsigned int play_size)
{     
      
      //  OSIntEnter();
      
    Tx_flag=0;
     //初始化DMA通道2
     rDMASKTRIG2 = (1<<2)|(0<<1); //关DMA通道2
     
     rDISRC2  = (int)(start_addr);   //源数据起始地址
     rDISRCC2 = (0<<1) | (0<<0);  //AHB系统总线,数据传送后源地址增加   
     
     rDIDST2  = ((unsigned int)IISFIFO);  //发送FIFO地址,目标地址
     rDIDSTC2 = (0<<2) | (1<<1) | (1<<0);//TC为0中断出现 ,APB外设总线,每次传输后地址不变   
     rDCON2   = (1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(0<<24)+(1<<23)+(0<<22)+(1<<20)+(play_size/2);
   
     rDMASKTRIG2 = (0<<2) | (1<<1) | (0<<0);     // DMA2通道打开
  
     //初始化IIS,开始发送
     rIISCON = (1<<5) | (0<<4)  | (1<<2) | (1<<1); //发送DMA请求使能,接收DMA请求禁止,IIS预分频器使能
     rIISPSR = 3<<5|3;                               //预分频A=3,B=3   
     //PCLK为时钟源,输出模式,IIS模式,每个声道16位,CODECLK=384fs,SCLK=32fs
     rIISMOD = (0<<9)|(0<<8) | (2<<6) | (0<<5) | (0<<4) | (1<<3) | (1<<2) | (1<<0);  
     rIISFCON = (1<<15) | (1<<13);                   //发送FIFO为DMA模式,发送FIFO使能
   
       rIISCON |= 0x1;             //启动IIS
        delay(1000);                              
        while(!Tx_flag){delay(100);}//此处要有延时,否则中断返回时,Tx_flag=1也不会跳过while往下执行
     Tx_flag=0;
            
     //IIS Tx Stop
     delay(10);                  
     rIISCON &= ~(1<<0);                   //IIS Interface stop
     rDMASKTRIG2  = (1<<2);               //DMA2停止
     rIISFCON     = 0x0;                   //发送/接收 FIFO 禁止   
}
//DMA2中断初始化
void  IIS_DMA2_Int_Init(void)
{
        rPRIORITY = 0x00000000;       // 使用默认的固定的优先级
  rINTMOD = 0x00000000;       // 所有中断均为IRQ中断  
  rINTPND |= BIT_DMA2 ;   // clear pending bit
     rSRCPND |= BIT_DMA2 ;
     rINTMSK |= (BIT_DMA2); //关中断
     pISR_DMA2  = (unsigned)DMA2_IIS_End; //注册向量表
  rINTMSK &= ~(BIT_DMA2);           //开中断
}
//执行IIS
void Speaking_wav(void)
{
    volatile unsigned char *sound_buf=downloadAddress;//声音数据存放首地址给sound_buf
   // unsigned char *sound_buf;        
    unsigned int i;
    unsigned int downloadSize = 243552;
         
   // sound_buf = (unsigned char *)downloadAddress ;
    for( i = 0; i < 243552; i++ )   sound_buf = WindowsXP_Wav ;
  
    IIS_PortSetting();
    UDA1341_Init();
    Start_IIS_DMA2(sound_buf,downloadSize);      
}
//中断服务程序
void  DMA2_IIS_End(void)
{
    ClearPending(BIT_DMA2); //清除中断标志位
     
     rINTMSK &= ~(BIT_DMA2); //开中断,以等待下次中断
     
     Tx_flag=1;
}

201101301047112.jpg (28.26 KB )

201101301047112.jpg

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

6

帖子

1

粉丝