Simulink Queues: "Unsupported message connection" - simulink

I am a very new Simulink user who has been thrown into the deep end of using Simulink + Embedded Coder to generate embedded code for a custom board with an STM32 with CAN communication.
I am desperately attempting to create CAN send/receive queues. The application only transmits CAN messages in a direct 1-to-1 response with a received message: each received CAN packet generates a single CAN packet response. So, my general format is as follows: CAN Rx Interrupt handler collects the message into a Bus, uses a Send block to put the message into a Queue, which is an input to a subsystem which runs from a function generator every 50ms. Inside, I process 3 messages using a do-while loop, each iteration generating its message message. Inside the do-while subsystem is another queue for the created response packets.
When I build the model, I get the following error, which has ZERO results in Google:
"Unsupported message connection between block [path]\Queue and Outport block [path]\TxQueue. Move block [path]\Queue to outside subsystem [path]."
Now, my understanding of Simulink is still shaky at best, but I presume that moving the "queue" block, which I presume DOES the actual enqueuing, to outside the do-while subsystem will result in the first 2 response packets being dropped, right? So why is this block unsupported? Am I completely wrong about how queues work in this accursed "programming language"? My expertise is largely in embedded C, and Simulink is so new and apparently so niche that finding answers to issues like this is bafflingly difficult. Hoping someone here can help me out.

Related

Any ideas why we're getting Intermittent gRPC Unavailable/Unknown RpcExceptions (C++/C#)

We are using gRPC (version 1.37.1) for our inter-process communication between our C# process and C++ process. Both processes act as a server and client with the other and run on the same machine over localhost using the HTTP/2 transport. All of the calls are use blocking synchronous unary calls and not bi-directional streaming. Some average(ish) stats:
From C++->C#: 0-2 calls per second, 0-40 calls per minute
From C#->C++: 0-5 calls per second, 0-200 calls per minute
Intermittently, we were getting one of 3 issues
C# client call to C++ server comes back with an RpcException, usually “HTTP2/Parse Error”, “Endpoint Read Failed”, or “Transport Closed”
C++ client call to C# server comes back with Unavailable or Unknown
C++ client WaitForConnected call to check the channel fails after 500ms
The top most one is the most frequent and where we have the most information about. Usually, what we’ll see is the Client receives the RPC call and runs into an unknown frame type. Then the subchannel goes into shutdown and everything usually re-connects fine. We also generally see an embedded error like the following (note that we replaced all FILE instances to FUNCTION in our gRPC source):
win_read","file_line":307,"os_error":"The system detected an invalid pointer address in attempting to use a pointer argument in a call.\r\n","syscall":"WSARecv","wsa_error":10014}]},{"created":"#1622120588.494000000","description":"frame of size 262404 overflows local window of 65535","file":"grpc_core::chttp2::TransportFlowControl::ValidateRecvData","file_line":213}]}
What we’ve seen with the unknown frame type, is that it parses the HEADERS, WINDOW_UPDATE, DATA, WINDOW_UPDATE and then gets a TCP: on_read without a corresponding READ and then tries to parse again. It’s this parse where it looks like the parser is at the wrong offset in the buffer, because it gets the unknown frame type, incoming frame size and incoming stream_id all map to the middle of the RPC call that it just parsed.
The above was what we were encountering prior to a change to create a new channel for each rpc call. While we realize it is not great from a performance standpoint, we have seen increased stability since making the change. However, we still do occasionally get rpc exceptions. Now, the most common is “Unknown”/”Stream Removed” rather than the ones listed above.
Any ideas on what might be going wrong is appreciated. We've turned on all gRPC tracing and have even added to it, as well as captured the issue in wireshark but so far aren't getting a great indication of what's causing the transport to close. Are there any good tools to monitor the socket/port for failure?

Whiteboard assertion failure on EEPROM write

