Struct as output of a Matlab System

1 次查看(过去 30 天)
Hello,
I'm trying to develop a UART read and send driver block for a Raspberry Pi. To access the write and read commands writen in c, I use the Matlab System. The sending is working fine ( I write the inputs into a struct within matlab and pass a pointer to that struct to my external c function) and also the right values are recieved.
The Problem is that I can't get the output of the block working. The readfunction gives back a buffer (as struct). So I try create a struct in my Matlab System and write the buffer in it. Then I want to set my ouput of the block to that struct or pass the different values to my output variables.
Here is the Matlab System file: (The most important part is the Recieve Data Part (watch comments), where I call the pidata_parse function)
classdef UART_read_send < matlab.System ...
& coder.ExternalDependency ...
& matlab.system.mixin.Propagates ...
& matlab.system.mixin.CustomIcon
%
% System object template for a sink block.
%
% This template includes most, but not all, possible properties,
% attributes, and methods that you can implement for a System object in
% Simulink.
%
% NOTE: When renaming the class name Sink, the file name and
% constructor name must be updated to use the class name.
%
% Copyright 2014 The MathWorks, Inc.
%#codegen
%#ok<*EMCA>
properties
% Public, tunable properties.
end
properties (Hidden)
fd;
size;
packetID = 17;
end
properties (Nontunable)
% Public, non-tunable properties.
UART_init_Baudrate = 'B9600';
end
properties (Constant, Hidden)
AvailableBrate = ['B1200' 'B2400' 'B4800' 'B9600' 'B19200' 'B38400' 'B57600' 'B115200' 'B230400' 'B460800' 'B500000' 'B576000' 'B921600' 'B1000000' 'B1152000' 'B1500000' 'B2000000' 'B2500000' 'B3000000' 'B3500000' 'B4000000'];
end
properties (Access = private)
% Pre-computed constants.
end
methods
% Constructor
function obj = UART_read_send(varargin)
coder.allowpcode('plain');
% Support name-value pair arguments when constructing the object.
setProperties(obj,nargin,varargin{:});
end
end
methods (Access=protected)
function setupImpl(obj, u1, u2)
if coder.target('Rtw')
% Call C-function implementing device initialization
% coder.cinclude('sink.h');
% coder.ceval('sink_init');
coder.cinclude('uart.h');
obj.fd = -1;
obj.fd = coder.ceval('uart_init');
else
% Place simulation setup code here
end
end
function [out1, out2] = stepImpl(obj,u1,u2)
if coder.target('Rtw')
% Call C-function implementing device output
%Schreiben der Eingänge in den Sendestrukt
%Zum ändern von Eingängen muss ebenfalls das entsprechende Strukt in der pidata.h angepasst werden
send_struct = struct('velocity',u1,'heading',u2);
%Berechnen der Bytegröße der Eingänge
size_u1 = -1;
size_u2 = -1;
size_u1 = coder.ceval('sizeof', u1);
size_u2 = coder.ceval('sizeof', u2);
obj.size = size_u1 + size_u2;
%Include der Struct Definition im C-Code und abgleichen der Namen
coder.cinclude('piData.h');
coder.cstructname(send_struct, 'piData_toFluco_t', 'extern');
%Senden des struct
coder.ceval('pidata_send', obj.fd, obj.packetID, coder.ref(send_struct), obj.size);
%Recieve Data
rcv_struct = struct('velocity_RCV',single ([0;0;0]),'heading_RCV',single([0;0;0;0;0]));
coder.cstructname(rcv_struct, 'piData_fromFluco', 'extern');
rcv_struct = coder.ceval('pidata_parse', obj.fd);
out1 = rcv_struct.velocity_RCV;
out2 = rcv_struct.heading_RCV;
%out1 = rcv_struct;
%y2 = rcv_struct.heading_RCV;
else
% Place simulation output code here
end
end
function releaseImpl(obj)
if coder.target('Rtw')
% Call C-function implementing device termination
coder.ceval('uart_close', obj.fd);
else
% Place simulation termination code here
end
end
end
methods (Access=protected)
%Define input properties function num = getNumInputsImpl(~) num = 2; end
function flag = isInputSizeLockedImpl(~,~)
flag = true;
end
function varargout = isInputFixedSizeImpl(~,~)
varargout{1} = true;
varargout{2} = true;
end
function flag = isInputComplexityLockedImpl(~,~)
flag = true;
end
function varargout = isInputComplexImpl(~)
varargout{1} = false;
varargout{2} = false;
end
% Define output properties
function num = getNumOutputsImpl(~)
num = 2;
end
function [out1, out2] = outputImpl(obj, ~)
out1 = obj.PreviousInput(end);
out2 = obj.PreviousInput(end);
end
function flag = isOutputSizeLockedImpl(~,~)
flag = true;
end
function varargout = isOutputFixedSizeImpl(~,~)
varargout{1} = true;
varargout{2} = true;
end
function flag = isOutputComplexityLockedImpl(~,~)
flag = true;
end
function varargout = isOutputComplexImpl(~)
varargout{1} = false;
varargout{2} = false;
end
function varargout = getOutputSizeImpl(~)
% varargout{1} = propagatedInputSize(obj, 1);
varargout{1} = [3,1];
varargout{2} = [5,1];
end
function varargout = getOutputDataTypeImpl(~)
varargout{1} = 'single';
varargout{2} = 'single';
end
function icon = getIconImpl(~)
% Define a string as the icon for the System block in Simulink.
icon = 'Rpi_UART_read_send';
end
end
methods (Static, Access=protected)
function simMode = getSimulateUsingImpl(~)
simMode = 'Interpreted execution';
end
function isVisible = showSimulateUsingImpl
isVisible = false;
end
end
methods (Static)
function name = getDescriptiveName()
name = 'UART_read_send';
end
function b = isSupportedContext(context)
b = context.isCodeGenTarget('rtw');
end
function updateBuildInfo(buildInfo, context)
if context.isCodeGenTarget('rtw')
% Update buildInfo
rootDir = fullfile(fileparts(mfilename('fullpath')),'src');
buildInfo.addIncludePaths(rootDir);
% Use the following API's to add include files, sources and
% linker flags
addIncludeFiles(buildInfo,'piData.h','uart.h');
addSourceFiles(buildInfo,'piData.c',rootDir);
addSourceFiles(buildInfo,'uart.c',rootDir);
%addLinkFlags(buildInfo,{'-llibSink'});
end
end
end
end
The piData.h:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: piData.h
* Author: Michael
*
* Created on 19. Mai 2016, 16:04
*/
#ifndef PIDATA_H
#define PIDATA_H
#include <stdint.h>
#pragma once
// Einstellen, dass die Paket-Structs dicht (ohne Byte-Lücken) gepackt sind
#pragma pack(push, 1)
// ######################
// # Paket-Definitionen #
// ######################
typedef struct {
float velocity [3];
float heading [5];
} piData_toFluco_t;
typedef struct {
float velocity_RCV[3];
float heading_RCV[5];
} piData_fromFluco_t;
piData_toFluco_t piData_toFluco;
piData_fromFluco_t piData_fromFluco;
// Ende von >>#pragma pack(push, 1)<< siehe Oben.
#pragma pack(pop)
// Liest die über den auxiliary Datalink eingehenden Pakete ein
piData_fromFluco_t pidata_parse(int uartsocket);
// Sendet die auxiliary Datalink-Pakete
void pidata_send(int uartsocket, uint8_t packet_id, piData_toFluco_t* packet_ptr, uint8_t size);
#endif /* PIDATA_H */
When I try to run the simulation like this (Input is just 2 constant, one is 3x1 and one is 5x1) I get the following error message:
The build process will terminate as a result.
Error executing SSH command: make: Entering directory '/home/pi/Test_rtt'
"gcc" -I"./" -O3 -D"MODEL=Test" -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"ALLOCATIONFCN=0" -D"TID01EQ=0" -D"_USE_TARGET_UDP_=" -D"_RUNONTARGETHARDWARE_BUILD_=" -D"EXIT_FAILURE=1" -D"EXTMODE_DISABLETESTING=" -c ./linuxUDP.c ./ext_svr.c ./ext_work.c ./rtiostream_interface.c ./updown.c ./rtiostream_tcpip.c ./rtiostream_utils.c ./Test.c ./Test_data.c ./ert_main.c ./piData.c ./uart.c
./Test.c: In function ‘Test_outputâ€&trade;:
./Test.c:43:20: error: expected ‘;â€&trade; before ‘expl_tempâ€&trade;
./Test.c:73:3: error: ‘expl_tempâ€&trade; undeclared (first use in this function)
./Test.c:73:3: note: each undeclared identifier is reported only once for each function it appears in
_Test.mk:125: recipe for target 'linuxUDP.o' failed
make: *** [linuxUDP.o] Error 1
make: Leaving directory '/home/pi/Test_rtt'
In the end I just need to get the recieved files into the output of my System. Does anyone has an idea how I could do that.
Edit: If I don't include the out1 = rcv_struct.velocity_RCV; and out2 = rcv_struct.heading_RCV; call, the simulation runs without any errors on the pi, but also without any outputs of the System block.
Cheers Michael

回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Programming Utilities 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by