|
|
|
@ -214,3 +214,125 @@ close_and_clear:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
|
int ret = -1; // 初始化返回值为-1,表示程序可能运行失败
|
|
|
|
|
|
|
|
|
|
uint64_t millisecond; // 用于存储操作所花费的毫秒数
|
|
|
|
|
char usage_string[1024]; // 存储程序使用说明的字符串
|
|
|
|
|
|
|
|
|
|
char *dev_name, *file_name; // 分别指向设备名和文件名的指针
|
|
|
|
|
char direction; // 存储传输方向的字符,'t' 表示写入设备,'f' 表示读取设备
|
|
|
|
|
uint64_t address, size; // 存储设备地址和传输数据大小
|
|
|
|
|
|
|
|
|
|
int dev_fd = -1; // 设备文件描述符,初始设置为-1表示未打开设备
|
|
|
|
|
FILE *file_p = NULL; // 文件指针,初始为NULL
|
|
|
|
|
void *buffer = NULL; // 数据缓冲区指针,初始为NULL
|
|
|
|
|
|
|
|
|
|
// 根据程序名和命令行参数构造使用说明字符串
|
|
|
|
|
sprintf(usage_string, USAGE, argv[0], argv[0], argv[0], argv[0]);
|
|
|
|
|
|
|
|
|
|
// 检查命令行参数数量是否足够
|
|
|
|
|
if (argc < 6) {
|
|
|
|
|
puts(usage_string); // 打印使用说明
|
|
|
|
|
return -1; // 参数不足,退出程序
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 解析命令行参数
|
|
|
|
|
file_name = argv[1];
|
|
|
|
|
direction = argv[2][0];
|
|
|
|
|
dev_name = argv[3];
|
|
|
|
|
|
|
|
|
|
// 解析设备地址和数据大小,如果解析失败则打印使用说明并退出
|
|
|
|
|
if (parse_uint(argv[4], &address) == 0) {
|
|
|
|
|
puts(usage_string);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (parse_uint(argv[5], &size) == 0) {
|
|
|
|
|
puts(usage_string);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据传输方向打印操作信息
|
|
|
|
|
if (direction == 't') {
|
|
|
|
|
printf("从: %s\n至: %s 地址=0x%lx\n大小: 0x%lx\n", file_name, dev_name, address, size);
|
|
|
|
|
} else if (direction == 'f') {
|
|
|
|
|
printf("从: %s 地址=0x%lx\n至: %s\n大小: 0x%lx\n", dev_name, address, file_name, size);
|
|
|
|
|
} else {
|
|
|
|
|
puts(usage_string);
|
|
|
|
|
return -1; // 无效的方向参数
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查数据大小是否合法
|
|
|
|
|
if (size > DMA_MAX_SIZE || size == 0) {
|
|
|
|
|
printf("*** 错误: DMA大小必须大于0且不超过 %lu\n", DMA_MAX_SIZE);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 分配缓冲区
|
|
|
|
|
buffer = malloc(size);
|
|
|
|
|
if (buffer == NULL) {
|
|
|
|
|
printf("*** 错误: 分配缓冲区失败\n");
|
|
|
|
|
goto close_and_clear; // 跳转到资源释放部分
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 打开设备
|
|
|
|
|
dev_fd = open(dev_name, O_RDWR);
|
|
|
|
|
if (dev_fd < 0) {
|
|
|
|
|
printf("*** 错误: 打开设备 %s 失败\n", dev_name);
|
|
|
|
|
goto close_and_clear;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 打开文件
|
|
|
|
|
file_p = (direction == 't') ? fopen(file_name, "rb") : fopen(file_name, "wb");
|
|
|
|
|
if (file_p == NULL) {
|
|
|
|
|
printf("*** 错误: 打开文件 %s 失败\n", file_name);
|
|
|
|
|
goto close_and_clear;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 记录操作开始时间
|
|
|
|
|
millisecond = get_millisecond();
|
|
|
|
|
|
|
|
|
|
// 根据传输方向进行读写操作
|
|
|
|
|
if (direction == 't') { // 写入设备
|
|
|
|
|
if (fread(buffer, 1, size, file_p) != size) {
|
|
|
|
|
printf("*** 错误: 读取文件 %s 失败\n", file_name);
|
|
|
|
|
goto close_and_clear;
|
|
|
|
|
}
|
|
|
|
|
if (dev_write(dev_fd, address, buffer, size)) {
|
|
|
|
|
printf("*** 错误: 写入设备 %s 失败\n", dev_name);
|
|
|
|
|
goto close_and_clear;
|
|
|
|
|
}
|
|
|
|
|
} else { // 读取设备
|
|
|
|
|
if (dev_read(dev_fd, address, buffer, size)) {
|
|
|
|
|
printf("*** 错误: 读取设备 %s 失败\n", dev_name);
|
|
|
|
|
goto close_and_clear;
|
|
|
|
|
}
|
|
|
|
|
if (fwrite(buffer, 1, size, file_p) != size) {
|
|
|
|
|
printf("*** 错误: 写入文件 %s 失败\n", file_name);
|
|
|
|
|
goto close_and_clear;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算并打印操作耗时和数据传输速率
|
|
|
|
|
millisecond = get_millisecond() - millisecond;
|
|
|
|
|
millisecond = (millisecond > 0) ? millisecond : 1; // 避免除以零错误
|
|
|
|
|
printf("耗时=%lu 毫秒 数据速率=%.1lf KB/s\n", millisecond, (double)size / millisecond / 1024);
|
|
|
|
|
|
|
|
|
|
ret = 0; // 如果一切正常,设置返回值为0,表示成功
|
|
|
|
|
|
|
|
|
|
close_and_clear: // 清理资源标签
|
|
|
|
|
|
|
|
|
|
// 释放缓冲区
|
|
|
|
|
if (buffer != NULL)
|
|
|
|
|
free(buffer);
|
|
|
|
|
|
|
|
|
|
// 关闭设备文件
|
|
|
|
|
if (dev_fd >= 0)
|
|
|
|
|
close(dev_fd);
|
|
|
|
|
|
|
|
|
|
// 关闭文件
|
|
|
|
|
if (file_p != NULL)
|
|
|
|
|
fclose(file_p);
|
|
|
|
|
|
|
|
|
|
return ret; // 返回程序执行结果
|
|
|
|
|
}
|
|
|
|
|