aboutsummaryrefslogtreecommitdiffstats
path: root/Transceiver52M/device/ipc/shm.h
diff options
context:
space:
mode:
authorEric <ewild@sysmocom.de>2020-04-24 21:39:17 +0200
committerEric <ewild@sysmocom.de>2020-04-27 05:02:26 +0200
commit90b0b8696d1eed260780792f9c29c2bf84b2d79e (patch)
tree8633322f88bdc756178d742585146ca2dafe2814 /Transceiver52M/device/ipc/shm.h
parent2120eb1e0a5d7cd3a0aceb3aa7ed54ed197a1b3d (diff)
v1
Diffstat (limited to 'Transceiver52M/device/ipc/shm.h')
-rw-r--r--Transceiver52M/device/ipc/shm.h265
1 files changed, 122 insertions, 143 deletions
diff --git a/Transceiver52M/device/ipc/shm.h b/Transceiver52M/device/ipc/shm.h
index 6565f5b..ddb599e 100644
--- a/Transceiver52M/device/ipc/shm.h
+++ b/Transceiver52M/device/ipc/shm.h
@@ -15,99 +15,64 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
-
-/*
-https://www.softprayog.in/programming/interprocess-communication-using-posix-shared-memory-in-linux
-
-man shm_open: link with -lrt
-Link with -pthread.
-
-#include <sys/mman.h>
-#include <sys/stat.h> // For mode constants
-#include <fcntl.h> // For O_* constants
-#include <semaphore.h>
-
-On start:
-int fd = shm_open(const char *name, int oflag, mode_t mode);
-* name must start with "/" and not contain more slashes.
-* name must be a null-terminted string of up to NAME_MAX (255)
-* oflag: O_CREAT|O_RDWR|O_EXCL
-* mode: check man open
-
-ftruncate(fd, len = sizeof(struct myshamemorystruct) to expand the memory region
-
-shm = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
-
-int sem_init(sem_t *&(shm->sem), 1, unsigned int value) == 0;
-
-close(fd); // After a call to mmap(2) the file descriptor may be closed without affecting the memory mapping.
-
-
-On exit:
-int shm_unlink(const char *name);
-
-
-sem_t *sem_open(const char *name, int oflag,
- mode_t mode, unsigned int value);
-* by a name of the form /somename; that is, a null-terminated string of up to NAME_MAX-4 (i.e., 251) characters
- consisting of an initial slash, followed by one or more characters, none of which are slashes.
-
-
-* unamed semaphore: sem_init + sem_destroy
-* Programs using the POSIX semaphores API must be compiled with cc -pthread to link against the real-time library, librt
-*/
+#pragma once
#include <stdint.h>
#include <unistd.h>
#include <limits.h>
+//#include <pthread.h>
+#include <semaphore.h>
/* RAW structures */
struct ipc_shm_raw_smpl_buf {
- uint32_t timestamp;
- uint32_t data_len; /* In samples */
- uint16_t samples[0];
+ uint64_t timestamp;
+ uint32_t data_len; /* In samples */
+ uint16_t samples[0];
};
struct ipc_shm_raw_stream {
- uint32_t num_buffers;
- uint32_t buffer_size; /* In samples */
- uint32_t read_next;
- uint32_t write_next;
- uint32_t buffer_offset[0];
- //struct ipc_shm_smpl_buf buffers[0];
+ pthread_mutex_t lock;
+ pthread_cond_t cf;
+ pthread_cond_t ce;
+ uint32_t num_buffers;
+ uint32_t buffer_size; /* In samples */
+ uint32_t read_next;
+ uint32_t write_next;
+ uint32_t buffer_offset[0];
+ //struct ipc_shm_smpl_buf buffers[0];
};
struct ipc_shm_raw_channel {
- uint32_t dl_buf_offset;
- uint32_t ul_buf_offset;
+ uint32_t dl_buf_offset;
+ uint32_t ul_buf_offset;
};
struct ipc_shm_raw_region {
- uint32_t num_chans;
- uint32_t chan_offset[0];
+ uint32_t num_chans;
+ uint32_t chan_offset[0];
};
-
/* non-raw, Pointer converted structures */
struct ipc_shm_stream {
- uint32_t num_buffers;
- uint32_t buffer_size;
- struct ipc_shm_raw_stream *raw;
- struct ipc_shm_raw_smpl_buf *buffers[0];
+ uint32_t num_buffers;
+ uint32_t buffer_size;
+ volatile struct ipc_shm_raw_stream *raw;
+ volatile struct ipc_shm_raw_smpl_buf *buffers[0];
};
struct ipc_shm_channel {
- struct ipc_shm_stream *dl_stream;
- struct ipc_shm_stream *ul_stream;
+ struct ipc_shm_stream *dl_stream;
+ struct ipc_shm_stream *ul_stream;
};
/* Pointer converted structures */
struct ipc_shm_region {
- uint32_t num_chans;
- struct ipc_shm_channel *channels[0];
+ uint32_t num_chans;
+ struct ipc_shm_channel *channels[0];
};
-unsigned int ipc_shm_encode_region(struct ipc_shm_raw_region *root_raw, uint32_t num_chans, uint32_t num_buffers, uint32_t buffer_size);
+unsigned int ipc_shm_encode_region(struct ipc_shm_raw_region *root_raw, uint32_t num_chans, uint32_t num_buffers,
+ uint32_t buffer_size);
struct ipc_shm_region *ipc_shm_decode_region(void *tall_ctx, struct ipc_shm_raw_region *root_raw);
/****************************************/
/* UNIX SOCKET API */
@@ -121,12 +86,12 @@ struct ipc_shm_region *ipc_shm_decode_region(void *tall_ctx, struct ipc_shm_raw_
#define IPC_SOCK_API_VERSION 1
/* msg_type */
-#define IPC_IF_MSG_GREETING_REQ 0x00
-#define IPC_IF_MSG_GREETING_CNF 0x01
-#define IPC_IF_MSG_INFO_REQ 0x02
-#define IPC_IF_MSG_INFO_CNF 0x03
-#define IPC_IF_MSG_OPEN_REQ 0x04
-#define IPC_IF_MSG_OPEN_CNF 0x05
+#define IPC_IF_MSG_GREETING_REQ 0x00
+#define IPC_IF_MSG_GREETING_CNF 0x01
+#define IPC_IF_MSG_INFO_REQ 0x02
+#define IPC_IF_MSG_INFO_CNF 0x03
+#define IPC_IF_MSG_OPEN_REQ 0x04
+#define IPC_IF_MSG_OPEN_CNF 0x05
#define MAX_NUM_CHANS 30
#define RF_PATH_NAME_SIZE 25
@@ -136,114 +101,128 @@ struct ipc_shm_region *ipc_shm_decode_region(void *tall_ctx, struct ipc_shm_raw_
#define FEATURE_MASK_CLOCKREF_INTERNAL (0x1 << 0)
#define FEATURE_MASK_CLOCKREF_EXTERNAL (0x1 << 1)
struct ipc_sk_if_info_chan {
- char tx_path[MAX_NUM_RF_PATHS][RF_PATH_NAME_SIZE];
- char rx_path[MAX_NUM_RF_PATHS][RF_PATH_NAME_SIZE];
-} __attribute__ ((packed));
+ char tx_path[MAX_NUM_RF_PATHS][RF_PATH_NAME_SIZE];
+ char rx_path[MAX_NUM_RF_PATHS][RF_PATH_NAME_SIZE];
+} __attribute__((packed));
struct ipc_sk_if_open_req_chan {
- char tx_path[RF_PATH_NAME_SIZE];
- char rx_path[RF_PATH_NAME_SIZE];
-} __attribute__ ((packed));
+ char tx_path[RF_PATH_NAME_SIZE];
+ char rx_path[RF_PATH_NAME_SIZE];
+} __attribute__((packed));
struct ipc_sk_if_open_cnf_chan {
- char chan_ipc_sk_path[108];
-} __attribute__ ((packed));
+ char chan_ipc_sk_path[108];
+} __attribute__((packed));
struct ipc_sk_if_greeting {
- uint8_t req_version;
-} __attribute__ ((packed));
+ uint8_t req_version;
+} __attribute__((packed));
struct ipc_sk_if_info_req {
- uint8_t spare;
-} __attribute__ ((packed));
+ uint8_t spare;
+} __attribute__((packed));
struct ipc_sk_if_info_cnf {
- uint32_t feature_mask;
- double min_rx_gain;
- double max_rx_gain;
- double min_tx_gain;
- double max_tx_gain;
- double iq_scaling_val;
- uint32_t max_num_chans;
- char dev_desc[200];
- struct ipc_sk_if_info_chan chan_info[0];
-} __attribute__ ((packed));
+ uint32_t feature_mask;
+ double min_rx_gain;
+ double max_rx_gain;
+ double min_tx_gain;
+ double max_tx_gain;
+ double iq_scaling_val_rx;
+ double iq_scaling_val_tx;
+ uint32_t max_num_chans;
+ char dev_desc[200];
+ struct ipc_sk_if_info_chan chan_info[0];
+} __attribute__((packed));
struct ipc_sk_if_open_req {
- uint32_t num_chans;
- uint32_t clockref; /* One of FEATUER_MASK_CLOCKREF_* */
- uint32_t rx_sps;
- uint32_t tx_sps;
- uint32_t bandwidth;
- struct ipc_sk_if_open_req_chan chan_info[0];
-} __attribute__ ((packed));
+ uint32_t num_chans;
+ uint32_t clockref; /* One of FEATUER_MASK_CLOCKREF_* */
+ uint32_t rx_sample_freq_num;
+ uint32_t rx_sample_freq_den;
+ uint32_t tx_sample_freq_num;
+ uint32_t tx_sample_freq_den;
+ uint32_t bandwidth;
+ struct ipc_sk_if_open_req_chan chan_info[0];
+} __attribute__((packed));
struct ipc_sk_if_open_cnf {
- uint8_t return_code;
- char shm_name[SHM_NAME_MAX];
- struct ipc_sk_if_open_cnf_chan chan_info[0];
-} __attribute__ ((packed));
+ uint8_t return_code;
+ uint32_t path_delay;
+ char shm_name[SHM_NAME_MAX];
+ struct ipc_sk_if_open_cnf_chan chan_info[0];
+} __attribute__((packed));
struct ipc_sk_if {
- uint8_t msg_type; /* message type */
- uint8_t spare[2];
+ uint8_t msg_type; /* message type */
+ uint8_t spare[2];
union {
- struct ipc_sk_if_greeting greeting_req;
- struct ipc_sk_if_greeting greeting_cnf;
- struct ipc_sk_if_info_req info_req;
- struct ipc_sk_if_info_cnf info_cnf;
- struct ipc_sk_if_open_req open_req;
- struct ipc_sk_if_open_cnf open_cnf;
+ struct ipc_sk_if_greeting greeting_req;
+ struct ipc_sk_if_greeting greeting_cnf;
+ struct ipc_sk_if_info_req info_req;
+ struct ipc_sk_if_info_cnf info_cnf;
+ struct ipc_sk_if_open_req open_req;
+ struct ipc_sk_if_open_cnf open_cnf;
} u;
-} __attribute__ ((packed));
-
+} __attribute__((packed));
//////////////////
// Channel socket
//////////////////
-#define IPC_IF_MSG_START_REQ 0x00
-#define IPC_IF_MSG_START_CNF 0x01
-#define IPC_IF_MSG_STOP_REQ 0x02
-#define IPC_IF_MSG_STOP_CNF 0x03
-#define IPC_IF_MSG_SETGAIN_REQ 0x04
-#define IPC_IF_MSG_SETGAIN_CNF 0x05
-#define IPC_IF_MSG_SETFREQ_REQ 0x04
-#define IPC_IF_MSG_SETFREQ_CNF 0x05
+#define IPC_IF_CHAN_MSG_OFFSET 50
+#define IPC_IF_MSG_START_REQ IPC_IF_CHAN_MSG_OFFSET + 0x00
+#define IPC_IF_MSG_START_CNF IPC_IF_CHAN_MSG_OFFSET + 0x01
+#define IPC_IF_MSG_STOP_REQ IPC_IF_CHAN_MSG_OFFSET + 0x02
+#define IPC_IF_MSG_STOP_CNF IPC_IF_CHAN_MSG_OFFSET + 0x03
+#define IPC_IF_MSG_SETGAIN_REQ IPC_IF_CHAN_MSG_OFFSET + 0x04
+#define IPC_IF_MSG_SETGAIN_CNF IPC_IF_CHAN_MSG_OFFSET + 0x05
+#define IPC_IF_MSG_SETFREQ_REQ IPC_IF_CHAN_MSG_OFFSET + 0x06
+#define IPC_IF_MSG_SETFREQ_CNF IPC_IF_CHAN_MSG_OFFSET + 0x07
+
+#define IPC_IF_NOTIFY_UNDERFLOW IPC_IF_CHAN_MSG_OFFSET + 0x08
+#define IPC_IF_NOTIFY_OVERFLOW IPC_IF_CHAN_MSG_OFFSET + 0x09
struct ipc_sk_chan_if_op_void {
-} __attribute__ ((packed));
+ // at least one dummy byte, to allow c/c++ compatibility
+ uint8_t dummy;
+} __attribute__((packed));
struct ipc_sk_chan_if_op_rc {
- uint8_t return_code;
-} __attribute__ ((packed));
+ uint8_t return_code;
+} __attribute__((packed));
struct ipc_sk_chan_if_gain {
- double gain;
- uint8_t is_tx;
-} __attribute__ ((packed));
+ double gain;
+ uint8_t is_tx;
+} __attribute__((packed));
struct ipc_sk_chan_if_freq_req {
- double freq;
- uint8_t is_tx;
-} __attribute__ ((packed));
+ double freq;
+ uint8_t is_tx;
+} __attribute__((packed));
struct ipc_sk_chan_if_freq_cnf {
- uint8_t return_code;
-} __attribute__ ((packed));
+ uint8_t return_code;
+} __attribute__((packed));
+
+struct ipc_sk_chan_if_notfiy {
+ uint8_t dummy;
+} __attribute__((packed));
struct ipc_sk_chan_if {
- uint8_t msg_type; /* message type */
- uint8_t spare[2];
+ uint8_t msg_type; /* message type */
+ uint8_t spare[2];
union {
- struct ipc_sk_chan_if_op_void start_req;
- struct ipc_sk_chan_if_op_rc start_cnf;
- struct ipc_sk_chan_if_op_void stop_req;
- struct ipc_sk_chan_if_op_rc stop_cnf;
- struct ipc_sk_chan_if_gain set_gain_req;
- struct ipc_sk_chan_if_gain set_gain_cnf;
- struct ipc_sk_chan_if_freq_req set_freq_req;
- struct ipc_sk_chan_if_freq_cnf set_freq_cnf;
+ struct ipc_sk_chan_if_op_void start_req;
+ struct ipc_sk_chan_if_op_rc start_cnf;
+ struct ipc_sk_chan_if_op_void stop_req;
+ struct ipc_sk_chan_if_op_rc stop_cnf;
+ struct ipc_sk_chan_if_gain set_gain_req;
+ struct ipc_sk_chan_if_gain set_gain_cnf;
+ struct ipc_sk_chan_if_freq_req set_freq_req;
+ struct ipc_sk_chan_if_freq_cnf set_freq_cnf;
+ struct ipc_sk_chan_if_notfiy notify;
} u;
-} __attribute__ ((packed));
+} __attribute__((packed));