{"id":13,"date":"2008-05-07T21:30:49","date_gmt":"2008-05-08T02:30:49","guid":{"rendered":"https:\/\/blogs.mathworks.com\/seth\/2008\/05\/07\/bus-signals-in-the-generated-code\/"},"modified":"2008-05-07T22:05:57","modified_gmt":"2008-05-08T03:05:57","slug":"bus-signals-in-the-generated-code","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/simulink\/2008\/05\/07\/bus-signals-in-the-generated-code\/","title":{"rendered":"Bus Signals in the Generated Code"},"content":{"rendered":"<p>Blog reader <a\r\nhref=\"https:\/\/blogs.mathworks.com\/seth\/2008\/04\/11\/how-do-you-think-about-virtual-buses\/#comment-150\">Paul\r\nJ. shared<\/a> with us his mental model of the bus as a structure.  While this\r\nisn\u2019t true of virtual buses, it is precisely true of nonvirtual buses.  In\r\nfact, when you generate the code for a nonvirtual bus using <a\r\nhref=\"https:\/\/www.mathworks.com\/products\/rtw\/\">Real-Time Workshop<\/a>, the\r\nresult is a structure.<\/p>\r\n\r\n<p><strong>Focus on the boundaries<\/strong><\/p>\r\n\r\n<p>In a <a\r\nhref=\"https:\/\/blogs.mathworks.com\/seth\/2008\/04\/29\/nonvirtual-bus-signals\/\">previous\r\npost about nonvirtual bus signals<\/a> I talked about memory allocated for the\r\nbus.  The places we have to think about memory allocation are the boundaries of\r\nsystems.  Here is the <a href=\"https:\/\/blogs.mathworks.com\/images\/seth\/2008Q2\/simplebusdemo_nv.mdl\">simplebusdemo_nv.mdl<\/a><\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2008Q2\/simplebusdemo_nv_diag.png\" \r\nalt=\"Simple bus demo diagram with a nonvirtual bus\"><\/p>\r\n\r\n<p>This model has the root level boundaries defined by the\r\ninport and outport blocks.  It also has a boundary at the edge of the ReusableFcn\r\nsubsystem.  The main_bus crosses this boundary and the generated code is\r\ndifferent if the bus is virtual versus nonvirtual.<\/p>\r\n\r\n<p>The ReusableFcn subsystem contains a Bus Selector and two\r\ngain blocks.<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2008Q2\/ReusableFcn_nv_diag.png\"\r\nalt=\"ReusableFcn subsystem with nonvirtual bus input\"><\/p>\r\n\r\n<p>I configured the subsystem to generate a reusable function. \r\nHere are the settings for the subsystem:<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2008Q2\/ReusableFcn_SubsysParam.png\"\r\nalt=\"ReusableFcn subsystem parameters\"><\/p>\r\n\r\n<p>Basically, I have specified how Real-Time Workshop should\r\nwrap up the algorithm implemented inside this system.  By specifying \u201cTreat as\r\natomic unit\u201d, the blocks inside the system execute together.  Real-Time\r\nWorkshop will generate reusable function code with my specified name\r\n(ReusableFcn) into a file of the same name (ReusableFcn.c).  The reusable\r\nfunction code will pass input and output signals as arguments to the function. \r\n<\/p>\r\n\r\n<p>I can now picture what this will look like:<\/p>\r\n\r\n<p><PRE>ReusableFcn(inputs..., outputs...)<\/PRE><\/p>\r\n\r\n<p><strong>Virtual buses pass every element separately<\/strong><\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2008Q2\/ReusableFcn_vir_diag.png\"\r\nalt=\"ReusableFcn subsystem with virtual bus input\"><\/p>\r\n\r\n<p>When the bus signal is virtual at the inport to the\r\nReusableFcn, only the elements of the bus that are used in the system need to\r\nbe passed through the boundary.  Here is the actual code for the function call:<\/p>\r\n\r\n<STYLE> .LN { font-style: italic; color: #888888 } <\/STYLE>\r\n<STYLE> .CT { font-style: italic; color: #117755 } <\/STYLE>\r\n<STYLE> .PP { font-style: bold;   color: #992211 } <\/STYLE>\r\n<STYLE> .KW { font-style: bold;   color: #112266 } <\/STYLE>\r\n<STYLE> .DT { font-style: bold;   color: #112266 } <\/STYLE>\r\n\r\n<PRE><SPAN class=\"LN\">30 <\/SPAN>  <SPAN class=\"CT\">\/* Outputs for atomic SubSystem: '&lt;Root&gt;\/ReusableFcn' *\/<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">31 <\/SPAN>  ReusableFcn(simplebusdemo_vir_U.Pulse, simplebusdemo_vir_U.Chirp,\r\n<\/SPAN><SPAN><SPAN class=\"LN\">32 <\/SPAN>              &amp;simplebusdemo_vir_B.ReusableFcn_m);\r\n<\/SPAN><SPAN><SPAN class=\"LN\">33 <\/SPAN><\/code><\/PRE>\r\n\r\n<p>Notice, there is no evidence in the code that a bus signal\r\nexists.  At compile-time, direct connections between sources and destinations\r\nreplace the virtual bus.<\/p>\r\n\r\n<PRE><\/SPAN><SPAN><SPAN class=\"LN\">19 <\/SPAN><SPAN class=\"CT\">\/* Output and update for atomic system: '&lt;Root&gt;\/ReusableFcn' *\/<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">20 <\/SPAN><SPAN class=\"DT\">void<\/SPAN> ReusableFcn(real32_T rtu_0, real_T rtu_1, rtB_ReusableFcn *localB)\r\n<\/SPAN><SPAN><SPAN class=\"LN\">21 <\/SPAN><B>{<\/B>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">22 <\/SPAN>  <SPAN class=\"CT\">\/* Gain: '&lt;S1&gt;\/Gain' *\/<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">23 <\/SPAN>  localB-&gt;Gain = 2.0F * rtu_0;\r\n<\/SPAN><SPAN><SPAN class=\"LN\">24 <\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">25 <\/SPAN>  <SPAN class=\"CT\">\/* Gain: '&lt;S1&gt;\/Gain1' *\/<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">26 <\/SPAN>  localB-&gt;Gain1 = 3.0 * rtu_1;\r\n<\/SPAN><SPAN><SPAN class=\"LN\">27 <\/SPAN><B>}<\/B>\r\n<\/SPAN><\/PRE>\r\n\r\n<p><strong>Nonvirtual buses are structures<\/strong><\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2008Q2\/ReusableFcn_nv_diag.png\"\r\nalt=\"ReusableFcn subsystem with nonvirtual bus input\"><\/p>\r\n\r\n<p>The nonvirtual bus is a contiguous block of memory.  This is\r\nassembled and passed into the ReusableFcn.<\/p>\r\n\r\n<PRE><SPAN class=\"LN\">30 <\/SPAN>  <SPAN class=\"CT\">\/* local block i\/o variables *\/<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">31 <\/SPAN>  main_bus rtb_main_bus;\r\n<\/SPAN><SPAN><SPAN class=\"LN\">32 <\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">33 <\/SPAN>  <SPAN class=\"CT\">\/* BusCreator: '&lt;Root&gt;\/Bus Creator' incorporates:<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">34 <\/SPAN><SPAN class=\"CT\">   *  BusCreator: '&lt;Root&gt;\/BusConversion_InsertedFor_Bus Creator_at_inport_0'<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">35 <\/SPAN><SPAN class=\"CT\">   *  BusCreator: '&lt;Root&gt;\/BusConversion_InsertedFor_Bus Creator_at_inport_1'<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">36 <\/SPAN><SPAN class=\"CT\">   *  Inport: '&lt;Root&gt;\/In1'<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">37 <\/SPAN><SPAN class=\"CT\">   *  Inport: '&lt;Root&gt;\/In2'<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">38 <\/SPAN><SPAN class=\"CT\">   *  Inport: '&lt;Root&gt;\/In3'<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">39 <\/SPAN><SPAN class=\"CT\">   *  Inport: '&lt;Root&gt;\/In4'<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">40 <\/SPAN><SPAN class=\"CT\">   *  Inport: '&lt;Root&gt;\/In5'<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">41 <\/SPAN><SPAN class=\"CT\">   *\/<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">42 <\/SPAN>  rtb_main_bus.bus1.Chirp = simplebusdemo_nv_U.Chirp;\r\n<\/SPAN><SPAN><SPAN class=\"LN\">43 <\/SPAN>  rtb_main_bus.bus1.Constant[0] = simplebusdemo_nv_U.Constant[0];\r\n<\/SPAN><SPAN><SPAN class=\"LN\">44 <\/SPAN>  rtb_main_bus.bus1.Constant[1] = simplebusdemo_nv_U.Constant[1];\r\n<\/SPAN><SPAN><SPAN class=\"LN\">45 <\/SPAN>  rtb_main_bus.bus1.Constant[2] = simplebusdemo_nv_U.Constant[2];\r\n<\/SPAN><SPAN><SPAN class=\"LN\">46 <\/SPAN>  rtb_main_bus.bus2.Clock = simplebusdemo_nv_U.Clock;\r\n<\/SPAN><SPAN><SPAN class=\"LN\">47 <\/SPAN>  rtb_main_bus.bus2.Pulse = simplebusdemo_nv_U.Pulse;\r\n<\/SPAN><SPAN><SPAN class=\"LN\">48 <\/SPAN>  rtb_main_bus.bus2.Sine[0] = simplebusdemo_nv_U.Sine[0];\r\n<\/SPAN><SPAN><SPAN class=\"LN\">49 <\/SPAN>  rtb_main_bus.bus2.Sine[1] = simplebusdemo_nv_U.Sine[1];\r\n<\/SPAN><SPAN><SPAN class=\"LN\">50 <\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">51 <\/SPAN>  <SPAN class=\"CT\">\/* Outputs for atomic SubSystem: '&lt;Root&gt;\/ReusableFcn' *\/<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">52 <\/SPAN>  ReusableFcn(&amp;rtb_main_bus, &amp;simplebusdemo_nv_B.ReusableFcn_a);\r\n<\/SPAN><\/PRE>\r\n\r\n<p>Each of the input signals is being copied into the\r\nrtb_main_bus variable, which is an instance of the main_bus type.  This\r\nstructure matches the bus object definition specified by main_bus, bus1, and\r\nbus2.<\/p>\r\n\r\n<p>I notice that the ReusableFcn has a shorter interface.  Now\r\nthe only input signal is a pointer to the rtb_main_bus, which is allocated\r\nlocally.<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2008Q2\/ReusableFcn_nv_diag.png\"\r\nalt=\"ReusableFcn subsystem with nonvirtual bus input\"><\/p>\r\n\r\n<PRE><SPAN class=\"LN\">19 <\/SPAN><SPAN class=\"CT\">\/* Output and update for atomic system: '&lt;Root&gt;\/ReusableFcn' *\/<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">20 <\/SPAN><SPAN class=\"DT\">void<\/SPAN> ReusableFcn(<SPAN class=\"DT\">const<\/SPAN> main_bus *rtu_In1, rtB_ReusableFcn *localB)\r\n<\/SPAN><SPAN><SPAN class=\"LN\">21 <\/SPAN><B>{<\/B>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">22 <\/SPAN>  <SPAN class=\"CT\">\/* Gain: '&lt;S1&gt;\/Gain' *\/<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">23 <\/SPAN>  localB-&gt;Gain = 2.0F * (*rtu_In1).bus2.Pulse;\r\n<\/SPAN><SPAN><SPAN class=\"LN\">24 <\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">25 <\/SPAN>  <SPAN class=\"CT\">\/* Gain: '&lt;S1&gt;\/Gain1' *\/<\/SPAN>\r\n<\/SPAN><SPAN><SPAN class=\"LN\">26 <\/SPAN>  localB-&gt;Gain1 = 3.0 * (*rtu_In1).bus1.Chirp;\r\n<\/SPAN><SPAN><SPAN class=\"LN\">27 <\/SPAN><B>}<\/B>\r\n<\/SPAN><\/PRE>\r\n\r\n<p>In the case of nonvirtual bus signals, the concept of\r\ninterface specification using the bus object carries all the way down to the\r\ngenerated code. <\/p>\r\n\r\n<p><strong>Now it\u2019s your turn<\/strong><\/p>\r\n\r\n<p>We have now covered most of the important topics on bus\r\nsignals.  What questions remain about bus signals and their use in your models?\r\nPost a <a href=\"https:\/\/blogs.mathworks.com\/seth\/?p=13&amp;#comment\">comment\r\nhere<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Blog reader Paul\r\nJ. shared with us his mental model of the bus as a structure.  While this\r\nisn\u2019t true of virtual buses, it is precisely true of nonvirtual buses.  In\r\nfact, when you generate the... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/simulink\/2008\/05\/07\/bus-signals-in-the-generated-code\/\">read more >><\/a><\/p>","protected":false},"author":40,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[21,11],"tags":[12,23,20,22,444,441],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/13"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/users\/40"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/comments?post=13"}],"version-history":[{"count":0,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/13\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/media?parent=13"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/categories?post=13"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/tags?post=13"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}