我遇到嵌入式系统和一个库的问题。
我目前正在使用一种名为Ambiq [3]的设备,该设备使用Cortex M-4,我想在其上使用FANN(快速人工神经网络)库[2]。 我能够编译和链接所有内容,但问题是FANN库在启动时需要读取2个文件。
现在,我有一个嵌入式系统,所以我没有任何文件系统,也没有操作系统。 我非常确定我可以在某种程度上将该文件的内容写入闪存,但我真的不知道如何将第一个文件地址链接到C文件函数,例如"的fopen"需要文件名作为输入。我只需要文件名和文件的物理地址之间的一些连接,如果它退出(或接受与文件名不同的C函数),我就完成了。
我已经尝试过的一件事是使用xxd -i [filename] [1]将文件内容硬编码到C数组中,但我不知道应该如何链接fopen FANN库使用。我也启动了一些切割器解析器,但它似乎非常耗时。
如果你能给我一些建议,请告诉我。 先感谢您。 最好的祝福。 Jaskirat
其他信息: - 用于编译的软件:带有makefile的Eclipse。 - 编译器:eabi-none-gcc工具箱 - 我正在使用应该在Cortex M4上运行的Ambiq微控制器应用程序直接编译FANN库源代码。
参考文献: [1] Read a file into a string at compile-time [2] FANN LIBRARY UFFICIAL SITE http://leenissen.dk/fann/wp/ [3] AMBIQ MICRO:http://ambiqmicro.com/
答案 0 :(得分:2)
查看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;
}
答案 1 :(得分:0)
假设您拥有FANN库的源代码,最简单的解决方案是修改它以直接访问数据数组,而不是使用文件系统模型。
但是,如果您确实必须将文件系统访问模型实现为静态数据,则需要实现这些功能,或者在提供实现库重新定位存根的情况下。例如,如果您正在使用newlib,则通过实现较低级别的系统调用来启用更高级别的stdio文件功能。例如open()
的最小存根没有任何作用,看起来像:
int open(const char *name, int flags, int mode) {
return -1;
}
读取函数使用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中。