I'm trying to port the code I wrote on simulator on a HR+ sensor, and I'm facing an issue I didn't have on simulator.
The code tries to write a quite large buffer (7.5KB) on EEPROM using Whiteboard's EEPROM API by splitting it in 16 bytes long temporary buffers, calling asyncPut and busy waiting for completion (onPutResult sets a flag) before writing the next chunk.
After a few thousands iteratations (it doesn't always fail at the same iteration) execution stops with this message I'm getting through RTT: 860:Whiteboard.cpp
I think it's an assertion failure. Are there more info available on this error? What am I doing wrong? Is my approach for writing large amounts of data the right one?
ASSERT on line 860 of the Whiteboard.cpp gets triggered when the sensor cannot handle a notification from a subscription in a timely manner. I did notice a "red flag" in your description: "... and busy waiting for completion ..." which is probably the reason for it.
The Movesense framework is fully asynchronous which means that any kind of busy-looping is strictly forbidden since it prevents normal operation of the sensor (like the above notification handling).
To avoid busy looping, trigger the next asyncPut in the onPutResult() callback and make sure to specify the AsyncRequestOptions::ForceAsync option to the call.
Full disclosure: I work for the Movesense team

What's the read logic when I call recvfrom() function in C/C++

I wrote a C++ program to create a socket and bind on this socket to receive ICMP/UDP packets. The code I wrote as following:
while(true){
recvfrom(sockId, rePack, sizeof(rePack), 0, (struct sockaddr *)&raddr, (socklen_t *)&len);
processPakcet(recv_size);
}
So, I used a endless while loop to receive messages continually, But I worried about the following two questions:
1, How long the message would be kept in the receiver queue or say in NIC queue?
I worried about that if it takes too long to process the first message, then I might miss the second message. so how fast should I read after read.
2, How to prevent reading the duplicated messages?
i.e, does the receiver queue knows me, when my thread read the first message done, would the queue automatically give me the second one? or say, when I read the first message, then the first message would be deleted by the queue and no one could receive it again.
Additionally, I think the while(true) module is not good, anyone could give me a good suggestion please. (I heard something like polling module).
First, you should always check the return value from recvfrom. It's unlikely the recvfrom will fail, but if it does (for example, if you later implement signal handling, it might fail with EINTR) you will be processing undefined data. Also, of course, the return value tells you the size of the packet you received.
For question 1, the actual answer is operating system-dependent. However, most operating systems will buffer some number of packets for you. The OS interrupt handler that handles the incoming packet will never be copying it directly into your application level buffer, so it will always go into an OS buffer first. The OS has previously noted your interest in it (by virtue of creating the socket and binding it you expressed interest), so it will then place a pointer to the buffer onto a queue associated with your socket.
A different part of the OS code will then (after the interrupt handler has completed) copy the data from the OS buffer into your application memory, free the OS buffer, and return to your program from the recvfrom system call. If additional packets come in, either before or after you have started processing the first one, they'll be placed on the queue too.
That queue is not infinite of course. It's likely that you can configure how many packets (or how much buffer space) can be reserved, either at a system-wide level (think sysctl-type settings in linux), or at the individual socket level (setsockopt / ioctl).
If, when you call recvfrom, there are already queued packets on the socket, the system call handler will not block your process, instead it will simply copy from the OS buffer of the next queued packet into your buffer, release the OS buffer, and return immediately. As long as you can process incoming packets roughly as fast as they arrive or faster, you should not lose any. (However, note that if another system is generating packets at a very high rate, it's likely that the OS memory reserved will be exhausted at some point, after which the OS will simply discard packets that exceed its resource reservation.)
For question 2, you will receive no duplicate messages (unless something upstream of your machine is actually duplicating them). Once a queued message is copied into your buffer, it's released before returning to you. That message is gone forever.
(Note that it's possible that some other process has also created a socket expressing interest in the same packets. That process would also get a copy of the packet data, which is typically handled internal to the operating system by reference counting rather than by actually duplicating the OS buffers, although that detail is invisible to applications. In any case, once all interested processes have received the packet, it will be discarded.)
There's really nothing at all wrong with a while (true) loop; it's a very common control structure for long-running server-type programs. If your program has nothing else it needs to be doing in the meantime, while true allowing it to block in recvfrom is the simplest and hence clearest way to implement it.
(You could use a select(2) or poll(2) call to wait. This allows you to handle waiting for any one of multiple file descriptors at the same time, or to periodically "time out" and go do something else, say, but again if you have nothing else you might need to be doing in the meantime, that is introducing needless complication.)

How can I invoke UART_Receive_IT() automatically when I receive a data?

I am new to STM32 and freertos. I need to write a program to send and receive data from a module via UART port. I have to send(Transmit) a data to that module(for eg. M66). Then I would return to do some other tasks. once the M66 send a response to that, my seial-port-receive-function(HAL_UART_Receive_IT) has to be invoked and receive that response. How can I achieve this?
The way HAL_UART_Receive_IT works is that you configure it to receive specified amount of data into given buffer. You give it your buffer to which it'll read received data and number of bytes you want to receive. It then starts receiving data. Once exactly this amount of data is received, a callback function HAL_UART_RxCpltCallback gets called (from IRQ) where you can do whatever you want with this data, e.g. add it to some kind of queue for later processing in the task context.
If I was to express my experiences related to working with HAL's UART module is that it's not the greatest one for generic use where you don't know the amount of data you expect to receive in advance. In the case of M66 modem you mention, this will happen all the time.
To solve this you have two choices:
Simply don't use HAL functions at all in case of UART, other than the initialization functions. Implement your own UART interrupt handler (most of the code can be copied from handler in HAL) where upon receiving data you place received bytes in a receive byte queue handled in your RTOS task. In this task you implement protocol parsing. This is the approach I use personally.
If you really want to use HAL but also work with a module that sends varying amount of data, call HAL_UART_Receive_IT and specify that you want to receive 1 byte each time. This will work, but will be (potentially much) slower than the first approach. Assuming you'll later want to implement some tcp/ip communication (you mentioned M66 GPRS module) you probably don't want to do it this way.
You should try the following way.
Enable UARTX Rx interrupt in NVIC.
Set Interrupt priority.
Unmask Interrupt request in EXTI.
Then use USARTX Interrupt Handler Function Define in you Vector.
Whenever the data is received from USARTX this function get automatically called and you can copy data from USARTX Receive Data Register.
I would rather suggest another approach. You probably want to archive higher speeds (lets say 921600 bods) and the interrupt way is fat to slow for it.
You need to implement the DMA transmition with the data end detection features. Run your USART in the DMA mode in the circular mode. You will have two events to serve. The first one is the DMA end of thransmition interrupt (then you copy the data from the current tail pointer to the end of the buffer to avoid data override) and USART IDLE interrupt - this will detect the end of the receive.

Simulink UDP Send Callback

How can I access the callbacks for the "UDP Send" Block (from Instrument Control Toolbox) in Simulink?
I want to send UDP data as fast as it is available in Simulink. After a short amount of time running my Simulink model the Simulation stops as "an asynchronous write is already in progress".
I would like to send whenever the status of that block is '{idle}', however I haven't found a way to access this information.
I also tried to write the function myself in a matlab script within the Simulink model, but code generation is not supported for udp class.
As far as I know, the UDP Send block doesn't give you access to that.
However, you can use coder.extrinsic(function_name_1, ...) to build your own MATLAB block.