📄 user.c
字号:
/*
*********************************************************************************************************
* 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 + -