📄 task.c
字号:
/******************************************************************************
* Flash File System (ffs)
* Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com
*
* FFS task. ONLY for target!
*
* $Id: task.c,v 1.1.1.1 2004/06/19 06:00:30 root Exp $
*
******************************************************************************/
#include "board.cfg"
#include "ffs.h"
#include "core.h"
#include "task.h"
#include "ffstrace.h"
#include "rvm_use_id_list.h"
#include "ffs_api.h" //TISH
/******************************************************************************
* Globals and function prototypes
******************************************************************************/
extern UINT8 pcm_init(void);
void ffs_task(void);
static effs_t ffs_init_status;
req_id_t request_id_last = 0;
T_OS_MB_ID ffs_mb_id;
UINT16 ffs_addr_id;
extern struct ffs_blocking_s;
/******************************************************************************
* FFS Test Task
******************************************************************************/
// For this to work, change:
// 1. MAX_RVF_TASKS define in rvf_target.h
// Note that the FFS_TEST_TASK_ID is set one too low! We assume we are lucky
// that no other task has the same ID...
#if (WITH_TFFS == 1)
#define FFS_TEST_STACK_SIZE 1024
#define FFS_TEST_TASK_ID (MAX_RVF_TASKS - 1 - 1)
void ffs_test_task(void);
void test_init(int keepgoing);
int test_run(char *testname);
static uint8 ffs_test_stack[FFS_TEST_STACK_SIZE];
// This is the string of test cases to run by calling test_run(). This
// string as written to from tmffs module.
char ffs_test_string[128];
// Delay for <delay> milliseconds
void tffs_delay(int delay)
{
delay = 14 * delay / 64; // approx. same as division by 60/13
OS_DELAY(delay);
}
UINT32 rvf_get_tick_count(void);
// Timer functions for benchmarking
UINT32 tffs_timer_begin(void)
{
return rvf_get_tick_count();
}
UINT32 tffs_timer_end(UINT32 time_begin)
{
// return current time minus time_begin
UINT32 ticks;
ticks = rvf_get_tick_count();
return (ticks - time_begin) * 60 / 13;
}
void ffs_test_task(void)
{
effs_t error;
OS_DELAY(217); // wait approx. 1000ms
ttw(str(TTrTest, "ffs_test_task()" NL));
while (1) {
OS_DELAY(217); // wait approx. 1000ms
// Poll to see if we have tests to run... We know that the writer of
// ffs_test_string has a higher priority than us, so it is properly
// written when we reach here.
if (*ffs_test_string) {
test_init(0);
error = test_run(ffs_test_string);
*ffs_test_string = 0;
if (error == 0)
ttw(str(TTrTest, "TEST succeeded" NL));
else
ttw(ttr(TTrTest, "TEST cases failed: %d" NL, error));
}
}
}
#endif // End of WITH_TFFS
/******************************************************************************
* Target Platform Abstraction Functions
******************************************************************************/
req_id_t request_id_get(void)
{
extern uint32 int_disable(void);
extern void int_enable(uint32 tmp);
uint32 cprs;
// We disable interrupt to avoid any other tasks to get the same id.
cprs = int_disable();
request_id_last++;
if (request_id_last < 0)
request_id_last = 0;
int_enable(cprs);
return request_id_last;
}
void *target_malloc(unsigned int size)
{
char *buf;
#if (_RVF == 1)
if ((rvf_get_buf(ffs_mb_id, size, (T_RVF_BUFFER*) &buf)) == RVF_RED)
return 0;
else
return buf;
#else
return 0;
#endif
}
void target_free(void *buf)
{
int error;
#if (_RVF == 1)
if ((error = OS_FREE(buf)) != OS_OK)
ttw(ttr(TTrFatal, "target_free() %d (FAILED)" NL, error));
#endif
}
/******************************************************************************
* FFS Blocking Call Handling
******************************************************************************/
effs_t ffs_b_begin(struct ffs_blocking_s *fb, T_RVF_MUTEX *mutex, int *result)
{
effs_t error;
if ((error = rvf_initialize_mutex(mutex)) < 0)
return error;
if ((error = rvf_lock_mutex(mutex)) < 0) // This will succeed
return error;
fb->result = result;
fb->mutex = mutex;
return EFFS_OK;
}
effs_t ffs_b_end(T_RVF_MUTEX *mutex)
{
effs_t error;
// This will block the task until the mutex has been released
if ((error = rvf_lock_mutex(mutex)) < 0)
return error;
if ((error = rvf_unlock_mutex(mutex)) < 0)
return error;
if ((error = rvf_delete_mutex(mutex)) < 0)
return error;
return EFFS_OK;
}
/******************************************************************************
* FFS Task
******************************************************************************/
void ffs_main_init()
{
ttr_init(TTrTask|TTrTest|TTrTestInfo);
//ttr_init(TTrTask|TTrTest|TTrTestInfo|TTrDrvErase|TTrDrvWrite|TTrTaskLow|TTrApi);
ffs_init_status = ffs_initialize();
pcm_init(); // We have to call pcm_init() before G23 starts.
}
void ffs_task_init(T_OS_MB_ID mbid, T_RVF_ADDR_ID addr_id)
{
int error;
ffs_mb_id = mbid;
ffs_addr_id = addr_id;
#if (WITH_TFFS == 1)
error =
OS_CREATE_TASK((TASKPTR) ffs_test_task, FFS_TEST_TASK_ID, "TFFS",
ffs_test_stack, FFS_TEST_STACK_SIZE,
249, // priority
4, // ET4_TASK type
0, // no time slicing
RUNNING); // start state
ttw(ttr(TTrTask, "os_create_task('TFFS') %d" NL, error));
#endif
}
void ffs_task()
{
extern int etm_ffs_init(void);
struct ffs_req_s *request;
T_FFS_FILE_CNF *confirm_file;
T_FFS_STREAM_CNF *confirm_stream;
T_RVF_MUTEX *mutex_p;
int error, free_mail, os_error = OS_OK;
uint16 revision, manufacturer_id, device_id;
uint32 base;
fd_t fdi;
char *temp_path;
req_id_t temp_id;
#if (BOARD == 34)
// Non formatted FFS should be formatted
// So we don't have to use PCTM to format it
if (fs.initerror == EFFS_NOFORMAT)
{
ffs_format_nb("/", 0x2BAD, 0);
}
ffs_InitRFCap();
#endif
#if (BOARD == 40)
// Non formatted FFS should be formatted
// So we don't have to use PCTM to format it
if (fs.initerror == EFFS_NOFORMAT)
{
ffs_preformat(0xDEAD);
ffs_format("/",0x2BAD);
}
#endif
ttr(TTrTask, "ffs_init() %d" NL, ffs_init_status);
ffs_query(Q_FFS_REVISION, &revision);
ttr(TTrTask,"FFS revision: 0x%x" NL, revision);
ffs_query(Q_DEV_MANUFACTURER, &manufacturer_id);
ffs_query(Q_DEV_DEVICE, &device_id);
ffs_query(Q_DEV_DRIVER, &revision);
ttr(TTrTask,"FFS device, driver: 0x%02x, 0x%04x, %d" NL,
manufacturer_id, device_id, revision);
ffs_query(Q_DEV_BASE, &base);
ffs_query(Q_DEV_BLOCKS, &revision);
ttr(TTrTask,"FFS base, blocks: 0x%x, %d" NL, base, revision);
ffs_query(Q_FFS_FORMAT_READ, &manufacturer_id);
ffs_query(Q_FFS_FORMAT_WRITE, &device_id);
ttr(TTrTask,"FFS format read, write: 0x%x, 0x%x" NL NL,
manufacturer_id, device_id);
// If some blocks has been marked for reclaim, reclaim them now...
blocks_reclaim();
// We can only mkdir("pcm") *after* our mailbox has been allocated
// otherwise mkdir("pcm") will fail.
error = ffs_mkdir_nb("/pcm", 0);
// Register FFS to ETM database
error = etm_ffs_init();
while (1)
{
OS_MAIL_WAIT(OS_MAIL_EVENT_MASK);
request = (struct ffs_req_s *) OS_MAIL_READ();
ttw(ttr(TTrTaskLow, "ffs_task(%d):" NL, request->cmd));
switch (request->cmd) {
case WRITE: case SEEK: case CLOSE: case FTRUNC: case FDATASYNC:
ttw(ttr(TTrTaskLow, " fdi = %d" NL, request->fdi));
// Save a local copy of fdi because the task we call later can
// modify it and we have to use the fdi if a callback is used
fdi = (fd_t)request->fdi;
break;
default:
ttw(ttr(TTrTaskLow, " name = %s" NL, request->path));
break;
}
ttw(ttr(TTrTaskLow, " src = 0x%x" NL, request->src));
ttw(ttr(TTrTaskLow, " size = %d" NL, request->size));
if (tr_query(TTrTaskDelays))
OS_DELAY(5);
switch (request->cmd) {
case NOP: error = EFFS_OK; break;
case FILE_WRITE: error = task_file_write(request); break;
case SYMLINK: error = task_symlink(request); break;
case MKDIR: error = task_mkdir(request); break;
case REMOVE: error = task_remove(request); break;
case RENAME: error = task_rename(request); break;
case FCONTROL: error = task_fcontrol(request); break;
case PREFORMAT: error = task_preformat(request); break;
case FORMAT: error = task_format(request); break;
case OPEN: error = task_open(request); break;
case WRITE: error = task_write(request); break;
case SEEK: error = task_seek(request); break;
case CLOSE: error = task_close(request); break;
case TRUNC: error = task_trunc(request); break;
case FTRUNC: error = task_ftrunc(request); break;
case FDATASYNC: error = task_fdatasync(request); break;
default:
ttr(TTrFatal, "FFS FATAL: bad request: %d" NL, request->cmd);
break;
}
ttw(ttr(TTrTaskLow, "ffs_task(%d) %d" NL, request->cmd, error));
if (tr_query(TTrTaskDelays))
OS_DELAY(5);
// Call-back to caller
mutex_p = 0;
if (request->cp) {
free_mail = 0; // don't free mail we will reuse it
// We reuse the mail we received for our call-back. Due to
// this reuse, we must be careful with the order of
// assignments. If this is a stream modify function use
// ffs_stream_cnf else use ffs_file_cnf
temp_id = request->request_id; // Save id before we reuse the mail mem.
switch (request->cmd) {
case WRITE: case SEEK: case CLOSE: case FTRUNC: case FDATASYNC:
confirm_stream = (T_FFS_STREAM_CNF *) request;
confirm_stream->error = error;
confirm_stream->request_id = temp_id;
confirm_stream->fdi = fdi;
confirm_stream->header.msg_id = FFS_MESSAGE_OFFSET;
if (request->cp->callback_func) {
request->cp->callback_func((T_FFS_STREAM_CNF *)
confirm_stream);
}
else if (request->cp->addr_id) {
os_error = OS_MAIL_SEND(request->cp->addr_id,
confirm_stream);
}
else {
ttr(TTrFatal, "FFS WARNING: empty return path" NL);
free_mail = 1; // free mail
}
break;
default:
temp_path = (char *) request->path;
confirm_file = (T_FFS_FILE_CNF *) request;
confirm_file->error = error;
confirm_file->request_id = temp_id;
confirm_file->path = temp_path;
confirm_file->header.msg_id = FFS_MESSAGE_OFFSET;
if (request->cp->callback_func) {
request->cp->callback_func((T_FFS_FILE_CNF *) confirm_file);
}
else if (request->cp->addr_id) {
os_error = OS_MAIL_SEND(request->cp->addr_id,
confirm_file);
}
else {
ttr(TTrFatal, "FFS WARNING: empty return path" NL);
free_mail = 1; // free mail
}
break;
}
if (os_error != OS_OK)
ttr(TTrFatal, "FFS FATAL: os_send_msg() %d" NL, os_error);
}
// Blocking handling / unlocking mutex
else if (request->fb) {
// Save the pointer to the mutex and the error value (allocated
// on the stack by the macro FFS_BLOCKING_BEGIN)
mutex_p = request->fb->mutex;
*request->fb->result = error;
free_mail = 1; // free mail
}
else {
// The task must have been a non blocking without any callback
free_mail = 1; // free mail
}
// Free the mail memory. Note that we always free it, except when we
// have successfully reused it for sending a mail call-back.
if (free_mail == 1) {
os_error = OS_FREE(request);
if (os_error != OS_OK)
ttr(TTrFatal, "FFS FATAL: os_free() %d" NL, os_error);
}
// Blocking handling / unlocking mutex
if (mutex_p) {
// Wake up the caller task
if ((os_error = rvf_unlock_mutex(mutex_p)) < 0)
ttr(TTrFatal, "FFS FATAL: rvf_unlock_mutex() %d" NL, os_error);
}
tr_bstat();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -