What is the correct way to use "global data sharing" in Simulink, including external C files with S function builder?
35 ビュー (過去 30 日間)
古いコメントを表示
Hello,
I would like to include two external C files in an existing Simulink simulation. Data transfer is needed between these two files/modules. To test this, I created a simple example model. I will attach this model (fill_read_struct.slx). As I can't attach a .c/.h file, I will paste the code of each file below. To improve understanding of the data flow, I have created a flow chart diagram (flow.jpg).
The basic data flow is as follows:
Within sfunc_fill_struct:
- Call Simulink_call_fill_data to fill each struct element (data.max_value/data.min_value) with values from the simulation (max_val, min_val).
- The filled struct values are shown as output in the simulation (data_max_val_fill, data_min_val_fill).
Within sfunc_read_struct:
- Call call_fcn (read_struct.c).
- Within call_fcn, the get_fcn_return_element_one and get_fcn_return_element_two functions are called. The return value of these functions is one element of the previously filled struct, data.XXX. Therefore, these functions are called in a loop to request one index out of six from each struct element in data.XXX. Each value is saved in a new struct (data_out.max_value/data_out.min_value). The 'get' functions are part of 'fill_struct.c'.
- The received data is output to data_out.XXX in the simulation (data_from_fcn_1 and data_from_fcn_2).
The simulation output is used to check whether the data is written and read correctly. I also implemented two additional functions, get_fcn_show_call_max_value and get_fcn_show_call_min_value, in fill_struct.c. These functions return a fixed value for each index when they are called (the simulation output is show_call_fcn_1 and show_call_fcn_2).
Each S-function is placed in a subsystem to set an execution priority and ensure that fill_struct.c is called before read_struct.c.
The simulation time is set to a fixed, discrete step size of 0.01.
The problem I am facing is that the values in data_from_fcn_1 and data_from_fcn_2 are always 0.
Information is transmitted from Simulink_call_fill_data to data.max_value and data.min_value; I can always observe the correct values in the simulation output, data_max_val_fill and data_min_val_fill.
The first four functions within fill_struct.c must also be called, as I can see the fixed return values from get_fcn_show_call_max_value and get_fcn_show_call_min_value on the show_call_fcn_1 and show_call_fcn_2 simulation outputs.
However, the values in data_from_fcn_1 and data_from_fcn_2 remain 0.
My question is whether this kind of 'global data sharing' from two external C files is possible in a Simulink simulation.
If so, what do I need to consider to ensure that the correct values are displayed in data_from_fcn_1 and data_from_fcn_2?
//fill_struct.c
#include "fill_struct.h"
#include <stdint.h>
// Function which is called from other modul to get return value
int16_t get_fcn_return_element_one(int8_t id)
{
return data.max_value[id];
}
int16_t get_fcn_return_element_two(int8_t id)
{
return data.min_value[id];
}
int16_t get_fcn_show_call_max_value(int8_t id)
{
return 2;
}
int16_t get_fcn_show_call_min_value(int8_t id)
{
return 3;
}
int i;
void simulink_call_fill_data(int16_t max_val[6], int16_t min_val[6]) {
for (i = 0; i < 6; i++) {
data.max_value[i] = max_val[i];
data.min_value[i] = min_val[i];
}
}
// -------------------------------------------------------
//fill_struct.h
#include <stdint.h>
typedef short int16_t;
struct data_struct_st
{
int16_t max_value[6];
int16_t min_value[6];
}data;
void simulink_call_fill_data(int16_t max_val[6], int16_t min_val[6]);
int16_t get_fcn_return_element_one(int8_t id);
int16_t get_fcn_return_element_two(int8_t id);
int16_t get_fcn_show_call_max_value(int8_t id);
int16_t get_fcn_show_call_min_value(int8_t id);
// -------------------------------------------------------
//read_struct.c
#include "read_struct.h"
#include "fill_struct.h"
void call_fcn (){
int i ;
for (i=0; i<6u; i++)
{
data_out.max_value[i] = get_fcn_return_element_one(i);
data_out.min_value[i] = get_fcn_return_element_two(i);
data_out.show_call_max_value[i] = get_fcn_show_call_max_value(i);
data_out.show_call_min_value[i] = get_fcn_show_call_min_value(i);
}
}
// -------------------------------------------------------
//read_struct.h
#include <stdint.h>
struct read_struct {
int16_t max_value[6];
int16_t min_value[6];
int16_t show_call_max_value[6];
int16_t show_call_min_value[6];
}data_out;
void call_fcn();
0 件のコメント
採用された回答
shantanu
2025 年 8 月 13 日 13:38
Hi,
I understand that you are trying to write into “data.max_value” and “data.min_value” in one S-function block where data is a C-struct and then attempting to read the same from the same struct using another s function block. But on reading, you are getting outputs as zero which is not working as expected.
The “.c” and “.h” files you have provided are not declaring the struct ‘data’ as suited for you task. You have separately declared two structs ‘data’ in each so each c program would create its own copy of the struct data so I believe this might not be the way to write and read from the shared memory.
Here are some links you might find helpful for this task:
In the above link, DLL (Dynamic link library) for memory shared read-write is used which ensures the global variables can be easily accessed among different S-function blocks.
In the above link, similar use case is there so you can look at this as well.
In addition to this, you can also attempt to do this task using Data Store memory blocks or Dwork Vectors. Refer to the following documentation links to get more information:
DWork Vectors :
Data store memory blocks
Hope this information helps!
0 件のコメント
その他の回答 (0 件)
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!