📄 task.c
字号:
case LFS_WRITE: error = task_lfs_write(request); break;
case LFS_CLOSE: error = task_lfs_close(request); break;
case LFS_REMOVE: error = task_lfs_remove(request); break;
#endif
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) {
T_RV_RETURN mycp;
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
// Save cp and id before we reuse the mail mem.
memcpy(&mycp, request->cp, sizeof(mycp));
temp_id = request->request_id;
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 (mycp.callback_func) {
mycp.callback_func((T_FFS_STREAM_CNF *) confirm_stream);
}
else if (mycp.addr_id) {
os_error = OS_MAIL_SEND(mycp.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 (mycp.callback_func) {
mycp.callback_func((T_FFS_FILE_CNF *) confirm_file);
}
else if (mycp.addr_id) {
os_error = OS_MAIL_SEND(mycp.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();
}
OS_DELETE_MUTEX(&ffs_write_mutex);
}
#if (WITH_TFFS == 1)
/******************************************************************************
* FFS Test Task - Defines, globals and function prototypes
******************************************************************************/
/// The size of the stack required to run the TFFS SWE.
#define TFFS_STACK_SIZE (1024)
/// The size of the primary memory bank.
#define TFFS_MB_PRIM_SIZE (1024 * 65)
/// The watermark of the primary memory bank.
#define TFFS_MB_PRIM_WATERMARK (TFFS_MB_PRIM_SIZE - 128)
/// The total of memory required by the TFFS SWE.
#define TFFS_POOL_SIZE (TFFS_STACK_SIZE + TFFS_MB_PRIM_SIZE)
#define TFFS_TASK_PRIORITY 248
// NOTEME move the below 3 lines to one structure?
T_RVF_ADDR_ID tffs_addr_id;
T_OS_MB_ID tffs_mb_id;
char ffs_test_string[128];
void ffs_test_task(void);
void test_init(int keepgoing);
int test_run(char *testname);
UINT32 rvf_get_tick_count(void);
/******************************************************************************
* FFS Test Task
******************************************************************************
The following steps are needed to get the FFS test task running:
1. Type the following line in rvm_use_id_list.h:
#define TFFS_USE_ID BUILD_USE_ID( 0, TEST_USE_ID_CLUSTER_1, 0x0004)
2. Add the below lines in create_RVtask.c:
#ifdef RVM_FFS_SWE
rv_start_swe_and_check (TFFS_USE_ID, "TFFS");
#endif
3. Add the below 2 line in the used xxx.mak file
export TFFS_STATE=1
TFFS_SOURCE=1
4. In ffs.mak: WITH_TFFS should be 1 and tffs.c, tcases.c and tdata.c
should be compiled in.
5. Compile and run the tests by typing 'tffs [test string]' in the TMSH shell.
******************************************************************************/
// Delay for <delay> milliseconds
void tffs_delay(int delay)
{
delay = 14 * delay / 64; // approx. same as division by 60/13
OS_DELAY(delay);
}
// 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 *tffs_malloc(unsigned int size)
{
char *buf;
if ((rvf_get_buf(tffs_mb_id, size, (T_RVF_BUFFER*) &buf)) == RVF_RED)
return 0;
else
return buf;
}
T_RVM_RETURN tffs_start(void)
{
effs_t error;
OS_DELAY(217); // wait approx. 1000ms
ttw(str(TTrTest, "ffs_test_task() running" 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));
}
}
return RVM_OK;
}
T_RVM_RETURN tffs_set_info(T_RVF_ADDR_ID addr_id,
T_RV_RETURN_PATH return_path[],
T_RVF_MB_ID bk_id_table[],
T_RVM_CB_FUNC call_back_error_ft)
{
tffs_addr_id = addr_id;
tffs_mb_id = bk_id_table[0];
return RVM_OK;
}
T_RVM_RETURN tffs_null(void)
{
return RVM_OK;
}
T_RVM_RETURN tffs_get_info(T_RVM_INFO_SWE * swe_info)
{
/* The SWE is a Type 4 SWE */
swe_info->swe_type = RVM_SWE_TYPE_4;
/* Used for info */
memcpy(swe_info->type_info.type4.swe_name, "TFFS", sizeof("TFFS"));
swe_info->type_info.type4.version = BUILD_VERSION_NUMBER(0,1,0);
/*
* This is the real way to indentify a SWE.
* Look in:
* - rvm_use_id_list.h if the SWE is part of the standard SDK.
* - rvm_ext_use_id_list.h for custom/under development SWEs.
*/
swe_info->type_info.type4.swe_use_id = TFFS_USE_ID;
/* Active SWE specific info */
swe_info->type_info.type4.stack_size = TFFS_STACK_SIZE;
swe_info->type_info.type4.priority = TFFS_TASK_PRIORITY;
/* End of specific */
/* Memory bank info */
swe_info->type_info.type4.nb_mem_bank = 1;
memcpy(swe_info->type_info.type4.mem_bank[0].bank_name, "TFFS_PRIM", sizeof("TFFS_PRIM"));
swe_info->type_info.type4.mem_bank[0].initial_params.size = TFFS_MB_PRIM_SIZE;
swe_info->type_info.type4.mem_bank[0].initial_params.watermark = TFFS_MB_PRIM_WATERMARK;
swe_info->type_info.type4.nb_linked_swe = 0;
/* Set the return path: NOT USED. */
swe_info->type_info.type4.return_path.callback_func = NULL;
swe_info->type_info.type4.return_path.addr_id = 0;
/* Generic functions */
swe_info->type_info.type4.set_info = tffs_set_info;
swe_info->type_info.type4.init = tffs_null;
swe_info->type_info.type4.stop = tffs_null;
swe_info->type_info.type4.kill = tffs_null;
/* Type 4 specific generic functions */
swe_info->type_info.type4.core = tffs_start;
/* End of specific */
return RVM_OK;
}
#endif // End of WITH_TFFS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -