This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Simulink里创建SCI通讯模块,错误:索引超出矩阵维度

求大神指教。

在MATLAB/Simulink里创建了SCI通讯的transmit和Receive模块,希望在目标板F28035的串口上收到数据后原原本本的再发送回来,在主机的串口调试助手上可以实现发送的内容再接收回来。如下图所示。F28035,SCI transmit,SCI receive都已配置好。

使用串口COM4

编译之后出现错误如下:

根据错误信息提示,我打开了c200hostsci_rx.m文件,PostPropagationSetup也找到具体位置,但是不知道该怎么修改。

c200hostsci_rx.m源码如下:

function c2000hostsci_rx(block)
% S-function for Host side serial receive block
%
%  See also C2000HOSTSCI_TX

% Copyright 2006-2013 The MathWorks, Inc.

setup(block);
  
%endfunction

%% Function: setup ===================================================
%% Abstract:
%%   Set up the S-function block's basic characteristics such as:
%%   - Input ports
%%   - Output ports
%%   - Dialog parameters
%%   - Options
%% 
%%   Required         : Yes
%%   C-Mex counterpart: mdlInitializeSizes
%%
function setup(block)
  datatypeID = block.DialogPrm(4).Data;
  dataLenPrm = block.DialogPrm(5);
  sampletimes = [block.DialogPrm(9).Data, 0];
  outputStatus = block.DialogPrm(10).Data;

  if isequal(dataLenPrm.Dimensions, [ 1 1 ])
      outputDims = dataLenPrm.Data;
  else
      DAStudio.error('TIC2000:blocks:SCIHostRxDataLength');
  end

  % Register number of ports
  block.NumInputPorts  = 0;
  if outputStatus == 1 %output receiving status
      block.NumOutputPorts = 2;
  else
      block.NumOutputPorts = 1;
  end
  
  % Setup port properties to be inherited or dynamic
  block.SetPreCompOutPortInfoToDynamic;
  
  % Override output port properties
  block.OutputPort(1).DatatypeID   = datatypeID;
  block.OutputPort(1).Complexity   = 'Real';
  block.OutputPort(1).SamplingMode = 'Sample';
  block.OutputPort(1).Dimensions   = outputDims;

  if block.NumOutputPorts == 2
      block.OutputPort(2).DatatypeID   = 0;
      block.OutputPort(2).Complexity   = 'Real';
      block.OutputPort(2).SamplingMode = 'Sample';
      block.OutputPort(2).Dimensions   = 1;
  end

  % Register parameters
  block.NumDialogPrms     = 10;
  block.DialogPrmsTunable = {'Nontunable', 'Nontunable', 'Nontunable', 'Nontunable', 'Nontunable', 'Nontunable', 'Nontunable','Nontunable', 'Nontunable', 'Nontunable'};

  % Register sample times
  %  [0 offset]            : Continuous sample time
  %  [positive_num offset] : Discrete sample time
  %
  %  [-1, 0]               : Port-based sample time
  %  [-2, 0]               : Variable sample time
  block.SampleTimes = sampletimes;
  
  %% -----------------------------------------------------------------
  %% Options
  %% -----------------------------------------------------------------
  % Specify if Accelerator should use TLC or call back into 
  % MATLAB file
  block.SetAccelRunOnTLC(false);
  
  %% -----------------------------------------------------------------
  %% Register methods called during update diagram/compilation
  %% -----------------------------------------------------------------
  
  %% 
  %% CheckParameters:
  %%   Functionality    : Called in order to allow validation of
  %%                      block's dialog parameters. User is 
  %%                      responsible for calling this method
  %%                      explicitly at the start of the setup method
  %%   C-Mex counterpart: mdlCheckParameters
  %%
  block.RegBlockMethod('CheckParameters', @CheckPrms);

  %%
  %% PostPropagationSetup:
  %%   Functionality    : Setup work areas and state variables. Can
  %%                      also register run-time methods here
  %%   C-Mex counterpart: mdlSetWorkWidths
  %%
  block.RegBlockMethod('PostPropagationSetup', @DoPostPropSetup);

  %% -----------------------------------------------------------------
  %% Register methods called at run-time
  %% -----------------------------------------------------------------
  
  %% 
  %% ProcessParameters:
  %%   Functionality    : Called in order to allow update of run-time
  %%                      parameters
  %%   C-Mex counterpart: mdlProcessParameters
  %%  
  block.RegBlockMethod('ProcessParameters', @ProcessPrms);

  %% 
  %% Start:
  %%   Functionality    : Called in order to initialize state and work
  %%                      area values
  %%   C-Mex counterpart: mdlStart
  %%
  block.RegBlockMethod('Start', @Start);

