⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 user.c

📁 Actions ucOS-II mp3方案源码,可以做参考
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*********************************************************************************************************
*                                                USDK80
*                                                The FIFO
*                                               user api
*                            
*                                           All Rights Reserved
*
* File : user.c
* By   : phchen
*********************************************************************************************************
*/
#include "FIFO.h"   
#include "fs_api.h" 
#include "TypeExt.h" 
#include "task_cfg.h"
#include "string.h"

extern void fifo_task(void);  
 
#pragma memory=dataseg(MOD_FIFO) 
user_head_t userfifo[MAX_FIFO];   
extern fifo_queue_t  fifo_queue; 
#pragma memory=default

#pragma memory=dataseg(DRAM_BUFFER) 
char buff[512]; 

#pragma memory=default
 
/*
Description : 初始化FIFO ,包括FIFO缓冲区,文件选择器。
Arguments   : 
Returns     : 
Notes       : 系统启动时进行初始化,支持多个应用。
*/
void api_init(void)
{
    char i;
    
    // 初始化用户控制块.
    //for(i = 0; i< MAX_FIFO; i++)
    //    userfifo[i].flag = 0;
    memset(&userfifo, 0x00, sizeof(user_head_t) * MAX_FIFO);
    memset(&fifo_queue, 0x00, sizeof(fifo_queue_t) );
    // 初始化文件选择模块.
    api_sel_init();
    
    // 创建缓冲任务
    OSTaskCreate((void(*)(void *))(long)fifo_task,    (void *)0x0000, 
                            (void *)FIFO_SPACE, FILESEL_ENGINE_PRIO, FILESEL_ENGINE_ID);  
}

/*
Description : 释放占有的资源 ,包括FIFO缓冲区,文件选择器。
Arguments   : 
Returns     : 
Notes       : 
*/
void api_exit(void)
{
    bool isTrue = TRUE;
    
//    // 检查是否有任务还在使用缓冲区,如有,不能杀死守护任务。
//    for(i = 0; i< MAX_FIFO; i++)
//    {
//        if( 0 != userfifo[i].flag )
//            isTrue = FALSE;
//    }

    // 文件选择模块的exit
    api_sel_exit();
    
    // 清除所有缓冲区。
    memset(&userfifo, 0x00, sizeof(user_head_t) * MAX_FIFO);
    
//    if(isTrue)
//    {
//        // 杀死缓冲守护任务   
//         
//    }
}

/*
Description : 打开一个缓冲区应用。
Arguments   : // mode: bit7,不需要文件选择器;bit6,不需要FIFO;其它的认为需要FIFO且表明文件选择的类型。
              rwFlag: 读写标志,1:读,2:写,3:读写。
              addr:FIFO起始地址;
              length:FIFO长度.
              //param:  这是文件选择时附加的参数,由用户和文件选择器设计者协商。
Returns     : 如果成功返回用户控制块序号(目前只有1,2);不成功返回NULL.
Notes       : 
*/
//int api_open(char rwFlag, unsigned char mode, int param)
int api_open(unsigned char rwFlag, long addr, long length)
{
    int i, j;
    if( length < FIFO_MINI_LENGTH )
        return FIFO_USER_ERR;
        
    for(i=0;i<MAX_FIFO;i++)
    {
        if(0 == userfifo[i].flag)
        {
            userfifo[i].flag = OS_GetTaskID();
            userfifo[i].rflag = rwFlag;
            
            if( !(rwFlag & 0x40) )
            {   
                api_files_init(&userfifo[i].files, addr, length);
            } 
            OSTimeDly(5); 
            return (i + 1);  
        }
    }
    return 0;
}

/*
Description : 关闭缓冲区 ,包括FIFO缓冲区,文件选择器。
Arguments   : 
Returns     : 
Notes       : 
*/
int api_close(int UHandle)
{
    user_head_t *user;
    
    if(UHandle < 1 && UHandle > MAX_FIFO)
        return FIFO_USER_ERR;
        
    user = &userfifo[UHandle -1];
    if( user->info.appendFlag )
    {
        // 关闭缓冲任务对该缓冲区的缓冲.
        // 由于不知道当前缓冲区是否正在缓冲,需要等待守护任务的回应。
        user->info.resetFlag = 0xFF;
        api_putUserToWaitingQueue(user);
    }
    if(user->fp)
    {
        FS_FClose( (FS_FILE *)user->fp );
        user->fp = 0;
    }
    if( user->rflag )
    {
        api_sel_close(user->sel);
    }
    // 清除数据块所有数据
    // user->flag = 0;
    memset(&userfifo[UHandle -1], 0x00, sizeof(user_head_t) );
    
    return 1;
}

