2

I am using Simulink and Simulink Coder to generate a dll of arbitrary Models. My C Application uses the mathworks CAPI. It runs arbitrary models (hard real time below 1 ms) and is able to modify any parameters of the model (by using the tunable parameters).

For simlpe scalar values I am obtaining the adress of the value.

Pseudocode:

void* simplegain = rtwCAPI_GetSignalAddrIdx()
*simplegain=42;

Everything runs fine. However, this approach can not be applied if I want an atomic change of complete vector and matrix.

For multidimensional Data I used memcopy to write all values from a destination to the result of GetSignalAddIdx(). Measurements have shown that using memcopy is to slow. Analysing the generated Code show various calls of rt_Lookup

real_T rt_Lookup(const real_T *x, int_T xlen, real_T u, const real_T *y)
// x is the pointer the matrix The Adress of the matrix is declared in a global structure  `rtDataAddrMap` statically. I can read it out, but do not know how to change.

What I like to achieve is:

  1. Define a second map in my application (same size).
  2. Write all new value the this second map.
  3. Change just the pointer in rtDataAddrMap to activate the second map.

The general question: How can I achieve to change multidimensional parameters atomically? What is the regular way to do this? (Code Generation Options etc..)

The specific question: (if my approach was right) What are reasonable solutions to change the data pointer of a matrix?

ToBe
  • 921
  • 1
  • 9
  • 23

1 Answers1

0

Atomic in the sense of calling an instruction which does its work in a single clock cycle (and thus not possible to interrupt) is not possible to achieve when it comes to this kind of multidimensional arrays. Instead you will need some kind of real time mechanism like a mutex or semaphore to protect your data. Mutexes and semaphores are built upon atomic operations which guarantees that two processes will not be able to consume the same resource at once.

Your approach with ping pong buffering of your data area will probably improve performance. Unfortunately I do not have enough experience from Mathworks generated code to tell how to implement that.

Henrik Carlqvist
  • 1,138
  • 5
  • 6
  • Thanks for your answer. I am under hard real time and need non blocking solutions and therefore are willing not to use locks. I am in specific looking for possibilities to to adapt the generated code or write wrapper around generated code to accomplish task. – ToBe Jun 16 '15 at 09:17
  • This kind of mechanisms (spinlock, mutex, semaphore or whatever it might be called) is a standard solution for real time design. The trick is to make sure that no task keep the lock any longer than necessary and to avoid deadlocks. Maybe you need to explain your problem more... What kind of bad stuff happen unless all cycles meet the hard requirement of less than 1 ms? Which real time environment do you have to guarantee that your real time tasks won't be left without resources for more than a few hundred us? Once we know your environment it will be easier to tell you about its mechanisms. – Henrik Carlqvist Jun 16 '15 at 19:34
  • Hard Real Time is not about performance in 1st place - its about determism/predictablity (execution time). I am using real time kernel (windows extension - RTX from IntervalZero). The application is communicating with the outer world via electrical signals (digital and analog). The model can be implemented as a digital feedback controller. Plants to control have Time constants below 1 ms. – ToBe Jun 17 '15 at 07:14
  • I agree that performance and real time are different things, hard real time means that missing a single deadline means a total system failure. With soft real time missed deadlines means a degraded but somehow still usable system. Does your software use more than one task (perhaps with different priorities)? If not, you will not need any mutex-mechanism or atomic functions as the outer world does not access your memory. I have no experience from RTX myself and found no info about their semaphore mechanisms on their web. – Henrik Carlqvist Jun 17 '15 at 21:01
  • Yes, multiple threads with different priorities. At least 2 are important here. Within 1st Thread (with lower priority - no hard real time constraint) the parameters are set. 2nd Thread with higher priority is stepping the model (hard real time contraint). In this thread I am looking to have the switch from old parameter to new parameter. With some minor differences synchronisation primitives are similar to Windows. – ToBe Jun 17 '15 at 21:09
  • 1
    Some kind of locking mechanism is needed to avoid that thread 2 reads the parameters when thread 1 was interrupted while in the middle of updating the parameters. Maybe you could also avoid this to happen by using an atomic update of a pointer to some kind of double buffer. If you use some lock and have more tasks with priorities between lower priority thread 1 and higher priority thread 2 you might want to rise the priority of task 1 before obtaining the lock. Otherwise a task with a priority between task 1 and task 2 might starve task 2 waiting for the lock while task 1 is waiting for CPU. – Henrik Carlqvist Jun 17 '15 at 21:38
  • I opened up a service request to mathworks and we will work on a a solution how the generated code can be adapted to have this kind of double buffering. I am leaving bounty to Henrik Carlvist, but will leave this question without accecpted answer now. – ToBe Jun 18 '15 at 07:15