%endfunction

%% -------------------------------------------------------------------
%% The local functions below are provided for illustrative purposes
%% to show how you may implement the various block methods listed
%% above.
%% -------------------------------------------------------------------

function CheckPrms(block)
  
%endfunction

function ProcessPrms(block)

  block.AutoUpdateRuntimePrms;
 
%endfunction
    
function DoPostPropSetup(block)
  
  setupBlk = find_system(bdroot, 'FollowLinks', 'on', 'MaskType','c2000 Host SCI Setup');

  switch block.DialogPrm(1).Data
  case 1
      commMode   = get_param(setupBlk, 'commModeA');
  case 2
      commMode   = get_param(setupBlk, 'commModeB');
  case 3
      commMode   = get_param(setupBlk, 'commModeC');
  case 4
      commMode   = get_param(setupBlk, 'commModeD');
  end

  %== Register method for Outputs function =========================
  switch commMode{1}
  case 'protocol'
    block.RegBlockMethod('Outputs', @ProOutputs);
  case 'raw data'
    block.RegBlockMethod('Outputs', @RawOutputs);
  end

  %== Restore serial port id and error output value to Dwork space ==
  block.NumDworks = 2;
  block.Dwork(1).Name            = 'InstrID';
  block.Dwork(1).Dimensions      = 1;
  block.Dwork(1).DatatypeID      = 0;      %double
  block.Dwork(1).Complexity      = 'Real'; % real
  
  block.Dwork(2).Name            = 'ErrorValue';
  block.Dwork(2).Dimensions      = block.OutputPort(1).Dimensions;
  block.Dwork(2).DatatypeID      = block.OutputPort(1).DatatypeID;
  block.Dwork(2).Complexity      = 'Real'; % real

%endfunction


function Start(block)
    
    %== Get Serial port ID and store it in to Dwork(1) ==============
    setupBlk = find_system(bdroot, 'FollowLinks', 'on', ...
                            'MaskType','c2000 Host SCI Setup');
    
    userdata = get_param(setupBlk{1}, 'userdata');
    
    moduleID =  block.DialogPrm(1).Data;
    
    block.Dwork(1).Data = userdata.serialID(moduleID);

    %== Setup initial output value & error output value ==============
    datatype    = class(block.OutputPort(1).Data);
    initPrm     = block.DialogPrm(6);
    errValuePrm = block.DialogPrm(8);
    
    if isequal(initPrm.Dimensions, [1 block.OutputPort(1).Dimensions])
        initValue = cast(initPrm.Data, datatype);
    elseif isequal(initPrm.Dimensions, [1 1])
        initValue = ones(1, block.OutputPort(1).Dimensions) .* initPrm.Data;
        initValue = cast(initValue, datatype);
    else
        DAStudio.error('TIC2000:blocks:SCIHostRxInitDimension');
    end
    block.OutputPort(1).Data = initValue;
    
    if isequal(errValuePrm.Dimensions, [1 block.OutputPort(1).Dimensions])
        errValue = cast(errValuePrm.Data, datatype);
    elseif isequal(errValuePrm.Dimensions, [1 1])
        errValue = ones(1, block.OutputPort(1).Dimensions) .* errValuePrm.Data;
        errValue = cast(errValue, datatype);
    else
        DAStudio.error('TIC2000:blocks:SCIHostRxTimeoutDimension');
    end
    block.Dwork(2).Data = errValue;
%endfunction