/*
Description : 打开列表中下一个缓冲FIFO文件。
Arguments   : handle:用户控制块号,open返回时的标号。
              num:上一个文件序号,供校验。
Returns     : 正确返回: 文件; 0,没有文件; 负数:错误号。
Notes       : 打开指定文件序号的下一个文件。
*/
int api_OpenNextFile(int UHandle)
{
    user_head_t *user;
    int filenum;
    
    if(UHandle < 1 && UHandle > MAX_FIFO)
        return FIFO_USER_ERR;
    user = &userfifo[UHandle -1];
    
    // 文件选择模块未初始化。
    if(0 == user->sel)
        return FIFO_USER_ERR;
    
    if( ( filenum = api_files_openNextFile(&user->files) ) <= 0)
    {   // 文件队列中没有当前需要的文件.
        user->info.nextFileNo = api_files_getCurFileNo(&user->files);
        if(user->info.appendFlag)
        {
            user->info.resetFlag = 1;
        }
        user->info.appendFlag = 0x05;
        user->info.length = 0;
        api_putUserToWaitingQueue(user);
        // 如果经过缓冲之后还没有文件,可以认为没有下一个文件或文件选择有误.
        if( ( filenum = api_files_openNextFile(&user->files) ) <= 0)
            return 0;
    }
    return filenum;
}


/*
Description : 打开列表中下某一序号的文件。
Arguments   : handle:用户控制块号,open返回时的标号。
              num:打开的文件序号。
Returns     : 正确返回: 文件号,负数:错误号。
Notes       : 该接口检查缓冲区中是否有该文件,如没有从num文件号开始缓冲。
*/
int api_OpenFileByNo(int UHandle, int num)
{
    user_head_t *user;
    int fileNo;
    
    if(UHandle < 1 && UHandle > MAX_FIFO)
        return FIFO_USER_ERR;
    user = &userfifo[UHandle -1];
    
    if( ( fileNo = api_files_openFileByNum(&user->files, num) ) <= 0)
    {   // 文件队列中没有当前需要的文件.
        // 重新缓冲文件.
        //api_files_reset(&user->files);
        user->info.appendFlag = 0x04;
        user->info.resetFlag = 1;
        user->info.nextFileNo = num;
        user->info.length = 0;
        user->info.err = 0;
        api_putUserToWaitingQueue(user);
        if( ( fileNo = api_files_openFileByNum(&user->files, num) ) <= 0)
            return 0;
    }
    return fileNo;
}



/*
Description : 打开列表中上一个缓冲FIFO文件。
Arguments   : handle:用户控制块号,open返回时的标号。
              num:上一个文件序号,供校验。
Returns     : 正确返回: 文件号,负数:错误号。
Notes       : 该接口检查缓冲区中是否有该文件,如没有从num文件号开始缓冲。
*/
int api_OpenPrevFile(int UHandle)
{
    user_head_t *user;
    int fileNo;
    
    if(UHandle < 1 && UHandle > MAX_FIFO)
        return FIFO_USER_ERR;
    user = &userfifo[UHandle -1];
    
    if( ( fileNo = api_files_openPrevFile(&user->files) ) <= 0)
    {   // 文件队列中没有当前需要的文件.
        user->info.nextFileNo = api_files_getCurFileNo(&user->files);
        if(user->info.appendFlag)
        {
            user->info.resetFlag = 1;
        }
        user->info.appendFlag = 0x06;
        user->info.length = 0;
        api_putUserToWaitingQueue(user);
        if( ( fileNo = api_files_openPrevFile(&user->files) ) <= 0)
            return 0;
    }
    return fileNo;
}

/*
Description : 按文件名打开或创建文件.
Arguments   : name:读写文件名
              handle:用户控制块号,open返回时的标号。
Returns     : 负数是错误号。
Notes       : 主要用于直接打开文件,不经过文件选择器。如open时的模式需要文件选择器(即mode<40),返回错误。
*/
int api_OpenFile(int UHandle, char *name)
{
    user_head_t *user;
    int filenum;
    int filehandle;
    
    if(UHandle < 1 && UHandle > MAX_FIFO)
        return FIFO_USER_ERR;
    user = &userfifo[UHandle -1];
    
        api_files_reset(&user->files);
        if(user->rflag & 0x01)
        {
            // 在这里应该增加文件选择器的附加处理.
            filehandle = (int)FS_FOpen(name, "rb");
            user->info.resetFlag = 1;
            user->info.appendFlag = 0x01;
            user->info.length = 0;
            user->fp = filehandle;
            api_putUserToWaitingQueue(user);
        }else {
             filehandle = (int)FS_FOpen(name, "ab");
             user->info.resetFlag = 0;
             user->info.appendFlag = 0x00;
             user->info.length = 0;
             user->fp = filehandle;
        }

    return 1;
}


/*
Description : 关闭FIFO文件 
Arguments   : handle:用户控制块号,open返回时的标号。
Returns     : 正确返回: 1,负数:错误号。
Notes       : 
*/
int api_CloseFile(int UHandle)
{
    user_head_t *user;
    
    if(UHandle < 1 && UHandle > MAX_FIFO)
        return FIFO_USER_ERR;
    user = &userfifo[UHandle -1];
    
    if(user->rflag & 0x02)
    {
        user->info.appendFlag = 0xff;
        api_putUserToWaitingQueue(user);
        FS_FClose(( FS_FILE *)user->fp);
        user->fp = 0;
    }
    return 1;
}


/*
Description : 读FIFO文件 
Arguments   : handle:用户控制块号,open返回时的标号。
              buffer:数据区
              length:读数据的长度。
Returns     : 返回读数据的长度,0:读到文件末尾,负数:错误号。
Notes       : 
*/
int api_ReadFile(int UHandle, char *buffer, int length)
{
    user_head_t *user;
    int result, tmp;
    unsigned char alignPtr;
    long space;
    
    if(UHandle < 1 && UHandle > MAX_FIFO)
        return FIFO_USER_ERR;
    user = &userfifo[UHandle -1];
    
    OS_ENTER_CRITICAL();   
    if((int)buffer < 0x3fff)
    {
        result = api_files_read(&user->files, buff, length);
    }else {
        result = api_files_read(&user->files, buffer, length);
    }
    if(result > 0)
    {
        if(0 == user->info.appendFlag)
        {
            space = api_fifo_testSpace(&user->files.fifo,1,0);
            if(user->files.alignPtr >= MAX_FILES - 2)
            {
                alignPtr = 0;
            }else {
                alignPtr = user->files.alignPtr + 2;
            }
            
            if( (space <= FIFO_RESTART_LENGTH) && ( user->files.files[alignPtr].fileNo < user->files.curFileNo ) )
            {
                user->info.appendFlag = 1;
                api_putUserToFifoQueue(user);
            }
        }
    }else if(0 > result) {
        // 没有数据.
        if(!user->info.appendFlag)
        {
            user->info.appendFlag = 1;
        }
        OS_EXIT_CRITICAL();
        api_putUserToWaitingQueue(user);
        OS_ENTER_CRITICAL();
        if((int)buffer < 0x3fff)
        {
            result = api_files_read(&user->files, buff, length);
        }else {
            result = api_files_read(&user->files, buffer, length);
        }
    }
    if(result > 0 && (int)buffer < 0x3fff)
    {
        //memcpy(buffer, buff, result);
        memcpyDMA(buffer, buff, result-1);
    }
    OS_EXIT_CRITICAL();
    return result;
}


/*
Description : 重定位FIFO文件指针。 
Arguments   : handle:用户控制块号,open返回时的标号。
              mode:偏移模式。0:从头部开始,1:从当前指针开始,2:从文件末尾开始。
              offset:文件偏移量。
Returns     : 正确返回: 1,负数:错误号。
Notes       : 
*/
int api_SeekFile(int UHandle, char mode, long offset)
{
    user_head_t *user;
    int result;
    long lng;
    
    if(UHandle < 1 && UHandle > MAX_FIFO)
        return FIFO_USER_ERR;
    user = &userfifo[UHandle -1];
    
    if(user->rflag & 0x02)
    {   // 写文件的SEEK.
        if(user->files.offsetFileEnd)
        {
            user->info.appendFlag = 1;
            api_putUserToWaitingQueue(user);
        }
        result = FS_FSeek((FS_FILE *)user->fp, offset, mode);
    }
    else 
    {   // 读文件的SEEK.
        result = api_files_seek(&user->files, mode, offset);
        if(result < 0)
        {// 错误处理,数据不在FIFO中.
            // 目前只是简单的RESET,再LOAD数据.
            //api_files_reset(user->files);
            //api_putUserToFifoQueue(user);
            lng = api_files_changeSeekMode(&user->files, mode, offset);
            if(lng > user->files.curFileLength - user->files.offsetFileEnd)
            {
                user->info.appendFlag = 0x81;
            }else {
                user->info.appendFlag = 0x82;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -