[英]C file functions in embedded world
我有一個嵌入式系統和一個庫的問題。
我目前正在使用一個名為Ambiq [3]的設備,該設備使用Cortex M-4,我想在其上使用FANN(快速人工神經網絡)庫[2]。 我能夠編譯和鏈接所有內容,但問題是FANN庫在啟動時需要讀取2個文件。
現在,我有一個嵌入式系統,所以我沒有任何文件系統,也沒有操作系統。 我很確定我可以在某種程度上將該文件的內容寫入閃存內但我真的不知道如何將第一個文件地址鏈接到C文件函數,例如“fopen”需要文件名作為輸入。 我只需要文件名和文件的物理地址之間的一些連接,如果它退出我就完成了(或者接受與文件名不同的C函數)。
我已經嘗試過的一件事是使用xxd -i [filename] [1]將文件內容硬編碼到C數組中,但我不知道應該如何鏈接FANN庫使用的fopen。 我也開始使用一些切割器解析器,但它似乎非常耗時。
如果你能給我一些建議,請告訴我。 先感謝您。 最好的祝福。 Jaskirat
附加信息: - 用於編譯的軟件:帶有makefile的Eclipse。 - 編譯器:eabi-none-gcc工具箱 - 我正在使用應該在Cortex M4上運行的Ambiq微控制器應用程序直接編譯FANN庫源代碼。
參考文獻:[1] 在編譯時將文件讀入字符串 [2] FANN LIBRARY UFFICIAL SITE http://leenissen.dk/fann/wp/ [3] AMBIQ MICRO: http ://ambiqmicro.com/
查看FANN源代碼,您需要重寫一個函數,並用sscanf替換fscanf並將指針傳遞給訓練數據....
struct fann_train_data *fann_read_train_from_fd(FILE * file, const char *filename)
{
unsigned int num_input, num_output, num_data, i, j;
unsigned int line = 1;
struct fann_train_data *data;
if(fscanf(file, "%u %u %u\n", &num_data, &num_input, &num_output) != 3)
{
fann_error(NULL, FANN_E_CANT_READ_TD, filename, line);
return NULL;
}
line++;
data = fann_create_train(num_data, num_input, num_output);
if(data == NULL)
{
return NULL;
}
for(i = 0; i != num_data; i++)
{
for(j = 0; j != num_input; j++)
{
if(fscanf(file, FANNSCANF " ", &data->input[i][j]) != 1)
{
fann_error(NULL, FANN_E_CANT_READ_TD, filename, line);
fann_destroy_train(data);
return NULL;
}
}
line++;
for(j = 0; j != num_output; j++)
{
if(fscanf(file, FANNSCANF " ", &data->output[i][j]) != 1)
{
fann_error(NULL, FANN_E_CANT_READ_TD, filename, line);
fann_destroy_train(data);
return NULL;
}
}
line++;
}
return data;
}
假設您擁有FANN庫的源代碼,最簡單的解決方案是修改它以直接訪問數據數組而不是使用文件系統模型。
但是,如果您確實必須為靜態數據實現文件系統訪問模型,則需要實現這些功能,或者在提供實現庫重新定位存根的情況下。 例如,如果您正在使用newlib,則通過實現較低級別的系統調用來啟用更高級別的stdio文件功能。 open()
的最小存根例如什么都不做,看起來像:
int open(const char *name, int flags, int mode) {
return -1;
}
read函數使用open
返回的句柄來訪問您根據需要定義的控件結構。 因此,讓我們假設您已經從文件數據生成靜態數據數組:
static const char file1[] = { '\x00`, `\x01`, ... } ;
static const char file2[] = { '\x00`, `\x01`, ... } ;
static struct
{
const char* file ;
int size ;
int index ;
} files[] = { {file1, sizeof(file1), -1}, {file2, sizeof(file2), -1} } ;
然后open()
變成:
int open(const char *name, int flags, int mode)
{
static const char* file_to_handle[] = { "file1", "file2", 0 } ; // change names to match the FANN library names.
int handle = -1 ;
for( int h = 0; file_to_handle[h] != 0 && handle == -1; h++ )
{
if( strcmp( file_to_handle[h], name ) == 0 && files[h].index == -1 )
{
handle = h ;
files[h].index = 0 ;
}
}
}
read()
實現:
int read(int file, char *ptr, int len)
{
int i = -1 ;
if( files[file].index > 0 )
{
i = 0 ;
while( files[file].index < files[file].size && i < len)
{
ptr[i] = files[file].index ;
i++ ;
files[file].index++ ;
}
}
return i ;
}
並close()
:
int close(int file)
{
files[file].index = -1 ;
return -1;
}
如果FANN使用對文件的隨機訪問,您可能還需要實現lseek()
。 這只是操縱files[file].index
。
這應該給你一個最小的只讀“硬編碼”文件系統。 請注意,為了清楚起見,我省略了檢查句柄是否有效以及其他可靠性和安全性代碼。 鑒於實現的只讀性質,您可能會或可能不會覺得有必要。 該代碼也是一個大綱,未經測試 - 將其視為偽代碼。
如果你沒有使用newlib,毫無疑問會有類似的重新定位存根,你可以簡單地以類似的方式覆蓋或實現更高級別的函數fopen()
等。
文件模型可能是內存耗盡,因為它可以通過修改FANN庫本身直接訪問ROM來將ROM內存復制到RAM中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.