Simulink: Read a file on RaspberryPi in external Mode [error: unknown type name ‘FILE’]

3 views (last 30 days)
Hello Community, I have a RPI that is reading sensorvalues from another board by I2C. Now I want to send the data to the scope. I searched around the forum, and found an entry where somebody wanted to achieve the same. He used the following code:
function y = fcn()
%#codegen
persistent pf;
pf = coder.opaque('FILE *');
y = coder.nullcopy(uint8(0));
res = coder.nullcopy(uint8(zeros(1, 10)));
readOnly = c_string('r');
readCmd = c_string(['i2cget -y 0 0x06 49']);
if isequal(coder.target, 'rtw')
pf = coder.ceval('popen', coder.rref(readCmd), coder.rref(readOnly));
coder.ceval('fgets', coder.wref(res), 10, pf);
coder.ceval('printf', c_string('%s'), c_string(res));
end
end
function str = c_string(str)
% Convert MATLAB string to C-string by adding a string termination
% character
str = [str, 0];
end
I get the following error, when using it:
The call to realtime_make_rtw_hook, during the after_make hook generated the following error:
Error executing SSH command: make: Entering directory `/home/pi/rpi_i2c_fcn_rtt'
"gcc" -I"./" -O3 -D"MODEL=rpi_i2c_fcn" -D"NUMST=1" -D"NCSTATES=0" -D"HAVESTDIO=" -D"ON_TARGET_WAIT_FOR_START=1" -D"ONESTEPFCN=0" -D"EXT_MODE=1" -D"TERMFCN=1" -D"MAT_FILE=0" -D"MULTI_INSTANCE_CODE=0" -D"INTEGER_CODE=0" -D"MT=0" -D"CLASSIC_INTERFACE=0" -D"TID01EQ=0" -D"_USE_TARGET_UDP_=" -D"_RUNONTARGETHARDWARE_BUILD_=" -c ./linuxUDP.c ./ext_svr.c ./ext_work.c ./rtiostream_interface.c ./updown.c ./rtiostream_tcpip.c ./rtiostream_utils.c ./ert_main.c ./rpi_i2c_fcn.c
./rpi_i2c_fcn.c: In function ‘rpi_i2c_fcn_output’:
./rpi_i2c_fcn.c:11:1: error: unknown type name ‘FILE’
./rpi_i2c_fcn.c:11:16: warning: assignment makes pointer from integer without a cast [enabled by default]
make: make: Leaving directory `/home/pi/rpi_i2c_fcn_rtt'
*** [linuxUDP.o] Error 1
The build process will terminate as a result.
Caused by:
Error executing SSH command: make: Entering directory `/home/pi/rpi_i2c_fcn_rtt'
"gcc" -I"./" -O3 -D"MODEL=rpi_i2c_fcn" -D"NUMST=1" -D"NCSTATES=0" -D"HAVESTDIO=" -D"ON_TARGET_WAIT_FOR_START=1" -D"ONESTEPFCN=0" -D"EXT_MODE=1" -D"TERMFCN=1" -D"MAT_FILE=0" -D"MULTI_INSTANCE_CODE=0" -D"INTEGER_CODE=0" -D"MT=0" -D"CLASSIC_INTERFACE=0" -D"TID01EQ=0" -D"_USE_TARGET_UDP_=" -D"_RUNONTARGETHARDWARE_BUILD_=" -c ./linuxUDP.c ./ext_svr.c ./ext_work.c ./rtiostream_interface.c ./updown.c ./rtiostream_tcpip.c ./rtiostream_utils.c ./ert_main.c ./rpi_i2c_fcn.c
./rpi_i2c_fcn.c: In function ‘rpi_i2c_fcn_output’:
./rpi_i2c_fcn.c:11:1: error: unknown type name ‘FILE’
./rpi_i2c_fcn.c:11:16: warning: assignment makes pointer from integer without a cast [enabled by default]
make: make: Leaving directory `/home/pi/rpi_i2c_fcn_rtt'
*** [linuxUDP.o] Error 1
I am using the studentversion of Matlab R2013a, could this be the problem?
Thanks for helping! Max

Answers (1)

Ryan Livingston
Ryan Livingston on 3 Feb 2014
Edited: Ryan Livingston on 3 Feb 2014
Nice to see someone using the RaspberryPi like this.
Two issues: you need to include stdio.h (for the definition of popen and the type FILE) and you'll likely run into the problem described in:
You can add:
coder.cinclude('<stdio.h>');
to your source code to include stdio.h.
Not defining _XOPEN_SOURCE or related as that post describes causes the C compiler to assume that popen returns an integer which you are then assigning to a FILE *, so it complains.
To follow the suggestion of defining _XOPEN_SOURCE to 500 you could update the build settings in "Simulation -> Model configuration parameters -> Code generation". Copy the TMF file you are using somewhere you can edit it:
copyfile([matlabroot '/rtw/c/grt/grt_unix.tmf'],'./grt_posix.tmf')
if you were using the grt default TMF file. In this file add a preprocessor define
-D_XOPEN_SOURCE=500
(or whatever you need) to a line like:
CPP_REQ_DEFINES = -DMODEL=$(MODEL) -DRT -DNUMST=$(NUMST) \
-DTID01EQ=$(TID01EQ) -DNCSTATES=$(NCSTATES) -DUNIX \ ...
Finally enter the path to your new file in the "Template makefile" box in configuration parameters.
Also, are you passing a uint8 array to FGETS intentionally? You may consider allocating a character array instead:
res = coder.nullcopy(blanks(10));
as passing an unsigned array may cause the compiler to complain again.
Lastly, you may want to consider passing an appropriate integer type for the second argument of FGETS as it expects an int:
In MATLAB writing 10 means a double with the value of 10 (similar to 10.0 in C). So passing something like int32(10) (or whatever matches int on the Pi) could be preferable.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!