%%
%% Outputs function for raw data mode
%%
function RawOutputs(block)

    try
        com = instrfind('id', block.Dwork(1).Data);
        head = uint8(block.DialogPrm(2).Data);
        tail = uint8(block.DialogPrm(3).Data);
        dataDim = block.DialogPrm(5).Data;
        dataType =  block.DialogPrm(4).Data; 

        switch dataType
        case {1, 6, 7}      %single, int32, uint32
            typeDim = 4;
        case {2, 3}         %int8, uint8
            typeDim = 1;
        case {4, 5}         %int16, uint16
            typeDim = 2;
        end

        dataLen = dataDim*typeDim;
        
        t0 = clock;
        tmax = com.Timeout;
        %== check head ================================%
        if length(head)
            cnt = 1;
            while (cnt <= length(head))
                recHead = fread(com, 1, 'uint8');
                if recHead == head(cnt)
                    cnt = cnt+1;
                else
                    cnt = 1;
                end
                if(etime(clock, t0) > tmax)
                    break;
                end
            end
            if cnt > length(head)
                rcvStat = 0;
            else
                rcvStat = 1;
            end
        else
            rcvStat = 0;
        end
        
        %== get data ==================================%
        if rcvStat == 0
            while(com.BytesAvailable < dataLen) %wait until data arrived
                if(etime(clock, t0) > tmax)
                    rcvStat = 1; %timeout
                    break;
                end
            end
            if (com.BytesAvailable >= dataLen)
                recbuff = uint8(fread(com, dataLen, 'uchar'));
                outdata = c2char2num(recbuff, dataType, dataDim);
            else %
                rcvStat = 1;
            end
        end
        
        %== check tail ================================%
        if rcvStat == 0 && length(tail)
            while(com.BytesAvailable < length(tail))
                if(etime(clock, t0) > tmax)
                    rcvStat = 1;
                    break;
                end
            end
            
            if(com.BytesAvailable >= length(tail))
                rcvTail = uint8(fread(com, length(tail))');
                if (isequal(rcvTail, tail))
                    rcvStat = 0;
                else
                    rcvStat = 2;
                end
            end
        end

        %== Output received data ======================%
        if rcvStat == 0
            block.OutputPort(1).Data = outdata;
        elseif block.DialogPrm(7).Data == 2
            block.OutputPort(1).Data = block.Dwork(2).Data;
        end
        if block.NumOutputPorts == 2
            block.OutputPort(2).Data = rcvStat;
        end

    catch ME
        fclose(com);
        ME.rethrow;
    end
%endfunction

%%
%% Output function for protocol mode
%% 
function ProOutputs(block)

dataType =  block.DialogPrm(4).Data; 

switch dataType
case {1, 6, 7}      %single, int32, uint32
    typeDim = 4;
case {2, 3}         %int8, uint8
    typeDim = 1;
case {4, 5}         %int16, uint16
    typeDim = 2;
end

dataDim = block.DialogPrm(5).Data;
dataLen = dataDim * typeDim;
try
    com = instrfind('id', block.Dwork(1).Data);
    t0 = clock;
    tmax = com.Timeout;
    while(1)
        if(com.BytesAvailable)
            rcvPkg = fread(com, com.BytesAvailable, 'uchar');
            rcvPkg = rcvPkg(end);
        else 
            rcvPkg = fread(com, 1);
        end

        if (rcvPkg == 's')
            try
                fwrite(com, 'r');
            catch ME
                if isempty(strfind( ME.identifier, 'blocks:SCIHostTxWriteTimeout'))
                    ME.rethrow;
                else
                    fwrite(com, 'r');
                end
            end
            
            while(1) % get the head of data package
                rcvPkg = fread(com, 1);
                if(rcvPkg == 'd')
                    break;
                elseif(etime(clock, t0) > tmax)
                    DAStudio.error('TIC2000:blocks:SCIHostRxReadTimeout');
                end
            end

            while(com.BytesAvailable < dataLen+1) %wait until all data arrived
                if(etime(clock, t0) > tmax)
                    fread(com, com.BytesAvailable); %clear receive buffer
                    DAStudio.error('TIC2000:blocks:SCIHostRxReadTimeout');
                end
            end
            
            recbuff = uint8(fread(com, dataLen+1, 'uchar'));
            if(~tchecksum(recbuff))
                block.OutputPort(1).Data = c2char2num(recbuff(1:end-1), dataType, dataDim);
                if block.NumOutputPorts == 2
                    block.OutputPort(2).Data = 0;
                end
                break;
            elseif block.DialogPrm(7).Data == 2 
                %data error, output error value
                block.OutputPort(1).Data = block.Dwork(2).Data;
                if block.NumOutputPorts == 2
                    block.OutputPort(2).Data = 2;
                end
                break;
            else
                if block.NumOutputPorts == 2
                    block.OutputPort(2).Data = 2;
                end
                break;
            end
        end
        
        if (etime(clock, t0) > tmax)
%%            DAStudio.error('TIC2000:blocks:SCIHostRxReadTimeout');
            break;
        end
    end
    
catch ME
    if(isempty(strfind(ME.message, 'sci_rx_timeout')))
        fclose(com);
        ME.rethrow;
    else %timeout
        if block.DialogPrm(7).Data == 2
            %output error value
            block.OutputPort(1).Data = block.Dwork(2).Data;
        end
        if block.NumOutputPorts == 2
            block.OutputPort(2).Data = 1;
        end
    end
end
%endfunction

这个问题困扰了我好几天,实在不知道怎么解决,谢谢各位大神了!