Commit eaf5e9f9 authored by Federico Vaga's avatar Federico Vaga

sw:*: improve HMQ header definition

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent f31d074f
......@@ -66,11 +66,25 @@ enum trtl_msg_id_o {
/**
* HMQ headerd descriptor
* Synchronous. When set, the sync_id is valid and the receiver
* must answer with a message with the same sync_id
*/
#define TRTL_HMQ_HEADER_FLAG_SYNC (1 << 0)
/**
* HMQ header descriptor
*/
struct trtl_hmq_header {
uint32_t len;
uint32_t sync_id;
/* word 0 */
uint16_t rt_app_id; /**< Real-Time application unique identifier */
uint8_t flags;
uint8_t msg_id; /**< Message identifier */
/* word 1 */
uint16_t len; /**< message-length */
uint16_t sync_id;/**< synchronous identifier */
/* word 2 */
uint32_t seq; /**< sequence number */
};
......
......@@ -107,22 +107,70 @@ static void trtl_hmq_header_read(struct trtl_hmq *hmq,
struct trtl_hmq_header *hdr)
{
struct trtl_dev *trtl = to_trtl_dev(hmq->dev.parent->parent);
uint32_t *base;
struct platform_device *pdev = to_platform_device(trtl->dev.parent);
uint32_t *base, val;
base = hmq->base_in + TRTL_MQ_SLOT_HEADER_START;
hdr->len = trtl_ioread(trtl, &base[0]) + 1; /* last valid index */
hdr->sync_id = trtl_ioread(trtl, &base[1]);
switch (pdev->id_entry->driver_data) {
case TRTL_VER_SVEC:
/* word 0 */
val = trtl_ioread(trtl, &base[0]);
hdr->rt_app_id = (val & 0x0000FFFF) >> 0;
hdr->flags = (val & 0x00FF0000) >> 16;
hdr->msg_id = (val & 0xFF000000) >> 24;
/* word 1*/
val = trtl_ioread(trtl, &base[1]);
hdr->len = (val & 0x0000FFFF) >> 0;
hdr->sync_id = (val & 0xFFFF0000) >> 16;
/* word 2*/
hdr->seq = trtl_ioread(trtl, &base[2]);
break;
default: {
uint32_t *hdr_w = (uint32_t *)hdr;
int i;
for (i = 0; i < sizeof(struct trtl_hmq_header) / 4; ++i)
hdr_w[i] = trtl_ioread(trtl, &base[i]);
break;
}
}
}
static void trtl_hmq_header_write(struct trtl_hmq *hmq,
struct trtl_hmq_header *hdr)
{
struct trtl_dev *trtl = to_trtl_dev(hmq->dev.parent->parent);
uint32_t *base;
struct platform_device *pdev = to_platform_device(trtl->dev.parent);
uint32_t *base, val;
base = hmq->base_out + TRTL_MQ_SLOT_HEADER_START;
trtl_iowrite(trtl, hdr->len - 1, &base[0]); /* last valid index */
trtl_iowrite(trtl, hdr->sync_id, &base[1]);
switch (pdev->id_entry->driver_data) {
case TRTL_VER_SVEC:
/* word 1 */
val = 0;
val |= (hdr->rt_app_id << 0);
val |= (hdr->msg_id << 24);
val |= (hdr->flags << 16);
trtl_iowrite(trtl, val, &base[0]);
/* word 1 */
val = 0;
val |= (hdr->sync_id << 16);
val |= (hdr->len << 0);
trtl_iowrite(trtl, val, &base[1]);
/* word 2 */
val = 0;
val |= (hdr->seq << 0);
trtl_iowrite(trtl, val, &base[2]);
break;
default: {
uint32_t *hdr_w = (uint32_t *)hdr;
int i;
for (i = 0; i < sizeof(struct trtl_hmq_header) / 4; ++i)
trtl_iowrite(trtl, hdr_w[i], &base[i]);
break;
}
}
}
......
......@@ -65,30 +65,30 @@ class TrtlMessageInternal(Structure):
("error", c_int),
]
class TrtlHeader(Structure):
class TrtlHmqHeader(Structure):
TRTL_HMQ_HEADER_FLAG_SYNC=(1 << 0)
_fields_ = [
("rt_app_id", c_uint16),
("flags", c_uint8),
("msg_id", c_uint8),
("slot_io", c_uint8),
("len", c_uint16),
("sync_id", c_uint16),
("seq", c_uint32),
("len", c_uint8),
("flags", c_uint8),
("__unused", c_uint8),
("trans", c_uint8),
("time", c_uint32),
]
class TrtlHmqHeader(Structure):
_fields_ = [
("len", c_uint32),
("sync_id", c_uint32),
]
def __eq__(self, other):
if self.rt_app_id != other.rt_app_id:
return False
if self.flags != other.flags:
return False
if self.msg_id != other.msg_id:
return False
if self.len != other.len:
return False
if self.sync_id != other.sync_id:
return False
if self.seq != other.seq:
return False
return True
class TrtlMessage(Structure):
......@@ -111,14 +111,6 @@ class TrtlMessage(Structure):
return True
class TrtlPacket(Structure):
_fields_ = [
("header", TrtlHeader),
("payload", (c_uint32 * (128 - 4))),
]
class TrtlDevice(object):
"""It is a Python class that represent a Mock Turtle Device
"""
......@@ -240,12 +232,6 @@ class TrtlDevice(object):
# self.libtrtl.trtl_hmq_filter_add.argtypes = [c_void_p]
# self.libtrtl.trtl_hmq_filter_clean.argtypes = [c_void_p]
# self.libtrtl.trtl_message_pack.argtypes = [POINTER(TrtlMessage),
# POINTER(TrtlHeader),
# c_void_p]
# self.libtrtl.trtl_message_unpack.argtypes = [POINTER(TrtlMessage),
# POINTER(TrtlHeader),
# c_void_p]
# # Return
# self.libtrtl.trtl_hmq_filter_add.restype = c_int
# self.libtrtl.trtl_hmq_filter_clean.restype = c_int
......
......@@ -18,7 +18,7 @@ You should have received a copy of the GNU Library General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from .PyMockTurtle import TrtlHeader, TrtlMessage, TrtlConfig, \
from .PyMockTurtle import TrtlHmqHeader, TrtlMessage, TrtlConfig, \
TrtlCpu, TrtlHmq, TrtlSmem, TrtlDevice, \
TRTL_CONFIG_ROM_MAX_CPU, \
TRTL_CONFIG_ROM_MAX_HMQ, \
......@@ -29,7 +29,7 @@ __all__ = (
"TrtlCpu",
"TrtlHmq",
"TrtlSmem",
"TrtlHeader",
"TrtlHmqHeader",
"TrtlMessage",
"TrtlConfig",
"TRTL_CONFIG_ROM_MAX_CPU",
......
......@@ -30,7 +30,10 @@ static char *trtl_error_str[] = {
"The HMQ slot is close",
"Invalid message",
"Error while reading HMQ messages",
"Failed to send/receive synchronous message",
"Failed to send synchronous message",
"Failed to receive synchronous message",
"Failed to receive synchronous message: timeout",
"Failed to receive synchronous message: invalid sync id",
NULL,
};
......@@ -42,9 +45,10 @@ enum trtl_msg_filter_predefiened {
static struct trtl_msg_filter filters[] = {
[TRTL_MSG_FILTER_ASYNC] = {
.flags = 0,
.operation = TRTL_MSG_FILTER_EQ,
.word_offset = 1, /* ATTENTION: sync_id in the message header */
.value = 0,
.operation = TRTL_MSG_FILTER_AND,
.word_offset = 0, /* ATTENTION: sync_id in the message header */
.mask = TRTL_HMQ_HEADER_FLAG_SYNC << 8,
.value = TRTL_HMQ_HEADER_FLAG_SYNC << 8,
},
[TRTL_MSG_FILTER_SYNC] = {
.flags = 0,
......@@ -1092,7 +1096,8 @@ int trtl_msg_async_send(struct trtl_dev *trtl,
/**
* It sends and receives a synchronous message
* It sends and receives a synchronous message. It is up to the user to set the
* "sync_id" in the message that it would like to send.
* @param[in] trtl device token
* @param[in] idx_cpu CPU index
* @param[in] idx_hmq HMQ index
......@@ -1112,13 +1117,14 @@ int trtl_msg_sync(struct trtl_dev *trtl,
struct polltrtl p;
struct trtl_msg_filter f_sync = {
.flags = 0,
.operation = TRTL_MSG_FILTER_EQ,
.operation = TRTL_MSG_FILTER_AND,
.word_offset = 1, /* ATTENTION: sync_id in the message header */
.mask = 0xFFFF0000,
};
int ret;
msg_s->hdr.sync_id = 1;
f_sync.value = msg_s->hdr.sync_id;
msg_s->hdr.flags |= TRTL_HMQ_HEADER_FLAG_SYNC;
f_sync.value = (msg_s->hdr.sync_id << 16);
ret = trtl_hmq_filter_add(wdesc->trtl_sync, idx_cpu, idx_hmq,
&f_sync);
......@@ -1130,7 +1136,7 @@ int trtl_msg_sync(struct trtl_dev *trtl,
if (ret < 0)
return -1;
if (ret == 0) {
errno = ETRTL_MSG_SYNC_FAILED;
errno = ETRTL_MSG_SYNC_FAILED_SEND;
return -1;
}
......@@ -1143,8 +1149,12 @@ int trtl_msg_sync(struct trtl_dev *trtl,
if (ret < 0)
return -1;
/* I (git blame) know, this if is over-complicated */
if (ret == 0 || (p.revents & POLLERR) || !(p.revents & POLLIN)) {
errno = ETRTL_MSG_SYNC_FAILED;
if (ret == 0) {
errno = ETRTL_MSG_SYNC_FAILED_RECV_TIMEOUT;
return -1;
}
if ((p.revents & POLLERR) || !(p.revents & POLLIN)) {
errno = ETRTL_MSG_SYNC_FAILED_RECV;
return -1;
}
......@@ -1153,13 +1163,13 @@ int trtl_msg_sync(struct trtl_dev *trtl,
if (ret < 0)
return -1;
if (ret == 0) {
errno = ETRTL_MSG_SYNC_FAILED;
errno = ETRTL_MSG_SYNC_FAILED_RECV;
return -1;
}
/* paranoid check, the driver should be right */
if (msg_s->hdr.sync_id != msg_r->hdr.sync_id) {
errno = ETRTL_MSG_SYNC_FAILED;
errno = ETRTL_MSG_SYNC_FAILED_INVAL;
return -1;
}
......
......@@ -88,7 +88,12 @@ enum trtl_error_number {
ETRTL_HMQ_CLOSE, /**< The HMQ is closed */
ETRTL_INVALID_MESSAGE, /**< Invalid message */
ETRTL_HMQ_READ, /**< Error while reading messages */
ETRTL_MSG_SYNC_FAILED,
ETRTL_MSG_SYNC_FAILED_SEND, /**< Send sync message failure */
ETRTL_MSG_SYNC_FAILED_RECV, /**< Receive sync message failure */
ETRTL_MSG_SYNC_FAILED_RECV_TIMEOUT, /**< Receive sync message failure:
timeout */
ETRTL_MSG_SYNC_FAILED_INVAL, /**< Receive sync message failure:
invalid */
__ETRTL_MAX,
};
......
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