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’:
./Test.c:43:20: error: expected ‘;’ before ‘expl_temp’
./Test.c:73:3: error: ‘expl_temp’ 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 个评论
回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Programming Utilities 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!