1 /* pipe_r.c */
2
3 /*
4 * Copyright (c) 1997-2010, 2013-2014 Wind River Systems, Inc.
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include "receiver.h"
10 #include "master.h"
11
12 /*
13 * Function prototypes.
14 */
15 int pipeget(struct k_pipe *pipe, enum pipe_options option,
16 int size, int count, unsigned int *time);
17
18 /*
19 * Function declarations.
20 */
21
22 /* pipes transfer speed test */
23
24 /**
25 * @brief Receive task
26 */
piperecvtask(void)27 void piperecvtask(void)
28 {
29 int getsize;
30 unsigned int gettime;
31 int getcount;
32 int pipe;
33 int prio;
34 struct getinfo getinfo;
35
36 /* matching (ALL_N) */
37
38 for (getsize = 8; getsize <= MESSAGE_SIZE_PIPE; getsize <<= 1) {
39 for (pipe = 0; pipe < 3; pipe++) {
40 getcount = NR_OF_PIPE_RUNS;
41 pipeget(test_pipes[pipe], _ALL_N, getsize,
42 getcount, &gettime);
43 getinfo.time = gettime;
44 getinfo.size = getsize;
45 getinfo.count = getcount;
46 /* acknowledge to master */
47 k_msgq_put(&CH_COMM, &getinfo, K_FOREVER);
48 }
49 }
50
51 for (prio = 0; prio < 2; prio++) {
52 /* non-matching (1_TO_N) */
53 for (getsize = (MESSAGE_SIZE_PIPE); getsize >= 8; getsize >>= 1) {
54 getcount = MESSAGE_SIZE_PIPE / getsize;
55 for (pipe = 0; pipe < 3; pipe++) {
56 /* size*count == MESSAGE_SIZE_PIPE */
57 pipeget(test_pipes[pipe], _1_TO_N,
58 getsize, getcount, &gettime);
59 getinfo.time = gettime;
60 getinfo.size = getsize;
61 getinfo.count = getcount;
62 /* acknowledge to master */
63 k_msgq_put(&CH_COMM, &getinfo, K_FOREVER);
64 }
65 }
66 }
67
68 }
69
70
71 /**
72 * @brief Read a data portion from the pipe and measure time
73 *
74 * @return 0 on success, 1 on error
75 *
76 * @param pipe Pipe to read data from.
77 * @param option _ALL_TO_N or _1_TO_N.
78 * @param size Data chunk size.
79 * @param count Number of data chunks.
80 * @param time Total write time.
81 */
pipeget(struct k_pipe * pipe,enum pipe_options option,int size,int count,unsigned int * time)82 int pipeget(struct k_pipe *pipe, enum pipe_options option, int size, int count,
83 unsigned int *time)
84 {
85 int i;
86 unsigned int t;
87 timing_t start;
88 timing_t end;
89 size_t sizexferd_total = 0;
90 size_t size2xfer_total = size * count;
91
92 /* sync with the sender */
93 k_sem_take(&SEM0, K_FOREVER);
94 start = timing_timestamp_get();
95 for (i = 0; option == _1_TO_N || (i < count); i++) {
96 size_t sizexferd = 0;
97 size_t size2xfer = MIN(size, size2xfer_total - sizexferd_total);
98 int ret;
99
100 ret = k_pipe_get(pipe, data_recv, size2xfer,
101 &sizexferd, option, K_FOREVER);
102
103 if (ret != 0) {
104 return 1;
105 }
106
107 if (option == _ALL_N && sizexferd != size2xfer) {
108 return 1;
109 }
110
111 sizexferd_total += sizexferd;
112 if (size2xfer_total == sizexferd_total) {
113 break;
114 }
115
116 if (size2xfer_total < sizexferd_total) {
117 return 1;
118 }
119 }
120
121 end = timing_timestamp_get();
122 t = (unsigned int) timing_cycles_get(&start, &end);
123 *time = SYS_CLOCK_HW_CYCLES_TO_NS_AVG(t, count);
124
125 return 0;
126 }
127