Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
trx_test
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
FANG WANG
trx_test
Commits
ab5d537f
Commit
ab5d537f
authored
Apr 25, 2023
by
111
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add tx thread
parent
a326f804
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
537 additions
and
21 deletions
+537
-21
readme.txt
readme.txt
+1
-1
system.c
system.c
+375
-0
system.h
system.h
+73
-0
trx_test.c
trx_test.c
+88
-20
No files found.
readme.txt
View file @
ab5d537f
BUILD:
x86
sudo gcc -o trx
trx_test.c oxgrf_lib.c -march=native -loxgrf_ss -g
sudo gcc -o trx
system.c trx_test.c oxgrf_lib.c -march=native -loxgrf_ss -g -lpthread
arm
sudo gcc -o trx trx_test.c yunsdr_lib.c -lyunsdr_ss -g
...
...
system.c
0 → 100644
View file @
ab5d537f
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/* This module provides a separate process to run system().
* The communication between this process and the main processing
* is done through unix pipes.
*
* Motivation: the UE sets its IP address using system() and
* that disrupts realtime processing in some cases. Having a
* separate process solves this problem.
*/
#define _GNU_SOURCE
#include "system.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include "assertions.h"
#define MAX_COMMAND 4096
static
int
command_pipe_read
;
static
int
command_pipe_write
;
static
int
result_pipe_read
;
static
int
result_pipe_write
;
static
pthread_mutex_t
lock
=
PTHREAD_MUTEX_INITIALIZER
;
static
int
module_initialized
=
0
;
/********************************************************************/
/* util functions */
/********************************************************************/
static
void
lock_system
(
void
)
{
if
(
pthread_mutex_lock
(
&
lock
)
!=
0
)
{
printf
(
"pthread_mutex_lock fails
\n
"
);
abort
();
}
}
static
void
unlock_system
(
void
)
{
if
(
pthread_mutex_unlock
(
&
lock
)
!=
0
)
{
printf
(
"pthread_mutex_unlock fails
\n
"
);
abort
();
}
}
static
void
write_pipe
(
int
p
,
char
*
b
,
int
size
)
{
while
(
size
)
{
int
ret
=
write
(
p
,
b
,
size
);
if
(
ret
<=
0
)
exit
(
0
);
b
+=
ret
;
size
-=
ret
;
}
}
static
void
read_pipe
(
int
p
,
char
*
b
,
int
size
)
{
while
(
size
)
{
int
ret
=
read
(
p
,
b
,
size
);
if
(
ret
<=
0
)
exit
(
0
);
b
+=
ret
;
size
-=
ret
;
}
}
int
checkIfFedoraDistribution
(
void
)
{
return
!
system
(
"grep -iq 'ID_LIKE.*fedora' /etc/os-release "
);
}
int
checkIfGenericKernelOnFedora
(
void
)
{
return
system
(
"uname -a | grep -q rt"
);
}
int
checkIfInsideContainer
(
void
)
{
return
!
system
(
"egrep -q 'libpod|podman|kubepods' /proc/self/cgroup"
);
}
/********************************************************************/
/* background process */
/********************************************************************/
/* This function is run by background process. It waits for a command,
* runs it, and reports status back. It exits (in normal situations)
* when the main process exits, because then a "read" on the pipe
* will return 0, in which case "read_pipe" exits.
*/
static
void
background_system_process
(
void
)
{
int
len
;
int
ret
;
char
command
[
MAX_COMMAND
+
1
];
while
(
1
)
{
read_pipe
(
command_pipe_read
,
(
char
*
)
&
len
,
sizeof
(
int
));
read_pipe
(
command_pipe_read
,
command
,
len
);
ret
=
system
(
command
);
write_pipe
(
result_pipe_write
,
(
char
*
)
&
ret
,
sizeof
(
int
));
}
}
/********************************************************************/
/* background_system() */
/* return -1 on error, 0 on success */
/********************************************************************/
int
background_system
(
char
*
command
)
{
int
res
;
int
len
;
if
(
module_initialized
==
0
)
{
printf
(
"FATAL: calling 'background_system' but 'start_background_system' was not called
\n
"
);
abort
();
}
len
=
strlen
(
command
)
+
1
;
if
(
len
>
MAX_COMMAND
)
{
printf
(
"FATAL: command too long. Increase MAX_COMMAND (%d).
\n
"
,
MAX_COMMAND
);
printf
(
"command was: '%s'
\n
"
,
command
);
abort
();
}
/* only one command can run at a time, so let's lock/unlock */
lock_system
();
write_pipe
(
command_pipe_write
,
(
char
*
)
&
len
,
sizeof
(
int
));
write_pipe
(
command_pipe_write
,
command
,
len
);
read_pipe
(
result_pipe_read
,
(
char
*
)
&
res
,
sizeof
(
int
));
unlock_system
();
if
(
res
==
-
1
||
!
WIFEXITED
(
res
)
||
WEXITSTATUS
(
res
)
!=
0
)
return
-
1
;
return
0
;
}
/********************************************************************/
/* start_background_system() */
/* initializes the "background system" module */
/* to be called very early by the main processing */
/********************************************************************/
void
start_background_system
(
void
)
{
int
p
[
2
];
pid_t
son
;
if
(
module_initialized
==
1
)
return
;
module_initialized
=
1
;
if
(
pipe
(
p
)
==
-
1
)
{
perror
(
"pipe"
);
exit
(
1
);
}
command_pipe_read
=
p
[
0
];
command_pipe_write
=
p
[
1
];
if
(
pipe
(
p
)
==
-
1
)
{
perror
(
"pipe"
);
exit
(
1
);
}
result_pipe_read
=
p
[
0
];
result_pipe_write
=
p
[
1
];
son
=
fork
();
if
(
son
==
-
1
)
{
perror
(
"fork"
);
exit
(
1
);
}
if
(
son
)
{
close
(
result_pipe_write
);
close
(
command_pipe_read
);
return
;
}
close
(
result_pipe_read
);
close
(
command_pipe_write
);
background_system_process
();
}
int
rt_sleep_ns
(
uint64_t
x
)
{
struct
timespec
myTime
;
clock_gettime
(
CLOCK_MONOTONIC
,
&
myTime
);
myTime
.
tv_sec
+=
x
/
1000000000ULL
;
myTime
.
tv_nsec
=
x
%
1000000000ULL
;
if
(
myTime
.
tv_nsec
>=
1000000000
)
{
myTime
.
tv_nsec
-=
1000000000
;
myTime
.
tv_sec
++
;
}
return
clock_nanosleep
(
CLOCK_MONOTONIC
,
TIMER_ABSTIME
,
&
myTime
,
NULL
);
}
void
threadCreate
(
pthread_t
*
t
,
void
*
(
*
func
)(
void
*
),
void
*
param
,
char
*
name
,
int
affinity
,
int
priority
){
pthread_attr_t
attr
;
int
ret
;
int
settingPriority
=
1
;
ret
=
pthread_attr_init
(
&
attr
);
AssertFatal
(
ret
==
0
,
"ret: %d, errno: %d
\n
"
,
ret
,
errno
);
if
(
checkIfFedoraDistribution
())
if
(
checkIfGenericKernelOnFedora
())
if
(
checkIfInsideContainer
())
settingPriority
=
0
;
if
(
settingPriority
)
{
ret
=
pthread_attr_setinheritsched
(
&
attr
,
PTHREAD_EXPLICIT_SCHED
);
AssertFatal
(
ret
==
0
,
"ret: %d, errno: %d
\n
"
,
ret
,
errno
);
ret
=
pthread_attr_setschedpolicy
(
&
attr
,
SCHED_OAI
);
AssertFatal
(
ret
==
0
,
"ret: %d, errno: %d
\n
"
,
ret
,
errno
);
if
(
priority
<
sched_get_priority_min
(
SCHED_OAI
)
||
priority
>
sched_get_priority_max
(
SCHED_OAI
))
{
printf
(
"Prio not possible: %d, min is %d, max: %d, forced in the range
\n
"
,
priority
,
sched_get_priority_min
(
SCHED_OAI
),
sched_get_priority_max
(
SCHED_OAI
));
if
(
priority
<
sched_get_priority_min
(
SCHED_OAI
))
priority
=
sched_get_priority_min
(
SCHED_OAI
);
if
(
priority
>
sched_get_priority_max
(
SCHED_OAI
))
priority
=
sched_get_priority_max
(
SCHED_OAI
);
}
AssertFatal
(
priority
<=
sched_get_priority_max
(
SCHED_OAI
),
""
);
struct
sched_param
sparam
=
{
0
};
sparam
.
sched_priority
=
priority
;
ret
=
pthread_attr_setschedparam
(
&
attr
,
&
sparam
);
AssertFatal
(
ret
==
0
,
"ret: %d, errno: %d
\n
"
,
ret
,
errno
);
}
ret
=
pthread_create
(
t
,
&
attr
,
func
,
param
);
AssertFatal
(
ret
==
0
,
"ret: %d, errno: %d
\n
"
,
ret
,
errno
);
pthread_setname_np
(
*
t
,
name
);
if
(
affinity
!=
-
1
)
{
cpu_set_t
cpuset
;
CPU_ZERO
(
&
cpuset
);
CPU_SET
(
affinity
,
&
cpuset
);
AssertFatal
(
pthread_setaffinity_np
(
*
t
,
sizeof
(
cpu_set_t
),
&
cpuset
)
==
0
,
"Error setting processor affinity"
);
}
pthread_attr_destroy
(
&
attr
);
}
#if 0
// Legacy, pthread_create + thread_top_init() should be replaced by threadCreate
// threadCreate encapsulates the posix pthread api
void thread_top_init(char *thread_name,
int affinity,
uint64_t runtime,
uint64_t deadline,
uint64_t period) {
int policy, s, j;
struct sched_param sparam;
char cpu_affinity[1024];
cpu_set_t cpuset;
int settingPriority = 1;
/* Set affinity mask to include CPUs 2 to MAX_CPUS */
/* CPU 0 is reserved for UHD threads */
/* CPU 1 is reserved for all RX_TX threads */
/* Enable CPU Affinity only if number of CPUs > 2 */
CPU_ZERO(&cpuset);
/* Check the actual affinity mask assigned to the thread */
s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0)
{
perror( "pthread_getaffinity_np");
exit_fun("Error getting processor affinity ");
}
memset(cpu_affinity,0,sizeof(cpu_affinity));
for (j = 0; j < 1024; j++)
{
if (CPU_ISSET(j, &cpuset))
{
char temp[1024];
sprintf (temp, " CPU_%d", j);
strcat(cpu_affinity, temp);
}
}
if (checkIfFedoraDistribution())
if (checkIfGenericKernelOnFedora())
if (checkIfInsideContainer())
settingPriority = 0;
if (settingPriority) {
memset(&sparam, 0, sizeof(sparam));
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
policy = SCHED_FIFO;
s = pthread_setschedparam(pthread_self(), policy, &sparam);
if (s != 0) {
perror("pthread_setschedparam : ");
exit_fun("Error setting thread priority");
}
s = pthread_getschedparam(pthread_self(), &policy, &sparam);
if (s != 0) {
perror("pthread_getschedparam : ");
exit_fun("Error getting thread priority");
}
pthread_setname_np(pthread_self(), thread_name);
LOG_I(HW, "[SCHED][eNB] %s started on CPU %d, sched_policy = %s , priority = %d, CPU Affinity=%s \n",thread_name,sched_getcpu(),
(policy == SCHED_FIFO) ? "SCHED_FIFO" :
(policy == SCHED_RR) ? "SCHED_RR" :
(policy == SCHED_OTHER) ? "SCHED_OTHER" :
"???",
sparam.sched_priority, cpu_affinity );
}
}
// Block CPU C-states deep sleep
void set_latency_target(void) {
int ret;
static int latency_target_fd=-1;
uint32_t latency_target_value=2; // in microseconds
if (latency_target_fd == -1) {
if ( (latency_target_fd = open("/dev/cpu_dma_latency", O_RDWR)) != -1 ) {
ret = write(latency_target_fd, &latency_target_value, sizeof(latency_target_value));
if (ret == 0) {
printf("# error setting cpu_dma_latency to %u!: %s\n", latency_target_value, strerror(errno));
close(latency_target_fd);
latency_target_fd=-1;
return;
}
}
}
if (latency_target_fd != -1)
LOG_I(HW,"# /dev/cpu_dma_latency set to %u us\n", latency_target_value);
else
LOG_E(HW,"Can't set /dev/cpu_dma_latency to %u us\n", latency_target_value);
// Set CPU frequency to it's maximum
if ( 0 != system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done"))
LOG_E(HW,"Can't set cpu frequency\n");
mlockall(MCL_CURRENT | MCL_FUTURE);
}
#endif
\ No newline at end of file
system.h
0 → 100644
View file @
ab5d537f
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _SYSTEM_H_OAI_
#define _SYSTEM_H_OAI_
#include <stdint.h>
#include <pthread.h>
#ifdef __cplusplus
extern
"C"
{
#endif
/****************************************************
* send a command to the background process
* return -1 on error, 0 on success
****************************************************/
int
background_system
(
char
*
command
);
/****************************************************
* initialize the background process
* to be called very early
****************************************************/
void
start_background_system
(
void
);
void
set_latency_target
(
void
);
void
threadCreate
(
pthread_t
*
t
,
void
*
(
*
func
)(
void
*
),
void
*
param
,
char
*
name
,
int
affinity
,
int
priority
);
#define SCHED_OAI SCHED_RR
#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_OAI)
#define OAI_PRIORITY_RT ((sched_get_priority_min(SCHED_OAI)+sched_get_priority_max(SCHED_OAI))/2)
#define OAI_PRIORITY_RT_MAX sched_get_priority_max(SCHED_OAI)-2
void
thread_top_init
(
char
*
thread_name
,
int
affinity
,
uint64_t
runtime
,
uint64_t
deadline
,
uint64_t
period
);
/****************************************************
* Functions to check system at runtime.
****************************************************/
int
checkIfFedoraDistribution
(
void
);
int
checkIfGenericKernelOnFedora
(
void
);
int
checkIfInsideContainer
(
void
);
int
rt_sleep_ns
(
uint64_t
x
);
#ifdef __cplusplus
}
#endif
#endif
/* _SYSTEM_H_OAI_ */
trx_test.c
View file @
ab5d537f
...
...
@@ -3,12 +3,17 @@
#include <assert.h>
#include "trx_test.h"
#include "system.h"
#include <semaphore.h>
#include <pthread.h>
#define NB_ANTENNAS_RX 4
#define NB_ANTENNAS_TX 1
#define NB_ANTENNAS_RX 1
#define NB_ANTENNAS_TX 4
#define SAMPLE_RATE (122880000)
//#define TX_RX_ONE_THREAD
int
txdata_size
=
61440
*
4
;
int
rxdata_size
=
61440
*
4
;
int
absolute_slot
=
0
;
...
...
@@ -40,9 +45,61 @@ struct timespec nr_get_timespec_diff(
return
result
;
}
openair0_timestamp
rx_timestamp
,
writeTimestamp
;
int32_t
*
rxp
[
NB_ANTENNAS_RX
];
int32_t
*
txp
[
NB_ANTENNAS_TX
];
int
readBlockSize
,
writeBlockSize
;
int
tx_cnt
=
0
;
int
rx_cnt
=
0
;
sem_t
ric_send_sem
;
double
clock_gettime_cur_tx
;
static
void
*
tx_thread
(
void
*
param
)
{
openair0_device
*
rfdevice
=
(
openair0_device
*
)
param
;
double
clock_gettime_cur
;
struct
timespec
time_start
;
struct
timespec
time_stop
;
while
(
1
)
{
sem_wait
(
&
ric_send_sem
);
//printf("00000000 tx cnt %d rx cnt %d\n", tx_cnt, rx_cnt);
// use previous timing_advance value to compute writeTimestamp
//writeTimestamp = timestamp+samples_per_subframe/20*5;// sent after 5 slot.
writeTimestamp
=
rx_timestamp
+
samples_per_subframe
/
4
;
// sent after 5 slot.
// but use current UE->timing_advance value to compute writeBlockSize
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE
,
VCD_FUNCTION_IN
);
clock_gettime
(
CLOCK_REALTIME
,
&
time_start
);
#if 1
rfdevice
->
trx_write_func
(
rfdevice
,
writeTimestamp
,
(
void
**
)
txp
,
writeBlockSize
,
1
,
1
);
#endif
clock_gettime
(
CLOCK_REALTIME
,
&
time_stop
);
clock_gettime_cur_tx
=
NR_TIMESPEC_TO_DOUBLE_US
(
nr_get_timespec_diff
(
&
time_start
,
&
time_stop
));
tx_cnt
++
;
//printf("11111111 tx cnt %d rx cnt %d\n", tx_cnt, rx_cnt);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE
,
VCD_FUNCTION_OUT
);
}
return
NULL
;
}
int
main
(
int
argc
,
char
**
argv
)
{
pthread_t
tx_threads
;
// test_t *t1=malloc(sizeof(test_t));
test_t
t2
[
4
];
...
...
@@ -55,7 +112,7 @@ int main( int argc, char **argv ) {
sched_setscheduler
(
getpid
(),
SCHED_RR
,
&
rr_param
);
cpu_set_t
mask
;
CPU_ZERO
(
&
mask
);
CPU_SET
(
5
,
&
mask
);
CPU_SET
(
20
,
&
mask
);
int
rc
=
sched_setaffinity
(
getpid
(),
sizeof
(
mask
),
&
mask
);
assert
(
rc
>=
0
);
...
...
@@ -118,16 +175,19 @@ int main( int argc, char **argv ) {
openair0_cfg
[
card
].
sdr_addrs
=
"dev=pciex:0,auxdac1=300"
;
openair0_timestamp
timestamp
,
timestampold
,
writeTimestamp
;
int32_t
*
rxp
[
NB_ANTENNAS_RX
];
int32_t
*
txp
[
NB_ANTENNAS_TX
];
openair0_timestamp
timestampold
;
int
start_rx_stream
=
1
;
double
clock_gettime_cur
;
struct
timespec
time_start
;
struct
timespec
time_stop
;
struct
timespec
time_start
,
time_start1
;
struct
timespec
time_stop
,
time_stop1
;
int
res
=
sem_init
(
&
ric_send_sem
,
0
,
0
);
if
(
res
!=
0
)
{
perror
(
"Semaphore initialization failed"
);
}
...
...
@@ -137,7 +197,7 @@ int main( int argc, char **argv ) {
for
(
int
i
=
0
;
i
<
NB_ANTENNAS_TX
;
i
++
)
{
txp
[
i
]
=
(
int32_t
*
)
malloc16_clear
(
txdata_size
);
}
int
readBlockSize
,
writeBlockSize
;
readBlockSize
=
samples_per_subframe
/
2
;
writeBlockSize
=
readBlockSize
;
...
...
@@ -145,17 +205,18 @@ int main( int argc, char **argv ) {
device_init
(
&
(
rfdevice
),
&
openair0_cfg
[
0
]);
threadCreate
(
&
tx_threads
,
tx_thread
,
&
rfdevice
,
"tx_thread"
,
21
,
sched_get_priority_max
(
SCHED_RR
)
-
2
);
rfdevice
.
trx_start_func
(
&
rfdevice
);
//first time is very long, don't know why.
clock_gettime
(
CLOCK_REALTIME
,
&
time_start
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ
,
VCD_FUNCTION_IN
);
rfdevice
.
trx_read_func
(
&
rfdevice
,
&
timestamp
,
&
rx_
timestamp
,
(
void
**
)
rxp
,
readBlockSize
,
1
);
timestampold
=
timestamp
;
timestampold
=
rx_
timestamp
;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ
,
VCD_FUNCTION_OUT
);
clock_gettime
(
CLOCK_REALTIME
,
&
time_stop
);
clock_gettime_cur
=
NR_TIMESPEC_TO_DOUBLE_US
(
nr_get_timespec_diff
(
&
time_start
,
&
time_stop
));
//us
...
...
@@ -167,39 +228,46 @@ int main( int argc, char **argv ) {
clock_gettime
(
CLOCK_REALTIME
,
&
time_stop
);
clock_gettime_cur
=
NR_TIMESPEC_TO_DOUBLE_US
(
nr_get_timespec_diff
(
&
time_start
,
&
time_stop
));
//us
if
(
clock_gettime_cur
>
510
)
printf
(
"slot_num %d, timestamp %ld, writeTimestamp %ld,time = %.2f sec, delay_time=
%.2lf
msec. readBlockSize %d. real read %ld.
\n
"
,
absolute_slot
,
timestamp
,
writeTimestamp
,
((
float
)
absolute_slot
)
/
2
/
1000
,
clock_gettime_cur
/
1000
,
readBlockSize
,(
timestamp
-
timestampold
));
if
(
(
clock_gettime_cur
>
300
)
||
(
clock_gettime_cur_tx
>
510
))
printf
(
"slot_num %d, timestamp %ld, writeTimestamp %ld,time = %.2f sec, delay_time=
(%.2lf, %d) (tx %.2lf, %d)
msec. readBlockSize %d. real read %ld.
\n
"
,
absolute_slot
,
rx_timestamp
,
writeTimestamp
,
((
float
)
absolute_slot
)
/
2
/
1000
,
clock_gettime_cur
/
1000
,
rx_cnt
,
clock_gettime_cur_tx
/
1000
,
tx_cnt
,
readBlockSize
,(
rx_
timestamp
-
timestampold
));
clock_gettime
(
CLOCK_REALTIME
,
&
time_start
);
timestampold
=
timestamp
;
timestampold
=
rx_
timestamp
;
#if 1
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ
,
VCD_FUNCTION_IN
);
rfdevice
.
trx_read_func
(
&
rfdevice
,
&
timestamp
,
&
rx_
timestamp
,
(
void
**
)
rxp
,
readBlockSize
,
1
);
rx_cnt
++
;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ
,
VCD_FUNCTION_OUT
);
#endif
#if
1
#if
def TX_RX_ONE_THREAD
// use previous timing_advance value to compute writeTimestamp
//writeTimestamp = timestamp+samples_per_subframe/20*5;// sent after 5 slot.
writeTimestamp
+=
timestamp
+
samples_per_subframe
/
2
;
// sent after 5 slot.
writeTimestamp
=
rx_timestamp
+
samples_per_subframe
/
4
;
// sent after 5 slot.
// but use current UE->timing_advance value to compute writeBlockSize
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE
,
VCD_FUNCTION_IN
);
clock_gettime
(
CLOCK_REALTIME
,
&
time_start1
);
rfdevice
.
trx_write_func
(
&
rfdevice
,
writeTimestamp
,
(
void
**
)
txp
,
writeBlockSize
,
1
,
1
);
clock_gettime
(
CLOCK_REALTIME
,
&
time_stop1
);
clock_gettime_cur_tx
=
NR_TIMESPEC_TO_DOUBLE_US
(
nr_get_timespec_diff
(
&
time_start1
,
&
time_stop1
));
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE
,
VCD_FUNCTION_OUT
);
#endif
#else
sem_post
(
&
ric_send_sem
);
#endif
}
// while !oai_exit
return
0
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment