Centralized Approach to Defining Block Libraries

Overview of how to define the parameters for a wrapper block.

Wrapper blocks are made of a GenericWrapperBlock placed inside a super block (with possibly other blocks). The GenericWrapperBlock block parameters, params and sysparams, must be defined for each wrapper block. Instead of defining them inside the corresponding wrapper block, it is recommended to define an OML library function with the following calling sequence:

[params, sysparams] = MyTargetLIB(blockID,_params)

  • blockID: A string identifying the block; may use the name of the wrapper block in the library.
  • _params: Structure containing the mask parameters and their values of the wrapper block. The variable _params inside the context of a masked super block already contains the mask parameters and their values.
  • params and sysparams: OML structures containing block-level and system-level code snippets associated with their keywords, for the block corresponding to the block blockID. The code snippet might, and often does, depend on the wrapper block parameters.

Consider, for example, the digitalRead Wrapper block from the RaspberryPi library.



This block has a single parameter, PinNumber. It is a super block containing a GenericWrapperBlock, as shown in the image below.



The params for this block (sysparams is empty for this block) are obtained from the OML library of the target. params is defined in the library as follows:
function [params, sysparams] = RaspberryPiWrapperLIB(blockID,_params)
  switch blockID
    case….
    case 'digitalRead'
      pin =  _params.PinNumber; 
      if pin<1 || pin>40 , error(‘Incorrect pin number.’); end 
      params=struct('PreCallString' , ['  $$1[0] = gpioRead(', num2str(pin) , ');'] , ...
               'PreCallStringInit' , ['gpioSetMode(' , num2str(_params.PinNumber) , ' , ' , 'PI_INPUT);'])
    case…
end

This Wrapper block places two code snippets in main.c corresponding to keywords 'PreCallString' and 'PreCallStringInit.' The first one is placed in main.c before calling the body step API. The latter is placed earlier to initialize the port. Both snippets depend on the wrapper block parameter PinNumber. The block does not define anything at the system level.

The keywords can be chosen freely by the target library developer, as long as the OML library file and the code generator agree on their meanings. However, it is recommended to use the following keywords as much as possible:
  • AllocateString
  • EndString
  • PostEndString
  • StartString
  • PostStartString
  • Include
  • PreCallString
  • PostCallString
  • localDeclarationStrings
  • PostPreCallString
  • PrePostCallString

Each keyword indicates the location where the corresponding code snippet is placed in the file main.c. If needed, new targets can define and use other keywords.