NSUKit 1.4.0
板卡级统一交互接口
载入中...
搜索中...
未找到
multi_chnl_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/6/17.
15//
16
17
18/*
19 * +---------------+ +-------------------+
20 * | | +---------------+ | |
21 * | |-----> | full_queue |-----> | |
22 * | | +---------------+ | |
23 * | upload_thread | | write_file_thread |
24 * | | +---------------+ | |
25 * | |<----- | empty_queue |<----- | |
26 * | | +---------------+ | |
27 * +---------------+ +-------------------+
28 * @class ThreadSafeQueue
29 */
30#include <iostream>
31#include <queue>
32#include <thread>
33#include <condition_variable>
34#include "NSUKit.h"
35
36
37#define STREAM_WITH_PCIE
38//#define STREAM_WITH_TCP
39#define SocType nsukit::NSUSoc <nsukit::SimCmdUItf, nsukit::SimCmdUItf, nsukit::SimStreamUItf>
40
41#ifdef STREAM_WITH_PCIE
42#define SocType nsukit::NSUSoc <nsukit::PCIECmdUItf, nsukit::PCIECmdUItf, nsukit::PCIEStreamUItf>
43#endif
44
45#ifdef STREAM_WITH_TCP
46#define SocType nsukit::NSUSoc <nsukit::TCPCmdUItf, nsukit::TCPCmdUItf, nsukit::TCPStreamUItf>
47#endif
48
49
54template <typename T>
55class ThreadSafeQueue {
56public:
58
59 //
60 void Push(T *value) {
61 std::unique_lock<std::mutex> lock(mutex_);
62 queue_.push(value);
63 lock.unlock();
64 condition_.notify_one();
65 }
66
67 //
68 T *Pop() {
69 std::unique_lock<std::mutex> lock(mutex_);
70 condition_.wait(lock, [this] { return !queue_.empty(); });
71 auto value = (T *)queue_.front();
72 queue_.pop();
73 return value;
74 }
75
76private:
77 std::queue<T *> queue_;
78 std::mutex mutex_;
79 std::condition_variable condition_;
80};
81
82
84
85
86struct Deque {
87 memQueue full{};
89 int stopFlag = 0;
90};
91
92
101void upload_thread(nsukit::BaseKit *_kit, int stream_chnl, Deque *q, nsuSize_t block, nsuSize_t total, std::mutex *mu) {
102 std::unique_lock<std::mutex> *lock;
103 nsuMemory_p mem;
104 nsuSize_t current = 0;
105 while (true) {
106 mem = q->empty.Pop();
107 auto s = _kit->open_recv(stream_chnl, mem, block, 0);
109 std::cout << "Establish CS and CR connections: " << std::endl;
110 std::cout << "Failed to enable data uplink " << nsukit::status2_string(s) << ", currently uplinked: " << current << std::endl;
111 break;
112 }
115 s = _kit->wait_stream(mem, 1.);
116 }
117 current += block;
118 q->full.Push(mem);
119 if (current == total) {
120 break;
121 };
122 }
123 lock = new std::unique_lock<std::mutex>(*mu);
124 q->stopFlag = 1;
125 delete lock;
126}
127
128
137void write_file_thread(nsukit::BaseKit *_kit, Deque *q, nsuSize_t block, const std::string &path, std::mutex *mu) {
138 std::unique_lock<std::mutex> *lock;
139 nsuMemory_p mem;
140 std::ofstream outF;
141 outF.open(path, std::ofstream::binary);
142 int cnt = 0;
143 nsuSize_t speed_count = 0;
144 auto st = std::chrono::steady_clock::now();
145
146 while (true) {
147 lock = new std::unique_lock<std::mutex>(*mu);
148 if (q->stopFlag == 1) {
149 break;
150 }
151 delete lock;
152 mem = q->full.Pop();
153 outF.write((char *)_kit->get_buffer(mem, block), block);
154 q->empty.Push(mem);
155// std::this_thread::sleep_for(std::chrono::seconds(1));
156 speed_count += block;
157
158 if (cnt % 20 == 0) {
159 auto count = std::chrono::steady_clock::now() - st;
160 std::cout << std::flush << '\r' << "current write file speed: " << speed_count*1000./(count.count()) << "MB/s" << std::endl;
161 speed_count = 0;
162 st = std::chrono::steady_clock::now();
163 }
164 cnt++;
165 }
166 std::cout << std::endl;
167 outF.close();
168}
169
170
172 kit->write(0x50010, 1);
173 kit->write(0x50010, 0);
174 kit->write(0x51010, 1);
175 kit->write(0x51010, 0);
176 kit->write(0x52010, 1);
177 kit->write(0x52010, 0);
178 kit->write(0x53010, 1);
179 kit->write(0x53010, 0);
180 kit->write(0x0, 0);
181 kit->write(0x0, 1);
182 return 0;
183}
184
185
187 kit->write(0x00004, 0);
188 kit->write(0x00004, 1);
189 kit->write(0x00008, 0);
190 kit->write(0x00008, 1);
191 kit->write(0x0000C, 0);
192 kit->write(0x0000C, 1);
193 kit->write(0x00010, 0);
194 kit->write(0x00010, 1);
195 kit->write(0x2001C, 0);
196 kit->write(0x2001C, 1);
197 kit->write(0x2001C, 2);
198 kit->write(0x2001C, 3);
199 kit->write(0x20014, 0);
200 kit->write(0x20014, 1);
201 kit->write(0x20010, 0);
202 kit->write(0x20010, 1);
203 kit->write(0x20020, 0xF);
204 kit->write(0x20020, 0);
205 kit->write(0x00004, 0);
206 kit->write(0x00004, 1);
207 kit->write(0x00008, 0);
208 kit->write(0x00008, 1);
209 kit->write(0x0000C, 0);
210 kit->write(0x0000C, 1);
211 kit->write(0x00010, 0);
212 kit->write(0x00010, 1);
213 return 0;
214}
215
216
218 kit->write(0x30000, 0x0);
219 kit->write(0x31000, 0x0);
220 kit->write(0x32000, 0x0);
221 kit->write(0x33000, 0x0);
222 kit->write(0x30008, 0x0);
223 kit->write(0x30008, 0x1);
224 kit->write(0x31008, 0x0);
225 kit->write(0x31008, 0x1);
226 kit->write(0x32008, 0x0);
227 kit->write(0x32008, 0x1);
228 kit->write(0x33008, 0x0);
229 kit->write(0x33008, 0x1);
230 return 0;
231}
232
233
235 kit->write(0x24 , 0x1); // 通道0切换至aurora 1:数据来自采集设备 0:数据由板卡内部产生
236 kit->write(0x30030, 98304); // 通道0打包长度 内部产生测试数据打包长度
237 kit->write(0x3000C, 49024); // 通道0递增数上限 内部产生递增测试数据最大值,数据达到最大值之后归零递增
238 kit->write(0x30004, 100); // 通道0带宽设置 单位MB/s,产生实时数据带宽
239 kit->write(0x30010, 0x0); // 通道0常数使能 1:产生常数数据,与“递增数据使能”互斥,只能其中一个配置为1
240 kit->write(0x3002C, 0xAAAA0000); // 通道0通道标识号
241 kit->write(0x3003C, 0x10); // 通道0数据位宽 16bit位宽数据
242 kit->write(0x30000, 0x1); // 通道0递增数使能 1:产生递增数据
243 kit->write(0x28 , 0x1); // 通道1切换至aurora
244 kit->write(0x31030, 0x4000); // 通道1打包长度
245 kit->write(0x3100C, 0x1F80); // 通道1递增数上限
246 kit->write(0x31004, 0x190); // 通道1带宽设置
247 kit->write(0x31010, 0x0); // 通道1常数使能
248 kit->write(0x3102C, 0xAAAA1111); // 通道1通道标识号
249 kit->write(0x3103C, 0x10); // 通道1数据位宽
250 kit->write(0x31000, 0x1); // 通道1递增数使能
251 kit->write(0x2c , 0x1); // 通道2切换至aurora
252 kit->write(0x32030, 0x4000); // 通道2打包长度
253 kit->write(0x3200C, 0x1F80); // 通道2递增数上限
254 kit->write(0x32004, 0x190); // 通道2带宽设置
255 kit->write(0x32010, 0x0); // 通道2常数使能
256 kit->write(0x3202C, 0xAAAA2222); // 通道2通道标识号
257 kit->write(0x3203C, 0x10); // 通道2数据位宽
258 kit->write(0x32000, 0x1); // 通道2递增数使能
259 kit->write(0x30 , 0x1); // 通道3切换至aurora
260 kit->write(0x33030, 0x4000); // 通道3打包长度
261 kit->write(0x3300C, 0x1F80); // 通道3递增数上限
262 kit->write(0x33004, 0x190); // 通道3带宽设置
263 kit->write(0x33010, 0x0); // 通道3常数使能
264 kit->write(0x3302C, 0xAAAA3333); // 通道3通道标识号
265 kit->write(0x3303C, 0x10); // 通道3数据位宽
266 kit->write(0x33000, 0x1); // 通道3递增数使能
267 return 0;
268}
269
270
271int start_chnl(nsukit::BaseKit *kit, Deque *q, uint32_t stream_chnl, uint32_t ds_block, uint32_t total_len, std::string file_name, std::mutex *mu) {
272 for (int i=0; i<10; i++) {
273 nsuMemory_p mem = kit->alloc_buffer(ds_block);
274 q->empty.Push(mem);
275 }
276
277 // Start the upstream and storage threads.
278 std::thread up_trd(upload_thread, kit, stream_chnl, q, ds_block, total_len, mu);
279 std::thread write_trd(write_file_thread, kit, q, ds_block, file_name, mu);
280
281 std::cout << "Stream thread start successful!!!" << std::endl;
282
283 up_trd.join();
284 write_trd.join();
285 return 0;
286}
287
288
289int main(int argc, char *argv[]) {
290 unsigned int ds_block = 4*1024*1024;
291 Deque q0, q1, q2, q3;
292 std::mutex mu0, mu1, mu2, mu3;
293 SocType kit{};
294
295 if (argc != 2) {
296 std::cout << "Unsupported parameter passing method" << std::endl;
297 // DataUpload 104857600
298 std::cout << argv[0] << " {totalBytes}" << std::endl;
299 return 1;
300 }
301 nsuSize_t total_len = std::atoi(argv[1]);
302 if (total_len % ds_block != 0) {
303 std::cout << "The total length of upstream data total_len "
304 << total_len << " Bytes should be "
305 << ds_block << "Integer multiple of Bytes" << std::endl;
306 return 1;
307 }
308
309 nsuInitParam_t param;
310 param.cmd_board = 0;
311 param.stream_board = 0;
312#ifdef STREAM_WITH_TCP
313 auto ip = std::string(argv[1]);
314 // 192.168.1.161 => 6001
315 std::string port_str{};
316 port_str += ip[ip.length()-2];
317 port_str += "00";
318 port_str += ip[ip.length()-1];
319 int port = std::atoi(port_str.data());
320 param.stream_ip = ip;
321 param.stream_tcp_port = port;
322 param.stream_tcp_block = 4 * 1024 * 1024;
323#endif
324
325 auto res = kit.link_cmd(&param);
327 std::cout << "Establish CS and CR connections: " << nsukit::status2_string(res) << std::endl;
328 }
329
330 res = kit.link_stream(&param);
332 std::cout << "Establish a DS connection: " << nsukit::status2_string(res) << std::endl;
333 }
334
335 // config to start
336 aurora_reset(&kit);
337 ddr_reset(&kit);
338 source_reset(&kit);
339 source_select(&kit);
340
341 std::cout << "SocLink Successful!!! now alloc buffer" << std::endl;
342 for (int i=0; i<10; i++) {
343 nsuMemory_p mem = kit.alloc_buffer(ds_block);
344 q0.empty.Push(mem);
345 }
346
347 for (int i=0; i<10; i++) {
348 nsuMemory_p mem = kit.alloc_buffer(ds_block);
349 q1.empty.Push(mem);
350 }
351
352 for (int i=0; i<10; i++) {
353 nsuMemory_p mem = kit.alloc_buffer(ds_block);
354 q2.empty.Push(mem);
355 }
356
357 for (int i=0; i<10; i++) {
358 nsuMemory_p mem = kit.alloc_buffer(ds_block);
359 q3.empty.Push(mem);
360 }
361
362 // Start the upstream and storage threads.
363 std::thread up_trd_0(upload_thread, &kit, 0, &q0, ds_block, total_len, &mu0);
364 std::thread write_trd_0(write_file_thread, &kit, &q0, ds_block, "data_ch_0.dat", &mu0);
365 std::thread up_trd_1(upload_thread, &kit, 1, &q1, ds_block, total_len, &mu1);
366 std::thread write_trd_1(write_file_thread, &kit, &q1, ds_block, "data_ch_1.dat", &mu1);
367 std::thread up_trd_2(upload_thread, &kit, 2, &q2, ds_block, total_len, &mu2);
368 std::thread write_trd_2(write_file_thread, &kit, &q2, ds_block, "data_ch_2.dat", &mu2);
369 std::thread up_trd_3(upload_thread, &kit, 3, &q3, ds_block, total_len, &mu3);
370 std::thread write_trd_3(write_file_thread, &kit, &q3, ds_block, "data_ch_3.dat", &mu3);
371
372 std::cout << "Stream thread start successful!!!" << std::endl;
373
374 up_trd_0.join();
375 write_trd_0.join();
376 up_trd_1.join();
377 write_trd_1.join();
378 up_trd_2.join();
379 write_trd_2.join();
380 up_trd_3.join();
381 write_trd_3.join();
382
383 // config to stop
384 aurora_reset(&kit);
385 ddr_reset(&kit);
386 source_reset(&kit);
387
388 std::cout << "Data upload completed" << std::endl;
389
390 return 0;
391}
392
void Push(T *value)
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 nsuMemory_p alloc_buffer(nsuStreamLen_t length, nsuVoidBuf_p buf=nullptr)
Definition: base_kit.h:68
virtual nsukitStatus_t wait_stream(nsuMemory_p fd, float timeout=0.)
Definition: base_kit.h:103
virtual nsukitStatus_t write(nsuRegAddr_t addr, nsuRegValue_t value)
Definition: base_kit.h:26
void upload_thread(nsukit::BaseKit *_kit, int stream_chnl, Deque *q, nsuSize_t block, nsuSize_t total, std::mutex *mu)
int aurora_reset(nsukit::BaseKit *kit)
void write_file_thread(nsukit::BaseKit *_kit, Deque *q, nsuSize_t block, const std::string &path, std::mutex *mu)
int source_select(nsukit::BaseKit *kit)
int ddr_reset(nsukit::BaseKit *kit)
int start_chnl(nsukit::BaseKit *kit, Deque *q, uint32_t stream_chnl, uint32_t ds_block, uint32_t total_len, std::string file_name, std::mutex *mu)
int source_reset(nsukit::BaseKit *kit)
ThreadSafeQueue< void > memQueue
std::string NSU_DLLEXPORT status2_string(nsukitStatus_t status)
Definition: config.cpp:15
int stopFlag
memQueue empty
memQueue full
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