Commit cbaa5449 authored by 黄灏's avatar 黄灏

Dpdkrf

parent d610c9a0
...@@ -523,6 +523,14 @@ add_library(oai_oxgrfdevif MODULE ${HWLIB_OXGRF_SOURCE} ) ...@@ -523,6 +523,14 @@ add_library(oai_oxgrfdevif MODULE ${HWLIB_OXGRF_SOURCE} )
target_link_libraries(oai_oxgrfdevif oxgrf_ss) target_link_libraries(oai_oxgrfdevif oxgrf_ss)
include_directories("${OPENAIR_DIR}/radio/DPDKRF/")
set(HWLIB_DPDKRF_SOURCE
${OPENAIR_DIR}/radio/DPDKRF/dpdkrf_oai.c
)
add_library(oai_dpdkrfdevif MODULE ${HWLIB_DPDKRF_SOURCE} )
target_link_libraries(oai_dpdkrfdevif dpdkrf)
include_directories("${OPENAIR_DIR}/radio/ETHERNET/USERSPACE/LIB/") include_directories("${OPENAIR_DIR}/radio/ETHERNET/USERSPACE/LIB/")
set(TPLIB_ETHERNET_SOURCE set(TPLIB_ETHERNET_SOURCE
${OPENAIR_DIR}/radio/ETHERNET/USERSPACE/LIB/ethernet_lib.c ${OPENAIR_DIR}/radio/ETHERNET/USERSPACE/LIB/ethernet_lib.c
......
...@@ -280,7 +280,7 @@ function main() { ...@@ -280,7 +280,7 @@ function main() {
-w | --hardware) -w | --hardware)
# Use OAI_USRP as the key word USRP is used inside UHD driver # Use OAI_USRP as the key word USRP is used inside UHD driver
case "$2" in case "$2" in
"USRP" | "BLADERF" | "LMSSDR" | "IRIS" | "SIMU" | "AW2SORI"| "OXGRF") "USRP" | "BLADERF" | "LMSSDR" | "IRIS" | "SIMU" | "AW2SORI"| "OXGRF" | "DPDKRF")
HW="OAI_"$2 HW="OAI_"$2
;; ;;
"None") "None")
...@@ -587,6 +587,7 @@ function main() { ...@@ -587,6 +587,7 @@ function main() {
ln -sf liboai_bladerfdevif.so liboai_device.so ln -sf liboai_bladerfdevif.so liboai_device.so
echo_info "liboai_device.so is linked to BLADERF device library" echo_info "liboai_device.so is linked to BLADERF device library"
elif [ "$HW" == "OAI_OXGRF" ] ; then elif [ "$HW" == "OAI_OXGRF" ] ; then
if [ ! -f "/usr/local/include/oxgrf_api_ss.h" ] ; then if [ ! -f "/usr/local/include/oxgrf_api_ss.h" ] ; then
sudo cp $THIS_SCRIPT_PATH/../radio/OXGRF/USERSPACE/LIB/oxgrf_api_ss.h /usr/local/include/oxgrf_api_ss.h sudo cp $THIS_SCRIPT_PATH/../radio/OXGRF/USERSPACE/LIB/oxgrf_api_ss.h /usr/local/include/oxgrf_api_ss.h
...@@ -598,6 +599,20 @@ function main() { ...@@ -598,6 +599,20 @@ function main() {
ln -sf liboai_oxgrfdevif.so liboai_device.so ln -sf liboai_oxgrfdevif.so liboai_device.so
echo_info "liboai_device.so is linked to OXGRF device library" echo_info "liboai_device.so is linked to OXGRF device library"
elif [ "$HW" == "OAI_DPDKRF" ] ; then
if [ ! -f "/usr/local/include/dpdkrf_lib.h" ] ; then
sudo cp $THIS_SCRIPT_PATH/../radio/DPDKRF/dpdkrf_lib.h /usr/local/include/dpdkrf_lib.h
sudo cp $THIS_SCRIPT_PATH/../radio/DPDKRF/libdpdkrf.so /usr/local/lib/libdpdkrf.so
sudo chmod +x /usr/local/lib/libdpdkrf.so
sudo ldconfig /usr/local/lib
fi
compilations $BUILD_DIR oai_dpdkrfdevif.txt oai_dpdkrfdevif
ln -sf liboai_dpdkrfdevif.so liboai_device.so
echo_info "liboai_device.so is linked to DPDKRF device library"
elif [ "$HW" == "OAI_LMSSDR" ] ; then elif [ "$HW" == "OAI_LMSSDR" ] ; then
# if [ -f "/usr/include/libbladeRF.h" ] ; then # if [ -f "/usr/include/libbladeRF.h" ] ; then
compilations $BUILD_DIR oai_lmssdrdevif.txt oai_lmssdrdevif compilations $BUILD_DIR oai_lmssdrdevif.txt oai_lmssdrdevif
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#include "executables/softmodem-common.h" #include "executables/softmodem-common.h"
const char *const devtype_names[MAX_RF_DEV_TYPE] = const char *const devtype_names[MAX_RF_DEV_TYPE] =
{"", "USRP B200", "USRP X300", "USRP N300", "USRP X400", "BLADERF", "OXGRF_DEV", "LMSSDR", "IRIS", "No HW", "UEDv2", "RFSIMULATOR"}; {"", "USRP B200", "USRP X300", "USRP N300", "USRP X400", "BLADERF", "OXGRF_DEV", "LMSSDR", "IRIS", "No HW", "UEDv2", "RFSIMULATOR","DPDKRF"};
const char *get_devname(int devtype) { const char *get_devname(int devtype) {
if (devtype < MAX_RF_DEV_TYPE && devtype !=MIN_RF_DEV_TYPE ) if (devtype < MAX_RF_DEV_TYPE && devtype !=MIN_RF_DEV_TYPE )
......
...@@ -95,6 +95,7 @@ typedef enum { ...@@ -95,6 +95,7 @@ typedef enum {
BLADERF_DEV, BLADERF_DEV,
/*!\brief device is OXGRF pcie*/ /*!\brief device is OXGRF pcie*/
OXGRF_DEV, OXGRF_DEV,
DPDKRF_DEV,
/*!\brief device is LMSSDR (SoDeRa)*/ /*!\brief device is LMSSDR (SoDeRa)*/
LMSSDR_DEV, LMSSDR_DEV,
/*!\brief device is Iris */ /*!\brief device is Iris */
......
#ifndef DPDKRF_H
#define DPDKRF_H
#include <sys/socket.h>
#include <unistd.h>
#define SAMPLE_PER_PACKAGE 960
#define CTRL_CMD_ID_CFG 0x1111
typedef struct
{
uint32_t header; // 0x12345678
uint16_t cmdType; // 0x1111
uint16_t enable; // 1-enable whole msg, 0-disable.
uint8_t rfState; // 0-rf disable; 1-enable; other value will disable this para.
uint8_t digLoopMode; // 0-normal work; 1-digital loop back mode. other value will disable this para.
uint8_t pad[6];
uint8_t rxGain[4]; // valid range is [0~30],other value will disable this para.
uint8_t txGain[4]; // valid range is [0~30],other value will disable this para.
uint64_t rxFreq; // unit is Hz; <1000 will disable this para.
uint64_t txFreq; // unit is Hz; <1000 will disable this para.
uint32_t crc;
uint32_t tail; // 0xA5A5A5A5
} STRUCT_CTRL_CMD_CFG_REQ;
typedef struct
{
uint32_t header; // 0x87654321
uint16_t cmdType; // 0x1111
uint16_t enable; // 1-enable whole msg, 0-disable.
uint8_t rfState; // 0-rf disable; 1-enable; other value will disable this para.
uint8_t digLoopMode; // 0-normal work; 1-digital loop back mode. other value will disable this para.
uint8_t pad[6];
uint8_t rxGain[4]; // valid range is [0~30],other value will disable this para.
uint8_t txGain[4]; // valid range is [0~30],other value will disable this para.
uint64_t rxFreq; // unit is Hz; <1000 will disable this para.
uint64_t txFreq; // unit is Hz; <1000 will disable this para.
uint32_t crc;
uint32_t tail; // 0x5A5A5A5A
} STRUCT_CTRL_CMD_CFG_ACK;
void Dpdk_device_init(int lcore_id, int antNum, int startDelay, int logEnable);
/**
* receive 1 package data from port. the package may DATA or CTRL frame.
* this function is blocked until receive 1 package.
* @param sockId
* sock ID, can only be 0 or 1.
* @param buf
* 2 level buffer pointer. buf[0] will store antenna 0 data, and buf[1] will store antenna 1 data.
* these 2 buffer should be malloc before call this function.
* @param timestamp
* a pointer to store the timestamp.
* @return
* - the received data sample num.
*/
int dpdkrf_recvDataPack(int sockfd, uint8_t **buf, int *timestamp);
/**
* send 1 package data. the package may DATA or CTRL frame.
* for data frame, 1 package hold 2 antenna data, each antenna has half.
* @param sockId
* sock ID, can only be 0 or 1.
* @param buf
* 2 level buffer pointer. buf[0] store antenna 0 data, and buf[1] store antenna 1 data.
* @param nsamps
* package sample Number.
* @param ctrlFlag
* - 0 data frame, else control frame.
* @param timestamp
* package sequence Number, at which the data will appear at air.
* @return
* - 0: Success;
* - others: send failed.
*/
int dpdkrf_sendDataPack(int sockfd, uint8_t **buf, int nsamps, int flags, int sn);
int32_t trx_dpdkrf_read(uint8_t **buff, uint32_t nsamps, uint64_t *timestamp);
int32_t trx_dpdkrf_write(uint8_t **buff, int nsamps, uint64_t timestamp);
int32_t trx_dpdkrf_write_ctrl(uint8_t **buff);
void *trx_dpdkrf_read_ctrl();
void plot(int type, void *data, int len);
#endif // HELLO_HELLO_H
\ No newline at end of file
#include <rte_eal.h>
#include <rte_ethdev.h>
#include <rte_mbuf.h>
#include <rte_malloc.h>
#include <rte_timer.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <stdlib.h>
#include<unistd.h>
#include <sched.h>
#include <pthread.h>
#include <string.h> /**> memset */
#include <signal.h>
#include <termios.h>
#include <rte_eal.h> /**> rte_eal_init */
#include <rte_debug.h> /**> for rte_panic */
#include <rte_errno.h> /**> rte_errno global var */
#include <rte_memzone.h> /**> rte_memzone_dump */
#include <rte_memcpy.h>
#include <rte_string_fns.h>
#include <rte_spinlock.h>
#include <time.h> /** For SLEEP **/
#include <getopt.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include <inttypes.h>
#include <sys/time.h>
#include <math.h>
#include "dpdkrf_oai.h"
#include "dpdkrf_lib.h"
#include "common/utils/LOG/log.h"
#define SAMPLE_PER_PACKAGE 960
#define ANT_PORT_NUM 1
int num_devices = 0;
#define DEFAULT_NUM 61440
static uint8_t cache_rx[4][SAMPLE_PER_PACKAGE*512];
static uint8_t cache_tx[4][SAMPLE_PER_PACKAGE*512];
#define CTRL_BUF_NUM 64
int32_t gTxCtrlBuf[SAMPLE_PER_PACKAGE * 2 * CTRL_BUF_NUM] __attribute__((aligned(8)));
int32_t gRxCtrlBuf[SAMPLE_PER_PACKAGE * 2 * CTRL_BUF_NUM] __attribute__((aligned(8)));
int gRxCtrlIdx = 0;
int gRxCtrlIdxRead = 0;
void trx_setMsgGainRx(void*buf, int g1, int g2, int g3, int g4)
{
STRUCT_CTRL_CMD_CFG_REQ *msg = buf;
memset(msg, 0, sizeof(STRUCT_CTRL_CMD_CFG_REQ));
msg->header = 0x12345678;
msg->cmdType = CTRL_CMD_ID_CFG;
msg->enable = 1;
msg->rfState = 1; // NO effect;
msg->digLoopMode = 3; // NO effect;
msg->rxGain[0] = g1;
msg->rxGain[1] = g2;
msg->rxGain[2] = g3;
msg->rxGain[3] = g4;
msg->txGain[0] = 100;
msg->txGain[1] = 100;
msg->txGain[2] = 100;
msg->txGain[3] = 100;
msg->txFreq = 0;
msg->rxFreq = 0;
return;
}
void trx_setMsgGainTx(void*buf, int g1, int g2, int g3, int g4)
{
STRUCT_CTRL_CMD_CFG_REQ *msg = buf;
memset(msg, 0, sizeof(STRUCT_CTRL_CMD_CFG_REQ));
msg->header = 0x12345678;
msg->cmdType = CTRL_CMD_ID_CFG;
msg->enable = 1;
msg->rfState = 1; // NO effect;
msg->digLoopMode = 3; // NO effect;
msg->rxGain[0] = 30;
msg->rxGain[1] = 30;
msg->rxGain[2] = 30;
msg->rxGain[3] = 30;
msg->txGain[0] = g1;
msg->txGain[1] = g2;
msg->txGain[2] = g3;
msg->txGain[3] = g4;
msg->txFreq = 0;
msg->rxFreq = 0;
return;
}
void* trx_dpdkrf_read_ctrl()
{
int t = (gRxCtrlIdx - gRxCtrlIdxRead + CTRL_BUF_NUM) % CTRL_BUF_NUM;
if (t != 0)
{
void*buff = &gRxCtrlBuf[gRxCtrlIdxRead * SAMPLE_PER_PACKAGE * 2];
gRxCtrlIdxRead++;
if (gRxCtrlIdxRead >= CTRL_BUF_NUM)
gRxCtrlIdxRead = 0;
return buff;
}
return 0;
}
int32_t trx_dpdkrf_write_ctrl(uint8_t **buff)
{
dpdkrf_sendDataPack(0, &buff[0], SAMPLE_PER_PACKAGE, 1, 0);
return 0;
}
int32_t test_dpdkrf_read (openair0_device *device, openair0_timestamp *ptimestamp, void **buff1, int nsamps, int cc){
void *buff[4];
for (int i = 0; i < ANT_PORT_NUM; i++)
{
buff[i] = buff1[i];
}
if (ANT_PORT_NUM == 1)
{
buff[1] = cache_rx[1];
}
int32_t rr = trx_dpdkrf_read(buff, nsamps, ptimestamp);
return nsamps;
}
int32_t test_dpdkrf_write (openair0_device *device,openair0_timestamp timestamp, void **buff1, int nsamps, int cc, int flags){
void *buff[4];
for (int i = 0; i < ANT_PORT_NUM; i++)
{
buff[i] = buff1[i];
}
if (ANT_PORT_NUM == 1)
{
buff[1] = cache_tx[1];
}
int32_t rr = trx_dpdkrf_write(buff,nsamps, timestamp);
return nsamps;
}
int trx_dpdkrf_start(openair0_device *device) {
uint8_t **txpCtrlgain = rte_malloc(NULL, 4 * sizeof(uint8_t), 0);
for (int i = 0; i < 4; i++)
{
txpCtrlgain[i] = (uint8_t *)gTxCtrlBuf;
}
LOG_I(HW, "[dpdkrf] Start dpdkrf ...\n");
Dpdk_device_init(15, 2, 5000000 * 5, 1);
trx_setMsgGainTx(gTxCtrlBuf, 0, 0, 0, 0);
txpCtrlgain[0] = (uint8_t *)gTxCtrlBuf;
trx_dpdkrf_write_ctrl(txpCtrlgain);
return 0;
}
void trx_dpdkrf_end(openair0_device *device){
}
int trx_dpdkrf_get_stats(openair0_device* device) {
return(0);
}
int trx_dpdkrf_reset_stats(openair0_device* device) {
return(0);
}
int trx_dpdkrf_stop(openair0_device* device) {
return(0);
}
int trx_dpdkrf_set_freq(openair0_device* device, openair0_config_t *openair0_cfg1) {
// printf("1freq = %ld %ld\n\n",openair0_cfg->rx_freq[0],openair0_cfg->tx_freq[0]);
// uint8_t **txpCtrl = rte_malloc(NULL, 4 * sizeof(uint8_t), 0);
// trx_setMsgFreq(gTxCtrlBuf, (uint64_t)(openair0_cfg->rx_freq[0]),(uint64_t)(openair0_cfg->tx_freq[0]));
// txpCtrl[0] = (uint8_t *)gTxCtrlBuf;
// trx_dpdkrf_write_ctrl(txpCtrl);
return(0);
}
int trx_dpdkrf_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) {
if (openair0_cfg->rx_gain[0] > 65+openair0_cfg->rx_gain_offset[0]) {
LOG_E(HW, "[oxgrf] Reduce RX Gain 0 by %f dB\n", openair0_cfg->rx_gain[0] - openair0_cfg->rx_gain_offset[0] - 65);
return -1;
}
uint8_t **txpCtrl = rte_malloc(NULL, 4 * sizeof(uint8_t), 0);
trx_setMsgGainRx(gTxCtrlBuf,(uint32_t)(openair0_cfg->rx_gain[0] > 65?65:openair0_cfg->rx_gain[0]),(uint32_t)(openair0_cfg->rx_gain[1] > 65?65:openair0_cfg->rx_gain[1]),100,100 );
int tx_gain1 = ((uint32_t)openair0_cfg->tx_gain[0] > 90?90:(uint32_t)openair0_cfg->tx_gain[0]);
int tx_gain2 = ((uint32_t)openair0_cfg->tx_gain[1] > 90?90:(uint32_t)openair0_cfg->tx_gain[1]);
trx_setMsgGainTx(gTxCtrlBuf, (90 - tx_gain1) * 1000,(90 - tx_gain2) * 1000,100,100);
txpCtrl[0] = (uint8_t *)gTxCtrlBuf;
trx_dpdkrf_write_ctrl(txpCtrl);
return(0);
}
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
dpdkrf_state_t *dpdkrf = (dpdkrf_state_t*)malloc(sizeof(dpdkrf_state_t));
memset(dpdkrf, 0, sizeof(dpdkrf_state_t));
LOG_I(HW, "[dpdkrf] openair0_cfg[0].sdr_addrs == '%s'\n", openair0_cfg[0].sdr_addrs);
LOG_I(HW, "[dpdkrf] openair0_cfg[0].rx_num_channels == '%d'\n", openair0_cfg[0].rx_num_channels);
LOG_I(HW, "[dpdkrf] openair0_cfg[0].tx_num_channels == '%d'\n", openair0_cfg[0].tx_num_channels);
// init required params
switch ((int)openair0_cfg->sample_rate) {
case 122880000:
openair0_cfg->samples_per_packet = 122880;
openair0_cfg->tx_sample_advance = 70;
openair0_cfg[0].tx_bw = 100e6;
openair0_cfg[0].rx_bw = 100e6;
break;
case 61440000:
openair0_cfg->samples_per_packet = 61440;
openair0_cfg->tx_sample_advance = 70;
openair0_cfg[0].tx_bw = 40e6;
openair0_cfg[0].rx_bw = 40e6;
break;
case 30720000:
openair0_cfg->samples_per_packet = 30720;
openair0_cfg->tx_sample_advance = 70;
openair0_cfg[0].tx_bw = 20e6;
openair0_cfg[0].rx_bw = 20e6;
break;
case 15360000:
openair0_cfg->samples_per_packet = 15360;
openair0_cfg->tx_sample_advance = 68;
openair0_cfg[0].tx_bw = 10e6;
openair0_cfg[0].rx_bw = 10e6;
break;
case 7680000:
openair0_cfg->samples_per_packet = 7680;
openair0_cfg->tx_sample_advance = 34;
openair0_cfg[0].tx_bw = 5e6;
openair0_cfg[0].rx_bw = 5e6;
break;
case 1920000:
openair0_cfg->samples_per_packet = 1920;
openair0_cfg->tx_sample_advance = 9;
openair0_cfg[0].tx_bw = 1.25e6;
openair0_cfg[0].rx_bw = 1.25e6;
break;
default:
LOG_I(HW, "[dpdkrf] Error: unknown sampling rate %f\n", openair0_cfg->sample_rate);
free(dpdkrf);
exit(-1);
break;
}
dpdkrf->sample_rate = (unsigned int)openair0_cfg->sample_rate;
LOG_I(HW, "[rf] sampling_rate %d\n", dpdkrf->sample_rate);
dpdkrf->rx_num_channels = openair0_cfg[0].rx_num_channels;
dpdkrf->tx_num_channels = openair0_cfg[0].tx_num_channels;
for (int i = 0; i < 1920 * 2; i++)
gTxCtrlBuf[i] = i;
char *arg[1] = {"./nr-softmodem"};
if (rte_eal_init(1,arg) < 0) {
rte_exit(EXIT_FAILURE, "Error with EAL init\n");
}
device->Mod_id = num_devices++;
device->type = DPDKRF_DEV;
device->trx_start_func = trx_dpdkrf_start;
device->trx_end_func = trx_dpdkrf_end;
device->trx_read_func = test_dpdkrf_read;
device->trx_write_func = test_dpdkrf_write;
device->trx_get_stats_func = trx_dpdkrf_get_stats;
device->trx_reset_stats_func = trx_dpdkrf_reset_stats;
device->trx_stop_func = trx_dpdkrf_stop;
device->trx_set_freq_func = trx_dpdkrf_set_freq;
device->trx_set_gains_func = trx_dpdkrf_set_gains;
device->openair0_cfg = openair0_cfg;
device->priv = (void *)dpdkrf;
// rte_timer_setup();
return 0;
}
#include "common_lib.h"
#include "nr-softmodem.h"
typedef struct {
//! Sample rate
unsigned int sample_rate;
int rx_num_channels;
int tx_num_channels;
//! Number of underflows
int num_underflows;
//! Number of overflows
int num_overflows;
//! number of RX errors
int num_rx_errors;
//! Number of TX errors
int num_tx_errors;
//! timestamp of current TX
uint64_t tx_current_ts;
//! timestamp of current RX
uint64_t rx_current_ts;
//! number of TX samples
uint64_t tx_nsamps;
//! number of RX samples
uint64_t rx_nsamps;
//! number of TX count
uint64_t tx_count;
//! number of RX count
uint64_t rx_count;
//! timestamp of RX packet
openair0_timestamp rx_timestamp;
}dpdkrf_state_t;
#define REMOVE_SUBSTRING_WITHCOMAS(S, TOREMOVE) \
remove_substring(S, TOREMOVE ","); \
remove_substring(S, TOREMOVE ", "); \
remove_substring(S, "," TOREMOVE); \
remove_substring(S, ", " TOREMOVE); \
remove_substring(S, TOREMOVE)
static inline void remove_substring(char* s, const char* toremove)
{
while ((s = strstr(s, toremove))) {
memmove(s, s + strlen(toremove), 1 + strlen(s + strlen(toremove)));
}
}
static inline void copy_subdev_string(char* dst, char* src)
{
int n = 0;
int len = (int)strlen(src);
/* Copy until end of string or comma */
while (n < len && src[n] != '\0' && src[n] != ',') {
dst[n] = src[n];
n++;
}
dst[n] = '\0';
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment