NSUKit 1.4.0
板卡级统一交互接口
载入中...
搜索中...
未找到
data_upload.cpp
浏览该文件的文档.
1
2// Copyright (c) 2024. Naishu
3// NSUKit is licensed under Mulan PSL v2.
4// You can use this software according to the terms and conditions of the Mulan PSL v2.
5// You may obtain a copy of Mulan PSL v2 at:
6// http://license.coscl.org.cn/MulanPSL2
7// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10// See the Mulan PSL v2 for more details.
12
13//
14// Created by jilianyi<jilianyi@naishu.tech> on 2024/4/12.
15//
16
17/*
18 * +---------------+ +-------------------+
19 * | | +---------------+ | |
20 * | |-----> | full_queue |-----> | |
21 * | | +---------------+ | |
22 * | upload_thread | | write_file_thread |
23 * | | +---------------+ | |
24 * | |<----- | empty_queue |<----- | |
25 * | | +---------------+ | |
26 * +---------------+ +-------------------+
27 * @class ThreadSafeQueue
28 */
29#include <iostream>
30#include <queue>
31#include <thread>
32#include <condition_variable>
33#include "NSUKit.h"
34
35
36//#define STREAM_WITH_PCIE
37#define STREAM_WITH_TCP
38#define SocType nsukit::NSUSoc <nsukit::SimCmdUItf, nsukit::SimCmdUItf, nsukit::SimStreamUItf>
39
40#ifdef STREAM_WITH_PCIE
41#define SocType nsukit::NSUSoc <nsukit::TCPCmdUItf, nsukit::TCPCmdUItf, nsukit::PCIEStreamUItf>
42#endif
43
44#ifdef STREAM_WITH_TCP
45#define SocType nsukit::NSUSoc <nsukit::TCPCmdUItf, nsukit::TCPCmdUItf, nsukit::TCPStreamUItf>
46#endif
47
48
53template <typename T>
54class ThreadSafeQueue {
55public:
57
58 //
59 void Push(T *value) {
60 std::unique_lock<std::mutex> lock(mutex_);
61 queue_.push(value);
62 lock.unlock();
63 condition_.notify_one();
64 }
65
66 //
67 T *Pop() {
68 std::unique_lock<std::mutex> lock(mutex_);
69 condition_.wait(lock, [this] { return !queue_.empty(); });
70 auto value = (T *)queue_.front();
71 queue_.pop();
72 return value;
73 }
74
75private:
76 std::queue<T *> queue_;
77 std::mutex mutex_;
78 std::condition_variable condition_;
79};
80
81
83
84
85struct Deque {
86 memQueue full{};
88 int stopFlag = 0;
89};
90
91
100void upload_thread(nsukit::BaseKit *_kit, Deque *q, nsuSize_t block, nsuSize_t total, std::mutex *mu) {
101 std::unique_lock<std::mutex> *lock;
102 nsuMemory_p mem;
103 nsuSize_t current = 0;
104 while (true) {
105 mem = q->empty.Pop();
106 auto s = _kit->open_recv(0, mem, block, 0);
108 std::cout << "Establish CS and CR connections: " << std::endl;
109 std::cout << "Failed to enable data uplink " << nsukit::status2_string(s) << ", currently uplinked: " << current << std::endl;
110 break;
111 }
114 s = _kit->wait_stream(mem, 1.);
115 }
116 current += block;
117 q->full.Push(mem);
118 if (current == total) {
119 break;
120 };
121 }
122 lock = new std::unique_lock<std::mutex>(*mu);
123 q->stopFlag = 1;
124 delete lock;
125}
126
127
136void write_file_thread(nsukit::BaseKit *_kit, Deque *q, nsuSize_t block, const std::string &path, std::mutex *mu) {
137 std::unique_lock<std::mutex> *lock;
138 nsuMemory_p mem;
139 std::ofstream outF;
140 outF.open(path, std::ofstream::binary);
141 int cnt = 0;
142 nsuSize_t speed_count = 0;
143 auto st = std::chrono::steady_clock::now();
144
145 while (true) {
146 lock = new std::unique_lock<std::mutex>(*mu);
147 if (q->stopFlag == 1) {
148 break;
149 }
150 delete lock;
151 mem = q->full.Pop();
152 outF.write((char *)_kit->get_buffer(mem, block), block);
153 q->empty.Push(mem);
154// std::this_thread::sleep_for(std::chrono::seconds(1));
155 speed_count += block;
156
157 if (cnt % 20 == 0) {
158 auto count = std::chrono::steady_clock::now() - st;
159 std::cout << std::flush << '\r' << "current write file speed: " << speed_count*1000./(count.count()) << "MB/s" << std::endl;
160 speed_count = 0;
161 st = std::chrono::steady_clock::now();
162 }
163 cnt++;
164 }
165 std::cout << std::endl;
166 outF.close();
167}
168
169
170int main(int argc, char *argv[]) {
171 unsigned int ds_block = 1024*1024;
172 Deque q;
173 std::mutex mu;
174 SocType* kit = new SocType{};
175
176 if (argc != 4) {
177 std::cout << "Unsupported parameter passing method" << std::endl;
178 // DataUpload 127.0.0.1 104857600 ./da_data_1.dat
179 std::cout << argv[0] << " {IP} {totalBytes} {filePath}" << std::endl;
180 return 1;
181 }
182 nsuSize_t total_len = std::atoi(argv[2]);
183 if (total_len % ds_block != 0) {
184 std::cout << "The total length of upstream data total_len "
185 << total_len << " Bytes should be "
186 << ds_block << "Integer multiple of Bytes" << std::endl;
187 return 1;
188 }
189
190 nsuInitParam_t param;
191 param.cmd_ip = argv[1];
192 param.cmd_board = 0;
193 param.stream_board = 0;
194#ifdef STREAM_WITH_TCP
195 auto ip = std::string(argv[1]);
196 // 192.168.1.161 => 6001
197 std::string port_str{};
198 port_str += ip[ip.length()-2];
199 port_str += "00";
200 port_str += ip[ip.length()-1];
201 int port = std::atoi(port_str.data());
202 param.stream_ip = ip;
203 param.stream_tcp_port = port;
204 param.stream_tcp_block = 4 * 1024 * 1024;
205#endif
206
207 auto res = kit->link_cmd(&param);
209 std::cout << "Establish CS and CR connections: " << nsukit::status2_string(res) << std::endl;
210 }
211
212 res = kit->link_stream(&param);
214 std::cout << "Establish a DS connection: " << nsukit::status2_string(res) << std::endl;
215 }
216
217 std::cout << "SocLink Successful!!! now alloc buffer" << std::endl;
218 for (int i=0; i<10; i++) {
219 nsuMemory_p mem = kit->alloc_buffer(ds_block);
220 q.empty.Push(mem);
221 }
222
223 res = kit->execute("RFConfig");
224 std::cout << "Soc Init Successful!!!" << std::endl;
225
226 kit->set_param("TotalTriggerPoints", 128); // 128k sample points
227 kit->set_param("PreTriggerPoints", 512); // pre sample 512 points
228 kit->set_param("CH0TriggerEnable", 1); // enable CH0 Trigger
229 kit->set_param("CH0TriggerLevel", 4096); // config CH0 Trigger level
230 res = kit->execute("ADTriggerConfig");
231 std::cout << "ADTrigger Config Successful!!!" << std::endl;
232
233 res = kit->execute("SocStop");
235 std::cout << "SocStop: " << nsukit::status2_string(res) << std::endl;
236 }
237
238 // Start the upstream and storage threads.
239 std::thread up_trd(upload_thread, kit, &q, ds_block, total_len, &mu);
240 std::thread write_trd(write_file_thread, kit, &q, ds_block, argv[3], &mu);
241
242 std::cout << "Stream thread start successful!!!" << std::endl;
243
244#ifdef STREAM_WITH_TCP
245 kit->set_param(u8"ADC数据输出方式", 1);
246 std::cout << "Use TCP get data stream" << std::endl;
247#else
248 kit.set_param(u8"ADC数据输出方式", 0);
249 std::cout << "Use PCIE get data stream" << std::endl;
250#endif
251 // Notify FPGA to start data acquisition.
252 res = kit->execute("SocStart");
254 std::cout << "SocStart: " << nsukit::status2_string(res) << std::endl;
255 }
256 up_trd.join();
257 write_trd.join();
258
259 // Notify FPGA to stop data acquisition.
260 res = kit->execute("SocStop");
262 std::cout << "SocStop: " << nsukit::status2_string(res) << std::endl;
263 }
264
265 std::cout << "Data upload completed" << std::endl;
266
267 return 0;
268}
void Push(T *value)
Definition: data_upload.cpp:59
virtual nsukitStatus_t open_recv(nsuChnlNum_t chnl, nsuMemory_p fd, nsuStreamLen_t length, nsuStreamLen_t offset=0)
Definition: base_kit.h:98
virtual nsuVoidBuf_p get_buffer(nsuMemory_p fd, nsuStreamLen_t length=0)
Definition: base_kit.h:76
virtual nsukitStatus_t wait_stream(nsuMemory_p fd, float timeout=0.)
Definition: base_kit.h:103
nsukitStatus_t execute(nsuCSParam_t cname) override
Definition: NSUKit.h:463
nsukitStatus_t set_param(nsuCSParam_t &param_name, const uint8_t &value) override
Definition: NSUKit.h:527
nsukitStatus_t link_cmd(nsuInitParam_t *param) override
Definition: NSUKit.h:328
nsukitStatus_t link_stream(nsuInitParam_t *param) override
Definition: NSUKit.h:376
nsuMemory_p alloc_buffer(nsuStreamLen_t length, nsuVoidBuf_p buf=nullptr) override
Definition: NSUKit.h:575
void upload_thread(nsukit::BaseKit *_kit, Deque *q, nsuSize_t block, nsuSize_t total, std::mutex *mu)
void write_file_thread(nsukit::BaseKit *_kit, Deque *q, nsuSize_t block, const std::string &path, std::mutex *mu)
ThreadSafeQueue< void > memQueue
Definition: data_upload.cpp:82
std::string NSU_DLLEXPORT status2_string(nsukitStatus_t status)
Definition: config.cpp:15
int stopFlag
memQueue empty
memQueue full
std::string cmd_ip
Definition: type.h:98
uint32_t stream_tcp_block
Definition: type.h:104
std::string stream_ip
Definition: type.h:102
uint32_t stream_tcp_port
Definition: type.h:103
nsuBoardNum_t cmd_board
Definition: type.h:115
nsuBoardNum_t stream_board
Definition: type.h:121
@ NSUKIT_STATUS_STREAM_RUNNING
DLLEXTERN typedef size_t nsuSize_t
Definition: type.h:87
DLLEXTERN typedef void * nsuMemory_p
Definition: type.h:86