<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.element14.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Forum - Recent Threads</title><link>https://community.element14.com/products/devtools/software/f/forum</link><description /><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><lastBuildDate>Mon, 15 Jul 2024 09:44:56 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://community.element14.com/products/devtools/software/f/forum" /><item><title>GitHub: automate Raspberry Pico project build verification with GitHub Actions</title><link>https://community.element14.com/thread/54818?ContentTypeID=0</link><pubDate>Mon, 15 Jul 2024 09:44:56 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:74c26e56-04b1-4b10-ace7-c8f788accf64</guid><dc:creator>Jan Cumps</dc:creator><slash:comments>1</slash:comments><comments>https://community.element14.com/thread/54818?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/54818/github-automate-raspberry-pico-project-build-verification-with-github-actions/rss?ContentTypeId=0</wfw:commentRss><description>&lt;h1&gt;&lt;span style="background-color:#ff0000;"&gt;Moved to&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/technologies/code_exchange/b/blog/posts/github-automate-raspberry-pico-project-build-verification-with-github-actions"&gt;GitHub: automate Raspberry Pico project build verification with GitHub Actions&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;You can Make GitHub build your project.&amp;nbsp;I&amp;#39;m using an Action to check out branches and build them, when a pull request is submitted. &lt;br /&gt;I adapted an existing flow from the Raspberry organisation. Here&amp;#39;s what it does&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;check out the branch that&amp;#39;s the source&amp;nbsp;for the pull request&lt;/li&gt;
&lt;li&gt;check out Pico-SDK, the&amp;nbsp;current development branch&lt;/li&gt;
&lt;li&gt;install CMake&lt;/li&gt;
&lt;li&gt;install the arm bare metal GNU toolchain&lt;/li&gt;
&lt;li&gt;build the SDK&lt;/li&gt;
&lt;li&gt;build the project&lt;/li&gt;
&lt;li&gt;react on pull request creation on the main and develop branch.&lt;/li&gt;
&lt;li&gt;make successful compilation a&amp;nbsp;mandatory check for the pull request.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the build fails, the&amp;nbsp;pull request&amp;nbsp;fails. That&amp;#39;s what I try to achieve in this exercise:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;developers can check in non-working in feature branches.&lt;/li&gt;
&lt;li&gt;once ready to ask&amp;nbsp;merging with one of the two protected branches (develop or main), code should&amp;nbsp;meet quality requirements and should build.&lt;br /&gt;That&amp;#39;s the moment that you deem your work done, and&amp;nbsp;should be ready for a code review.&lt;br /&gt;If your code breaks the build at this point, you impact others - and maybe the production release. It&amp;#39;s a fail.&lt;/li&gt;
&lt;li&gt;Code reviewers don&amp;#39;t have to spend time validating non-funcioning code.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The script I&amp;#39;m using is based on the &lt;a href="https://github.com/raspberrypi/pico-examples/blob/e38b215d2a5259906302a6669043d95af5894d50/.github/workflows/macOS.yml" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;Raspberrry MacOS build for Pico&lt;/a&gt;. I adapted it for Linux.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" height="112" src="https://community.element14.com/resized-image/__size/996x224/__key/communityserver-discussions-components-files/126/pastedimage1720986004290v1.png" width="498" /&gt;&lt;/p&gt;
&lt;p&gt;Script source of build.yml:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;pre class="ui-code" data-mode="text"&gt;name: Build on ubuntu against pico-sdk develop
on:
  workflow_dispatch:
  #push:
  #  branches:
  #    - &amp;#39;develop&amp;#39;
  #    - &amp;#39;main&amp;#39;
  pull_request:
    types: [opened, reopened]
    branches:
      - &amp;#39;develop&amp;#39;
      - &amp;#39;main&amp;#39;

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    
      - name: Clean workspace
        run: |
          echo &amp;quot;Cleaning up previous run&amp;quot;
          rm -rf &amp;quot;${{ github.workspace }}&amp;quot;
          mkdir -p &amp;quot;${{ github.workspace }}&amp;quot;
      - name: Checkout pico_gps_teseo_i2c
        uses: actions/checkout@v4
        with:
          path: pico_gps_teseo_i2c

      - name: Checkout pico-sdk/develop
        uses: actions/checkout@v4
        with:
          repository: raspberrypi/pico-sdk
          ref: develop
          path: pico-sdk

      - name: Checkout pico-sdk submodules
      
        working-directory: ${{github.workspace}}/pico-sdk
        run: git submodule update --init
      - name: Install dependencies
        run: |
          sudo apt-get install cmake
          #curl -Lo gcc-arm-none-eabi.tar.bz2 &amp;quot;https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2?rev=78196d3461ba4c9089a67b5f33edf82a&amp;amp;hash=5631ACEF1F8F237389F14B41566964EC&amp;quot;
          #sudo mkdir /opt/gcc-arm-none-eabi
          #sudo tar xf gcc-arm-none-eabi.tar.bz2 --strip-components=1 -C /opt/gcc-arm-none-eabi
          #echo &amp;#39;export PATH=$PATH:/opt/gcc-arm-none-eabi/bin&amp;#39; | sudo tee -a /etc/profile.d/gcc-arm-none-eabi.sh
          #export PATH=$PATH:/opt/gcc-arm-none-eabi/bin
          #export PICO_TOOLCHAIN_PATH=/opt/gcc-arm-none-eabi/bin
          #source /etc/profile
          #arm-none-eabi-gcc --version
          sudo apt install gcc-arm-none-eabi
          
      - name: Build Project&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Excuses for the&amp;nbsp;formatting. The code editor does not want to accept this code. Click on this &lt;a href="https://github.com/jancumps/pico_gps_teseo_i2c/blob/main/.github/workflows/build.yml" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;link for a better view&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When you create this script in the .github/workflows folder, it &amp;#39;ll kick off each time a pull rrequest is opened for main or develop. But it will not impact the pull request.&lt;br /&gt;If you want to make pull requests dependent on successful build, you &amp;#39;ll also hav to create a ruleset for the branch.&lt;/p&gt;
&lt;p&gt;On&amp;nbsp;your repository&amp;#39;s web page on&amp;nbsp;GitHub, select settings -&amp;gt; Rules -&amp;gt; Rulesets.&lt;br /&gt;If the branch(es) you want to protect don&amp;#39;t have a ruleset yet, create one. Else you can update the existing one.&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" style="max-height:283px;max-width:500px;"  height="283" src="https://community.element14.com/resized-image/__size/1000x566/__key/communityserver-discussions-components-files/126/pastedimage1721035892809v1.png" width="500" /&gt;&lt;/p&gt;
&lt;p&gt;The first checkbox will take care that&amp;nbsp;the branches you want to protect, can only accept commits via a pull request. When you work together as a team, it&amp;#39;s good that branch owners can check code before it&amp;#39;s merged in the code base.&lt;br /&gt;The second check also adds the condition, that the build job must complete in good order.&lt;/p&gt;
&lt;p&gt;A developer that submits a pull request, gets this page:&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" height="144" src="https://community.element14.com/resized-image/__size/994x288/__key/communityserver-discussions-components-files/126/pastedimage1720982706863v1.png" width="497" /&gt;&lt;/p&gt;
&lt;p&gt;They don&amp;#39;t have to wait for this to complete. They &amp;#39;d get an email if it failed.&amp;nbsp;Once the job is completed, the reviewer sees the screen capture I posted at the start of this blog. If the job was successful, code review and merge can happen.&lt;/p&gt;
&lt;h3 id="mcetoc_1i2qs7e4m1"&gt;How does it fit in my workflow:&lt;/h3&gt;
&lt;p&gt;I&amp;nbsp;created another action earlier: &amp;nbsp;&lt;a href="https://community.element14.com/technologies/code_exchange/f/forum/54815/github-automate-project-documentation-with-doxygen-and-publish-online-after-pushing-commits"&gt;GitHub: automate project documentation with DoxyGen, and publish online after pushing commits&lt;/a&gt;&amp;nbsp;. Together, the 2 automate a decent part of code management:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the build validation described here, when a pull request is made to development or main&lt;/li&gt;
&lt;li&gt;when a pull request to main is accepted and merged by the branch manager (me :) ), the doucmentation is regenerated and published to github.io.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1i2qs77fr0"&gt;Future improvements:&lt;/h3&gt;
&lt;p&gt;I&amp;#39;m considering to let the job create a project release, when a&amp;nbsp;new Version TAG is created in the repository. I&amp;#39;d have to make these changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;add trigger on TAG creation event. Filter on tags that start with &amp;#39;v&amp;#39;.&lt;/li&gt;
&lt;li&gt;change the build type from Debug to Release&lt;/li&gt;
&lt;li&gt;use a GitHub Action to create a release in the repository, and upload the .uf2 file as asset to that release.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Link to&amp;nbsp;&lt;a href="https://community.element14.com/search?q=*#serptag=teseo_c%2B%2B&amp;amp;serpsort=date%20desc" data-e14adj="t"&gt;all posts&lt;/a&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>C++ and templates: callbacks that return a value, or a void</title><link>https://community.element14.com/thread/54742?ContentTypeID=0</link><pubDate>Fri, 21 Jun 2024 16:38:59 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:4e1bda44-73fd-4193-bb9b-e6c83c5309f4</guid><dc:creator>Jan Cumps</dc:creator><slash:comments>0</slash:comments><comments>https://community.element14.com/thread/54742?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/54742/c-and-templates-callbacks-that-return-a-value-or-a-void/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p&gt;In C(++), a function can return a value. Or a void. &lt;br /&gt;A function with a return value ends with &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;return &lt;strong&gt;&lt;em&gt;X&lt;/em&gt;&lt;/strong&gt;;&lt;/span&gt;.&lt;br /&gt;A function that returns &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;void&lt;/span&gt;, has a last line &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;return;&lt;/span&gt;. Without value. (and&amp;nbsp;you don&amp;#39;t have to write that &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;return;&lt;/span&gt;, but that doesn&amp;#39;t matter in&amp;nbsp;this discussion)&lt;br /&gt;When using templates, this needs consideration, if you allow the return type to&amp;nbsp; be &amp;quot;templated&amp;quot; and you want to support &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;void&lt;/span&gt; as one of the options for a return value of a member.&lt;/p&gt;
&lt;p&gt;A void function (named a procedure in a lot of programming languages) is different than a function that returns something. Internally and conceptually.&lt;br /&gt;&lt;em&gt;internally&lt;/em&gt;:&amp;nbsp;the return value is a position on the stack. void functions don&amp;#39;t have that position.&lt;br /&gt;&lt;em&gt;conceptually&lt;/em&gt;: ignoring the internally difference, and returning something in a &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;void()&lt;/span&gt; function anyways, breaks the C(++) language. Also not returning a value (of the correct type) in a function that does require a return value, fails to compile.&lt;/p&gt;
&lt;p&gt;I wrote &lt;a href="https://community.element14.com/products/devtools/software/f/forum/54719/c-callbacks-and-templates" data-e14adj="t"&gt;a templated class that can call a callback&lt;/a&gt;. And I wanted it to support returning numbers / bools.&amp;nbsp;&lt;br /&gt;The thing is: when no callback function is set, the class had to work too. It &lt;em&gt;has&lt;/em&gt; to return a value in that case .So I wrote this code:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;	inline R call(Args... args) {
		if (_callback == nullptr) {
			return 0; // R can only be a arithmetic type. 0 should work as default.
		}
		return (*_callback)(args...);
	}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This works great for boolean, integer, float return values. But it you want to support callbacks that don&amp;#39;t have a return value, it will fail.&lt;br /&gt;If R is type void, the compilation will not allow r&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;eturn 0;&lt;/span&gt;. And if R is a number, compilation will not allow &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;return;&lt;/span&gt;.&lt;/p&gt;
&lt;h1 id="mcetoc_1i0tq35hb0"&gt;solution: constant expressions&lt;/h1&gt;
&lt;p&gt;In C++ , we can write constant expressions. A condition that&amp;#39;s checked at compile time. If it&amp;#39;s true, the containing block will be compiled. If it&amp;#39;s false, not.&lt;br /&gt;A bit related to the C style&amp;nbsp;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;#ifdef&lt;/span&gt; , but context aware.&amp;nbsp;A constant expression knows the code it&amp;#39;s acting upon (including parameter types). These constant expressions understand C++ source code.&lt;br /&gt;What they have in common with defines: they both are static: they resolve everything during compilation. They have no runtime cost.&lt;/p&gt;
&lt;p&gt;I use this construct to have different behaviour if the return type of my callback function is void, and when it&amp;#39;s an arithmetic (number) type:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;	/*
	 * R can either be an arithmetic type, or void
	 */
	inline R call(Args... args) {
		if constexpr (std::is_void&amp;lt;R&amp;gt;::value) {
			if (_callback == nullptr) {
				return;
			}
			(*_callback)(args...);
		}

		if constexpr (! std::is_void&amp;lt;R&amp;gt;::value) {
			if (_callback == nullptr) {
				return 0; // R can only be a arithmetic type. 0 should work as default.
			}
			return (*_callback)(args...);
		}
	}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;You can see that when my templated code is configured for a callback function that returns a bool or a number, it &amp;#39;ll use the lower part, and always return a value.&lt;br /&gt;When the template is configured for a void() type of callback (a procedure), it just returns, without a return value.&lt;/p&gt;
&lt;p&gt;This compiles, runs, is type safe and has no runtime impact.&amp;nbsp;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;if constexpr&lt;/span&gt; gets resolved when you build the code. If your code doesn&amp;#39;t have &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;void()&lt;/span&gt; callbacks, the top part doesn&amp;#39;t get compiled. If it doesn&amp;#39;t have callbacks that expect a return value, the bottom part doesn&amp;#39;t get compiled.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Check my set of test cases below, to see how this works:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#include &amp;lt;cstdio&amp;gt;
#include &amp;quot;callbackmanager.h&amp;quot;
#include &amp;lt;string&amp;gt;

class MyClass {
public:
	inline int handler(const int&amp;amp; num1, const int&amp;amp; num2) const {
          return num1 + num2;
      }
      static inline int staticHandler(const int&amp;amp; num1, const int&amp;amp; num2) {
          return num1 + num2;
      }
};

int functionHandler(const int&amp;amp; num1, const int&amp;amp; num2) {
    return num1 + num2;
}

int main() {

    int a = 4;
    int b = 5;

	{ // scenario: call object method
    MyClass myClass;

    Callback&amp;lt;int, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
    // Use a lambda to capture myClass and call the object method
    cb.set([&amp;amp;myClass](const int&amp;amp; num1, const int&amp;amp; num2) -&amp;gt; int {
        return myClass.handler(num1, num2);
    });

    int o = cb.call(a, b);
    printf(&amp;quot;Value: %i\n&amp;quot;, o);
	fflush(stdout);
	}

	{ // scenario: call static method
    Callback&amp;lt;int, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
    // Use a lambda to call the static method
    cb.set([](const int&amp;amp; num1, const int&amp;amp; num2) -&amp;gt; int {
        return MyClass::staticHandler(num1, num2);
    });

    int o = cb.call(a, b);
    printf(&amp;quot;Value: %i\n&amp;quot;, o);
	fflush(stdout);
	}

	{ // scenario: call C function
    Callback&amp;lt;int, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
    // Use a lambda to call the classic C function
    cb.set([](const int&amp;amp; num1, const int&amp;amp; num2) -&amp;gt; int {
        return functionHandler(num1, num2);
    });

    int o = cb.call(a, b);
    printf(&amp;quot;Value: %i\n&amp;quot;, o);
	fflush(stdout);
	}

	{ // scenario: call pure lambda
    Callback&amp;lt;int, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
    // Use a lambda to execute anonymous C code
    cb.set([](const int&amp;amp; num1, const int&amp;amp; num2) -&amp;gt; int {
        return num1 + num2;
    });

    int o  = cb.call(a, b);
    printf(&amp;quot;Value: %i\n&amp;quot;, o);
	fflush(stdout);
	}

	{ // scenario: return a bool
    Callback&amp;lt;bool, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
    // Use a lambda to execute anonymous C code
    cb.set([](const int&amp;amp; num1, const int&amp;amp; num2) -&amp;gt; bool {
        return num1 == num2;
    });

    printf(&amp;quot;Value: %s\n&amp;quot;, cb.call(a, b) ? &amp;quot;true&amp;quot; : &amp;quot;false&amp;quot;);
	fflush(stdout);
	}

	{ // scenario: use a callback that returns void
    Callback&amp;lt;void, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
    // Use a lambda to execute anonymous C code
    cb.set([](const int&amp;amp; num1, const int&amp;amp; num2) {
        printf(&amp;quot;void gets num1: %i, num2: %i\n&amp;quot;, num1, num2);
    	fflush(stdout);
        return;
    });
    cb.call(a, b);
	}

	{ // scenario: use a callback that returns void, and has no attributes
    Callback&amp;lt;void&amp;gt; cb;
    // Use a lambda to execute anonymous C code
    cb.set([]() {
        printf(&amp;quot;void with no parameters\n&amp;quot;);
    	fflush(stdout);
        return;
    });
    cb.call();
	}

	/*
	{ // scenario: use an unsupported (non-fundamental) type for return value R
	  // this will generate a compile error
    Callback&amp;lt;std::string, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
	}
*/

}&lt;/pre&gt;&lt;/p&gt;
&lt;table border="1"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;a constexpr knows &amp;quot;everything&amp;quot; about your code. When you use it in a template class, it will know for what types your project will use that template class.&amp;nbsp;Then it &amp;#39;ll&amp;nbsp;take care that it &amp;#39;ll only send that part of the code to the compiler, that is needed for your project.&lt;/p&gt;
&lt;p&gt;For classes like the one that I&amp;#39;m writing, this is great. My class has no clue how it &amp;#39;ll be used. But I provide logic for a set of scenarios that I want to support.&lt;br /&gt;C++ constructs like &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;constexpr&lt;/span&gt; will take care that this flexibility has no cost when executing the code. All code gets checked at compilation, and needs to pass the strict C++ type checks. But at no cost for the final firmware.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>C++ and templates: restrict what types can be used in a template</title><link>https://community.element14.com/thread/54725?ContentTypeID=0</link><pubDate>Mon, 17 Jun 2024 15:33:54 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:56a59140-6063-4163-9b05-56117c976f1c</guid><dc:creator>Jan Cumps</dc:creator><slash:comments>7</slash:comments><comments>https://community.element14.com/thread/54725?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/54725/c-and-templates-restrict-what-types-can-be-used-in-a-template/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p&gt;When you use templates in C++, the user can normally plug any C type in a program.&amp;nbsp;For a template class I developed (read &amp;nbsp;&lt;a href="https://community.element14.com/products/devtools/software/f/forum/54719/c-callbacks-and-templates"&gt;C++ callbacks and templates&lt;/a&gt;&amp;nbsp;), I want to restrict one of the template arguments:&amp;nbsp;R. This is the type of the return value of a callback function.&amp;nbsp;The&amp;nbsp;restriction that I want to impose, is that the function should not return an object, array, string, ... . Numeric and bool types should do. Or&amp;nbsp;return nothing (void).&lt;/p&gt;
&lt;p&gt;I want to be able to return a 0 if no&amp;nbsp;function is set in _callback. So as long as the return value is a C++ arithmetic types, I&amp;#39;ll be good. My mechanism will fail if a developer wants to use functions that return strings, arrays, objects, ...&lt;br /&gt;I think that being able to return any arithmetic type is flexible enough for a generic callback handler.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;template &amp;lt;typename R, typename... Args&amp;gt;
// restrict to arithmetic data types for return value, or void
  requires std::is_void&amp;lt;R&amp;gt;::value || std::is_arithmetic_v&amp;lt;R&amp;gt;
class Callback {

// ...

	/*
	 * R can either be an arithmetic type, or void
	 */
	inline R call(Args... args) {
		if constexpr (std::is_void&amp;lt;R&amp;gt;::value) {
			if (_callback == nullptr) {
				return;
			}
			(*_callback)(args...);
		}

		if constexpr (! std::is_void&amp;lt;R&amp;gt;::value) {
			if (_callback == nullptr) {
				return 0; // R can only be a arithmetic type. 0 should work as default.
			}
			return (*_callback)(args...);
		}
	}

// ...&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I could do nothing. In that case the developer would get a compilation error on this line in my code:&amp;nbsp;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;return 0;&lt;/span&gt;.&amp;nbsp;And they &amp;#39;ll have to go and investigate why my code throws an error.&lt;/p&gt;
&lt;p&gt;C++ now has a mechanism that&amp;#39;s called &lt;a href="https://en.cppreference.com/w/cpp/language/constraints" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;concept&lt;/a&gt;. With that, I can restrict the C++ type that a particular template&amp;nbsp;attribute can have. I will use that to only allow arithmetic types for the return value type R.&lt;br /&gt;When doing that, the compiler will give a clear message, pointing to the user&amp;#39;s code line where they defined an invalid return type:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;78 |&amp;nbsp; &amp;nbsp; &amp;nbsp;Callback&amp;lt;std::string, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;&lt;br /&gt;error: template constraint failure for &amp;#39;template&amp;lt;class R, class ... Args&amp;gt;&amp;nbsp; requires&amp;nbsp; std::is_arithmetic&amp;lt;_Tp&amp;gt;::value class Callback&amp;#39;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;note: constraints not satisfied&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Thank you for reading. Check&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/products/devtools/software/f/forum/54742/c-and-templates-callbacks-that-return-a-value-or-a-void"&gt;C++ and templates: callbacks that return a value, or a void&lt;/a&gt;&amp;nbsp;for yet another dive into hip C++...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>C++ callbacks and templates: make the Callback class call an object member, a static member, a C function and a pure lambda function</title><link>https://community.element14.com/thread/54721?ContentTypeID=0</link><pubDate>Sun, 16 Jun 2024 10:25:57 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:5b356e06-5881-4266-b1c9-4f99fba9084c</guid><dc:creator>Jan Cumps</dc:creator><slash:comments>1</slash:comments><comments>https://community.element14.com/thread/54721?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/54721/c-callbacks-and-templates-make-the-callback-class-call-an-object-member-a-static-member-a-c-function-and-a-pure-lambda-function/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p&gt;I developed a templated C++ callback manager:&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/products/devtools/software/f/forum/54719/c-callbacks-and-templates"&gt;C++ callbacks and templates&lt;/a&gt;&amp;nbsp;.&amp;nbsp;I claimed that it&amp;nbsp;can&amp;nbsp;call back&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;a classic C function, &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;a lambda, &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;a static class method or &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;an object method,&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;and it supports these return types:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;void&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;bool&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;number&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;objects (if the class has a default constructor and &amp;quot;is returnable&amp;quot;.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;But in that first post, I only showed an example where the method of an object was used as callback handler.&amp;nbsp;In this post, I show all 4 scenarios.&amp;nbsp;This time,&amp;nbsp;I&amp;#39;m not showing the power of templates, but the power of lambda functions.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;As a refresher, here is the Callback manager. Unchanged since previous post. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/jancumps/callbackmanager/blob/main/callbackmanager.cpp" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;callmanager.cpp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="csharp"&gt;module;

#include &amp;lt;concepts&amp;gt;
#include &amp;lt;functional&amp;gt;

export module callbackmanager;

namespace callbackmanager {

// concept guards what types of return values we can handle
template&amp;lt;typename R&amp;gt;
concept Callbackable = 
	std::is_void&amp;lt;R&amp;gt;::value ||
	std::is_arithmetic_v&amp;lt;R&amp;gt; ||
	std::is_class_v&amp;lt;R&amp;gt;;

export template &amp;lt;Callbackable R, typename... Args&amp;gt;
class Callback {
	using callbackfunction_t = std::function&amp;lt;R(Args...)&amp;gt;;	
public:
	Callback() : callback_(nullptr), is_callback_set(false){}

	inline void set(callbackfunction_t callback) {
	    callback_ = callback;
		is_callback_set = true;
	}

	inline void unset() {
		callback_ = nullptr;
		is_callback_set = false;
	}

	[[deprecated(&amp;quot;Use operator () instead.&amp;quot;)]]
	inline R call(Args... args) {
		return *this(args...);
	}

	inline bool is_set() {
		return is_callback_set;		
	}

	/*
	 * R can be an arithmetic type, an object, or void
	 */
	inline R operator()(Args... args) {
		if constexpr (std::is_void&amp;lt;R&amp;gt;::value) {  // void
			if (!is_callback_set) {
				return;
			} else {
				(callback_)(args...);
			}
		} else if constexpr (std::is_class&amp;lt;R&amp;gt;::value) { // object
			if (!is_callback_set) {
				return R();
			} else {
				return (callback_)(args...);
			}
		} else { // not void nor object
			if (!is_callback_set) {
				return 0; // R can only be a arithmetic type. 0 should work as default.
			} else {
				return (callback_)(args...);
			}
		}
	}

private:
	callbackfunction_t callback_;
	bool is_callback_set;
};

} // namespace callbackmanager&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;And here is the code that exercises the 4 scenarios. Each scenario is&amp;nbsp;surrounded by {}. That means that they run in their own little isolated scope, And they don&amp;#39;t spoil each other.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;First, some code that will be used in the test. They are 3 different types of functions / methods:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family:inherit;"&gt;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;MyClass&lt;/span&gt;, now with a static and normal member function. So that we can test a scenario where we call an object member, and a scenario where we call a static class member.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family:inherit;"&gt;classic C function&amp;nbsp;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;functionHandler()&lt;/span&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style="font-family:inherit;"&gt;All 3 do the same thing. They return the sum of two integers.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;typeinfo&amp;gt;

import callbackmanager;

class MyClass {
public:
      inline int handler(const int&amp;amp; num1, const int&amp;amp; num2) const {
          return num1 + num2;
      }
      static inline int staticHandler(const int&amp;amp; num1, const int&amp;amp; num2) {
          return num1 + num2;
      }
};

int functionHandler(const int&amp;amp; num1, const int&amp;amp; num2) {
    return num1 + num2;
}&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Then the 4 tests:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;int main() {

    int a = 4;
    int b = 5;

    Callback&amp;lt;int, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
    // Use a lambda to capture myClass and call the object method
    cb.set([&amp;amp;myClass](const int&amp;amp; num1, const int&amp;amp; num2) -&amp;gt; int {
        return myClass.handler(num1, num2);
    });

    int o = cb(a, b);
    printf(&amp;quot;Value: %i\n&amp;quot;, o); // We might be on an embedded system, use printf() and not std::cout
	fflush(stdout);
	}

	{ // scenario: call static method
    Callback&amp;lt;int, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
    // Use a lambda to call the static method
    cb.set([](const int&amp;amp; num1, const int&amp;amp; num2) -&amp;gt; int {
        return MyClass::staticHandler(num1, num2);
    });

    int o = cb(a, b);
    printf(&amp;quot;Value: %i\n&amp;quot;, o); // We might be on an embedded system, use printf() and not std::cout
	fflush(stdout);
	}

	{ // scenario: call C function
    Callback&amp;lt;int, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
    // Use a lambda to call the classic C function
    cb.set([](const int&amp;amp; num1, const int&amp;amp; num2) -&amp;gt; int {
        return functionHandler(num1, num2);
    });

    int o = cb(a, b);
    printf(&amp;quot;Value: %i\n&amp;quot;, o); // We might be on an embedded system, use printf() and not std::cout
	fflush(stdout);
	}

	{ // scenario: call pure lambda
    Callback&amp;lt;int, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
    // Use a lambda to execute anonymous C code
    cb.set([](const int&amp;amp; num1, const int&amp;amp; num2) -&amp;gt; int {
        return num1 + num2;
    });

    int o  = cb(a, b);
    printf(&amp;quot;Value: %i\n&amp;quot;, o);
	fflush(stdout);
	}

	{ // scenario: return a bool
    Callback&amp;lt;bool, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
    // Use a lambda to execute anonymous C code
    cb.set([](const int&amp;amp; num1, const int&amp;amp; num2) -&amp;gt; bool {
        return num1 == num2;
    });

    printf(&amp;quot;Value: %s\n&amp;quot;, cb(a, b) ? &amp;quot;true&amp;quot; : &amp;quot;false&amp;quot;);
	fflush(stdout);
	}

	{ // scenario: use void
    Callback&amp;lt;void, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
    // Use a lambda to execute anonymous C code
    cb.set([](const int&amp;amp; num1, const int&amp;amp; num2) {
        return;
    });
    cb(a, b);
	}
	
    { // scenario: return an object
    class return_class {
    public:
        return_class() : value_(0) {};
        int value_;
    };

	callbackmanager::Callback&amp;lt;return_class&amp;gt; cb;
    // Use a lambda to execute anonymous C code
    cb.set([]() -&amp;gt; return_class {
        return_class rc;
        rc.value_ = 1;
        return rc;
    });
    return_class ret = cb();
    printf(&amp;quot;Value: %d\n&amp;quot;, ret.value_ );
	fflush(stdout);
	}

	/*
	{ // scenario: use an unsupported (non-fundamental) type for return value R
	  // this will generate a compile error
    Callback&amp;lt;std::string, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
	}
}&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;edit:&amp;nbsp;The template also allows void return values. Some more tests:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;	{ // scenario: use void
    Callback&amp;lt;void, const int&amp;amp;, const int&amp;amp;&amp;gt; cb;
    // Use a lambda to execute anonymous C code
    cb.set([](const int&amp;amp; num1, const int&amp;amp; num2) {
        printf(&amp;quot;void gets num1: %i, num2: %i\n&amp;quot;, num1, num2);
    	fflush(stdout);
        return;
    });
    cb.call(a, b);
	}

	{ // scenario: use void, and no attributes
    Callback&amp;lt;void&amp;gt; cb;
    // Use a lambda to execute anonymous C code
    cb.set([]() {
        printf(&amp;quot;void with no parameters\n&amp;quot;);
    	fflush(stdout);
        return;
    });
    cb.call();
	}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Scenarios, in order of execution: (&lt;em&gt;edit: this was written before I revised the code to support&amp;nbsp;configurable return value. The test code above is adapted, but I didn&amp;#39;t change the images below)&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span&gt;call object method&lt;br /&gt;In this one, I create object &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;myClass&lt;/span&gt; of type &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;MyClass&lt;/span&gt;. Then pass its &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;handle()&lt;/span&gt; method as callback. &lt;br /&gt;This was the scenario of the first post.&lt;br /&gt;&lt;img alt="image" style="max-height:360px;max-width:640px;"  src="https://community.element14.com/resized-image/__size/1280x720/__key/communityserver-discussions-components-files/126/pastedimage1718533908601v1.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;call static class method&lt;br /&gt;In this test, I don&amp;#39;t declare an object of type MyClass. I pass the static &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;MyClass::staticHandle()&lt;br /&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="https://community.element14.com/resized-image/__size/1280x720/__key/communityserver-discussions-components-files/126/pastedimage1718533940203v2.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;classic C function&lt;br /&gt;Here, the callback gets a very common C function, named &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;functionHandler()&lt;/span&gt;, as handler.&amp;nbsp;&lt;br /&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="https://community.element14.com/resized-image/__size/1280x720/__key/communityserver-discussions-components-files/126/pastedimage1718533971892v3.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;a pure lambda.&lt;br /&gt;In this test, I pass an anonymous block of code as handler:&lt;br /&gt;&lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;return num1 + num2;&lt;/span&gt;&lt;br /&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="https://community.element14.com/resized-image/__size/1280x720/__key/communityserver-discussions-components-files/126/pastedimage1718533988796v4.png" /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;return an object. This is added on 09-mar-2025.Works as long as the object supports a default constructor and does not forbid copy / assign.&lt;br /&gt;&lt;img loading="lazy" alt="image" style="max-height:287px;max-width:367px;"  height="287" src="https://community.element14.com/resized-image/__size/734x574/__key/communityserver-discussions-components-files/126/pastedimage1741524650836v1.png" width="367" /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;In each test,&amp;nbsp;the &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;Callback&lt;/span&gt; object &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;cb&lt;/span&gt; will call the code that&amp;#39;s given to it in the &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;set()&lt;/span&gt; call. All using the exact same little Callback template class. If you would set breakpoints, here is where the code would stop for each of the 4 cases:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;img loading="lazy" alt="image" style="max-height:678px;max-width:499px;"  height="678" src="https://community.element14.com/resized-image/__size/998x1356/__key/communityserver-discussions-components-files/126/pastedimage1718535291980v1.png" width="499" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:75%;"&gt;&lt;em&gt;edit: this was written before I replaced call() by operator ()..In your code, don&amp;#39;t use &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;cb.call(args)&lt;/span&gt;, but &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;cb(args)&lt;/span&gt;. The test code&amp;nbsp;in the blog is adapted, but I didn&amp;#39;t change the images.&lt;/em&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;The test code is &lt;a href="https://gist.github.com/jancumps/6dbc257c80911270775ee9d44a5131ee" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;available as a Gist&lt;/a&gt;.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>C++ callbacks and templates</title><link>https://community.element14.com/thread/54719?ContentTypeID=0</link><pubDate>Sat, 15 Jun 2024 10:50:00 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:95e9f4be-67c8-415a-81cf-d67f3fd1ce81</guid><dc:creator>Jan Cumps</dc:creator><slash:comments>17</slash:comments><comments>https://community.element14.com/thread/54719?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/54719/c-callbacks-and-templates/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p&gt;I&amp;#39;m experimenting: can I use&amp;nbsp;a method of a particular object as a callback?&amp;nbsp;This can be used in typical callback situations, e.g.:&amp;nbsp;in a&amp;nbsp;UART driver. But also&amp;nbsp;in interrupt handlers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;lightweight: small runtime cost, low firmware&amp;nbsp;hit.&amp;nbsp;Can be used for tiny&amp;nbsp;embedded systems.&lt;/li&gt;
&lt;li&gt;reusable: don&amp;#39;t assume parameters and types for the handler, when writing this little framework -&amp;gt; C++ templates&lt;/li&gt;
&lt;li&gt;hip -&amp;gt; object oriented, modern C++ constructs&lt;/li&gt;
&lt;li&gt;type safe -&amp;gt; again C++ templates&lt;/li&gt;
&lt;li&gt;allow a classic C function, a lambda, a static class method or an object method as handler&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;example: Raspberry&amp;nbsp;Pico blinky using this design&lt;/p&gt;
&lt;table border="1"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;span style="font-size:150%;"&gt;&lt;span style="color:#000000;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;&lt;span style="color:#af00db;"&gt;#include&lt;/span&gt;&lt;span style="color:#0000ff;"&gt; &lt;/span&gt;&lt;span style="color:#a31515;"&gt;&amp;lt;new&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;&lt;span style="color:#af00db;"&gt;#include&lt;/span&gt;&lt;span style="color:#0000ff;"&gt; &lt;/span&gt;&lt;span style="color:#a31515;"&gt;&amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;&lt;span style="color:#af00db;"&gt;#include&lt;/span&gt;&lt;span style="color:#0000ff;"&gt; &lt;/span&gt;&lt;span style="color:#a31515;"&gt;&amp;quot;pico/stdlib.h&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#000000;font-size:150%;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;import callbackmanager;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#000000;font-size:150%;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;&lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#267f99;"&gt;uint32_t&lt;/span&gt; &lt;span style="color:#001080;"&gt;delay_ms&lt;/span&gt; = &lt;span style="color:#098658;"&gt;250&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#000000;font-size:150%;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;&lt;span style="color:#001080;"&gt;callbackmanager&lt;/span&gt;::Callback&amp;lt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&amp;gt; cb;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:150%;"&gt;&lt;span style="color:#000000;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; &lt;span style="color:#795e26;"&gt;main&lt;/span&gt;() {&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:#795e26;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;gpio_init&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;(&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;PICO_DEFAULT_LED_PIN&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:#795e26;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;gpio_set_dir&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;(&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;PICO_DEFAULT_LED_PIN&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;, &lt;/span&gt;&lt;span style="color:#0070c1;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;GPIO_OUT&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:#001080;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;cb&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;.&lt;/span&gt;&lt;span style="color:#795e26;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;set&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;([]() {&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:#0000ff;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;static&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;bool&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt; &lt;/span&gt;&lt;span style="color:#001080;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;state&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt; = &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;false&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:#795e26;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;gpio_put&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;(&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;PICO_DEFAULT_LED_PIN&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;, &lt;/span&gt;&lt;span style="color:#001080;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;state&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt; = !&lt;/span&gt;&lt;span style="color:#001080;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;state&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;});&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:150%;"&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:#af00db;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;while&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt; (&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;) {&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:#795e26;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;cb&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;();&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:#795e26;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;sleep_ms&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;(&lt;/span&gt;&lt;span style="color:#001080;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;delay_ms&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:150%;"&gt;&lt;span style="color:#000000;"&gt;&lt;span style="font-family:Consolas, &amp;#39;Courier New&amp;#39;, monospace;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:arial, helvetica, sans-serif;font-size:inherit;"&gt;&lt;span style="color:#000000;"&gt;project:&amp;nbsp;&lt;a href="https://community.element14.com/cfs-file/__key/communityserver-discussions-components-files/126/2133.pico_5F00_callback_5F00_blink.zip"&gt;community.element14.com/.../2133.pico_5F00_callback_5F00_blink.zip&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="mcetoc_1i0dng6rh0"&gt;Callback&amp;nbsp;template class&lt;/h1&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The template callback class. This is in essence the whole mechanism. A generic class that allows you to register and call event handler functions, lambda&amp;#39;s and methods.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#include &amp;lt;functional&amp;gt;

// concept guards what types of return values we can handle
template&amp;lt;typename R&amp;gt;
concept Callbackable = 
	std::is_void&amp;lt;R&amp;gt;::value ||
	std::is_arithmetic_v&amp;lt;R&amp;gt; ||
	std::is_class_v&amp;lt;R&amp;gt;;
	
template &amp;lt;Callbackable R, typename... Args&amp;gt;
class Callback {
	using callbackfunction_t = std::function&amp;lt;R(Args...)&amp;gt;;	
public:
	Callback() : callback_(nullptr), isSet(false){}

	inline void set(callbackfunction_t callback) {
	    callback_ = callback;
		isSet = true;
	}

	inline void unset() {
		callback_ = nullptr;
		isSet = false;
	}

	inline bool is_set() {
		return isSet;		
	}

	/*
	 * R can be an arithmetic type, an object, or void
	 */
	inline R operator()(Args... args) {
		if constexpr (std::is_void&amp;lt;R&amp;gt;::value) {  // void
			if (!is_callback_set) {
				return;
			} else {
				(callback_)(args...);
			}
		} else if constexpr (std::is_class&amp;lt;R&amp;gt;::value) { // object
			if (!is_callback_set) {
				return R();
			} else {
				return (callback_)(args...);
			}
		} else { // not void nor object
			if (!is_callback_set) {
				return 0; // R can only be a arithmetic type. 0 should work as default.
			} else {
				return (callback_)(args...);
			}
		}

	}
	
private:
	callbackfunction_t callback_;
	bool isSet;
};&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This generic class allows for handlers that pass any amount of parameters. No assumption of the types.&lt;/p&gt;
&lt;p&gt;When we use the class in our code, we &amp;#39;ll tell it what the parameters are, and their type. For this blog, I am going to pass it 2 integers. The return value is also an integer.&lt;/p&gt;
&lt;p&gt;&lt;code&gt; Callback&amp;lt;int, int, int&amp;gt; cb;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In the declaration above, the first int is the return value type, the 2 others are parameter 1 and 2.&amp;nbsp;Once you write this code, the object cb will only accept handler methods that take two integers as parameter, and return an integer.&lt;/p&gt;
&lt;h1 id="mcetoc_1i0dnovsf1"&gt;Example of class that will handle the callback&lt;/h1&gt;
&lt;p&gt;This could be a gio class (blinky a led when an interrupt occurred?), a GUIwidget, or a business object. Typical guidelines apply: a handler should be swift. In particular if it&amp;#39;s an interrupt handler.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;class MyClass {
public:
      int handler(int num1, int num2) {
          return num1 + num2;
      }
};&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The example does not do a lot today. It just sums up the two integers passed. But as a POC this will do.&lt;/p&gt;
&lt;p&gt;Actual code using the two&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#include &amp;lt;cstdio&amp;gt;

int main()
{
    MyClass myClass;

    Callback&amp;lt;int, int, int&amp;gt; cb;
    // Use a lambda to capture myClass and call the member method
    cb.set([&amp;amp;myClass](int num1, int num2) -&amp;gt; int {
        return myClass.handler(num1, num2);
    });

    int a = 4;
    int b = 5;

    int o = cb(a, b);
    printf(&amp;quot;Value: %i\n&amp;quot;, o); // We might be on an embedded system, use printf() and not std::cout
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;table border="1" width="499" height="27"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;em&gt;Why use a lambda to pair the handler and Callback ?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;In the code, I did not learn the MyClass how to register itself. And the Callback doesn&amp;#39;t know anything about who or what&amp;nbsp;it &amp;#39;ll call. These classes (and their objects) are unaware of each other. Loose coupling.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Callback&amp;lt;int, int, int&amp;gt; cb;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cb.set([&amp;amp;myClass](int num1, int num2) -&amp;gt; int {&lt;br /&gt;&amp;nbsp; return myClass.handler(num1, num2);&lt;br /&gt; })&lt;/code&gt;&lt;code&gt;;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In the application logic, I tie the two together. The lambda function code (the anonymous function, starting with the &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;[&lt;/span&gt;, and ending with the &lt;span style="font-family:&amp;#39;courier new&amp;#39;, courier;"&gt;}&lt;/span&gt; above), is used as the vehicle to hold the code that the Callback object will execute when needed.&lt;/p&gt;
&lt;p&gt;The lambda function could as well be a straigtforward piece of code, not related to any object:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Callback&amp;lt;int, int, int&amp;gt; cb;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cb.set([](int num1,&amp;nbsp;int&amp;nbsp;num2) -&amp;gt; int {&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp; return num1 + num2;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;});&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Or we could pass completely different executable code. As long as the lambda matches the signature given when instantiating the Callback class.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;In an embedded system,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;myClass would be one of your application objects.&lt;/li&gt;
&lt;li&gt;cb could be part of a driver, or the HAL layer&lt;/li&gt;
&lt;li&gt;cb.set() would be called by you, to register the handler&lt;/li&gt;
&lt;li&gt;cb.call() would be done by the driver, or HAL ISR, when it wants to notify you (call your callback handler)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the case of this example, it will execute myClass.handler(). If you &amp;#39;d have many MyClass objects, it would call the exact one that&amp;#39;s registered in with&amp;nbsp;set().&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" style="max-height:413px;max-width:500px;"  height="413" src="https://community.element14.com/resized-image/__size/1000x826/__key/communityserver-discussions-components-files/126/uml.jpg" width="500" /&gt;&lt;br /&gt;&lt;span style="font-size:75%;"&gt;&lt;em&gt;Example use of the callback class in an embedded application&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Anything special?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This approach allows to write a reusable callback system. It is type safe. But it does not assume&amp;nbsp;what the type is of the object it &amp;#39;ll call the handler off. (Or if it&amp;#39;s actually an object).&lt;br /&gt;It&amp;#39;s a small amount of code, that performs a&amp;nbsp;function that&amp;nbsp;you regularly need in an embedded or event driven design.&lt;/p&gt;
&lt;table border="1" width="499" height="27"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;em&gt;What does type-safe mean in this context?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If your interrupt handler assumes a function that passes 2 integers, and you pass it a callback function that has&amp;nbsp;different parameters,&lt;br /&gt;you get a compile time error. Your code will not build, because the handler is not compatible.&lt;/p&gt;
&lt;p&gt;And you get all of that, without having to specify the number of variables, and their types, in the Callback class code. We get a reusable class. Type&amp;nbsp;safe.&amp;nbsp;Without the need to foresee all possible combinations.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;this library now also works for Arduino (tested with IDE2, and an Arduino MKT GSM 1400)&lt;/em&gt;&lt;/p&gt;
&lt;table border="1"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p dir="auto"&gt;For Arduino, you can &lt;a href="https://gist.github.com/jancumps/6dbc257c80911270775ee9d44a5131ee/raw/e046870456af25c6ddb79e65504d4ed77d79c3c8/callbackmanager.h" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;download callbackmanager.h&lt;/a&gt; to your computer, then use Sketch -&amp;gt; Add File ... to get the callbackmanager included to your project. &lt;br /&gt;Add this line to your sketch:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;quot;callbackmanager.h&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p dir="auto"&gt;I added a sketch to test the callback manager to this gist: &lt;a href="https://gist.githubusercontent.com/jancumps/6dbc257c80911270775ee9d44a5131ee/raw/df2641f47183aefc09261c25b77c7ddff0f336af/test_arduino.ino" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;test_arduino.ino&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="https://community.element14.com/resized-image/__size/1280x720/__key/communityserver-discussions-components-files/126/pastedimage1721652589582v2.png" /&gt;&lt;br /&gt;&lt;span style="font-size:75%;"&gt;Arduinos that use the gcc-avg toolchain are not supported (UNO, Mega, the original basic Nano)&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;shortcuts:&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="text-decoration:line-through;"&gt;I assume fixed return value type. A richer implementation can use template for that too, and should allow void.&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;em&gt;edit: this works&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="text-decoration:line-through;"&gt;I pass arguments by value. A better design would also allow pass by reference. And to pass&amp;nbsp;const references.&lt;/span&gt;&amp;nbsp;&lt;em&gt;edit: this works&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="text-decoration:line-through;"&gt;should I use a shared pointer, so that&amp;nbsp;I can never call the handler of an object that no longer exists? (solved by alternative: provide an unset() method).&lt;/span&gt;&amp;nbsp;&lt;em&gt;edit: the class no longer uses pointers&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;it only allows to call one handler. Good for ISR use. But in an event driven design, you may want to register more handlers. I prefer just one handler. simple scope, simple responsibility.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Inspiration:&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I started from &lt;a href="https://blog.mbedded.ninja/programming/languages/c-plus-plus/callbacks/" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;this example by&amp;nbsp;Geoffrey Hunter&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;mbed&amp;#39;s &lt;a href="https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/_callback_8h_source.html" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;Callback class&lt;/a&gt;, although I didn&amp;#39;t use any of the code&lt;/li&gt;
&lt;li&gt;cplusplus&amp;#39; &lt;a href="//%20https//cplusplus.com/reference/functional/function/function/#example" data-e14adj="t"&gt;tutorial for std::function&lt;/a&gt;, to validate if it works for static class member, object member, classic C function and lambda function.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Code is &lt;a href="https://github.com/jancumps/callbackmanager" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;available on github&lt;/a&gt;. Additional assets&amp;nbsp;&lt;a href="https://gist.github.com/jancumps/6dbc257c80911270775ee9d44a5131ee" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;available on Gist&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;CMakeLists.txt to build an example program:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;cmake_minimum_required(VERSION 3.28)

project(callbackmanager C CXX ASM)

# GoogleTest requires at least C++14
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS &amp;quot;${CMAKE_CXX_FLAGS} -fmodules-ts -fcommon&amp;quot;)

add_executable(${CMAKE_PROJECT_NAME})
target_sources(${CMAKE_PROJECT_NAME}
        PUBLIC
        ${CMAKE_CURRENT_SOURCE_DIR}/example/callback_examples.cpp
)
target_sources(${CMAKE_PROJECT_NAME}
        PUBLIC
        FILE_SET cxx_modules TYPE CXX_MODULES FILES
        ${CMAKE_CURRENT_SOURCE_DIR}/callbackmanager.cpp
)

target_link_libraries( ${CMAKE_PROJECT_NAME}
)&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I test this code in&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/products/devtools/software/f/forum/54721/c-callbacks-and-templates-make-the-callback-class-call-an-object-member-a-static-member-a-c-function-and-a-pure-lambda-function"&gt;C++ callbacks and templates: make the Callback class call an object member, a static member, a C function and a pure lambda function&lt;/a&gt;&amp;nbsp;&lt;br /&gt;edit 20250208: I converted it to a c++ module:&amp;nbsp;&lt;a href="https://community.element14.com/technologies/code_exchange/b/blog/posts/modern-c-modules-convert-existing-example-from-h-to-module"&gt;modern C++ modules: convert existing example from .h to module&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>Github Template repository: get updates from origin</title><link>https://community.element14.com/thread/54714?ContentTypeID=0</link><pubDate>Fri, 14 Jun 2024 08:49:50 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:500f5d36-1593-4e29-b014-c0e7028a3dec</guid><dc:creator>Jan Cumps</dc:creator><slash:comments>4</slash:comments><comments>https://community.element14.com/thread/54714?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/54714/github-template-repository-get-updates-from-origin/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p&gt;When you create a Github repository from a Template, there is no origin &amp;lt;&amp;gt; destination relationship. They live separate lives.&amp;nbsp;This is different from Forking a repository. In that case the fork knows its origin, and you can sync your Fork from the origin.&lt;/p&gt;
&lt;p&gt;I would like to update my repository from the original template though. Because that repository gets bug fixes, and I want to inherit them.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Original&amp;nbsp;template repo:&amp;nbsp;&lt;a id="" href="https://github.com/jancumps/pst_rtos" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;https://github.com/jancumps/pst_rtos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;My&amp;nbsp;repository that&amp;#39;s based on that template:&amp;nbsp;&lt;a id="" href="https://github.com/jancumps/pst_rtos_xiao" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;https://github.com/jancumps/pst_rtos_xiao&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I&amp;nbsp;have been looking for solutions. I found a few custom Github actions that can do this. But they fail if there&amp;#39;s a merge conflict. And because it&amp;#39;s a job, you can&amp;#39;t interactively resolve that.&amp;nbsp;Then I found a solution on &lt;a href="https://stackoverflow.com/a/56577320" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;Stack Overflow&lt;/a&gt; that uses the git command. It worked for me:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;I&amp;#39;m looking for feedback. Do you think that this will&amp;nbsp;corrupt the pst_freertos_xiao repo?&lt;br /&gt;The Stack Overflow page lists the side effects, and I&amp;#39;ve read them. It also has different suggestions, e.g.: patching ...&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I started a command line, and navigated to the root of pst_rtos_xiao&amp;nbsp;repository&amp;nbsp;clone on my hard disk.&lt;/p&gt;
&lt;p&gt;Then I executed these commands:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git pull&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" style="max-height:191px;max-width:599px;"  height="191" src="https://community.element14.com/resized-image/__size/1198x382/__key/communityserver-discussions-components-files/126/pastedimage1718354346597v4.png" width="599" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git remote add template &lt;a id="" href="https://github.com/jancumps/pst_rtos.git" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;https://github.com/jancumps/pst_rtos.git&lt;/a&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" style="max-height:48px;max-width:602px;"  height="48" src="https://community.element14.com/resized-image/__size/1204x96/__key/communityserver-discussions-components-files/126/pastedimage1718354173426v1.png" width="602" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git fetch --all&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" style="max-height:287px;max-width:602px;"  height="287" src="https://community.element14.com/resized-image/__size/1204x574/__key/communityserver-discussions-components-files/126/pastedimage1718354190302v2.png" width="602" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git merge template/main --allow-unrelated-histories&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" style="max-height:130px;max-width:603px;"  height="130" src="https://community.element14.com/resized-image/__size/1206x260/__key/communityserver-discussions-components-files/126/pastedimage1718354440173v6.png" width="603" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If merge conflicts occcur, this would be&amp;nbsp;where you fix them.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git status&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" style="max-height:208px;max-width:602px;"  height="208" src="https://community.element14.com/resized-image/__size/1204x416/__key/communityserver-discussions-components-files/126/pastedimage1718354378493v5.png" width="602" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git add CMakeLists.txt&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git add source/scpi/scpi-def.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" style="max-height:114px;max-width:603px;"  height="114" src="https://community.element14.com/resized-image/__size/1206x228/__key/communityserver-discussions-components-files/126/pastedimage1718354527199v7.png" width="603" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git commit -a -m &amp;quot;refreshing from template&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" style="max-height:77px;max-width:601px;"  height="77" src="https://community.element14.com/resized-image/__size/1202x154/__key/communityserver-discussions-components-files/126/pastedimage1718354583307v8.png" width="601" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ git push&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" style="max-height:163px;max-width:600px;"  height="163" src="https://community.element14.com/resized-image/__size/1200x326/__key/communityserver-discussions-components-files/126/pastedimage1718354606869v9.png" width="600" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This&amp;nbsp;merged all changes in my oinline Github repo&amp;nbsp;&lt;a id="" href="https://github.com/jancumps/pst_rtos_xiao" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;https://github.com/jancumps/pst_rtos_xiao&lt;/a&gt;. That was the goal.&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" style="max-height:366px;max-width:598px;"  height="366" src="https://community.element14.com/resized-image/__size/1196x732/__key/communityserver-discussions-components-files/126/pastedimage1718354882186v10.png" width="598" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>Member insight with Ubuntu Pro &amp; esm-apps</title><link>https://community.element14.com/thread/53605?ContentTypeID=0</link><pubDate>Sun, 03 Sep 2023 20:47:11 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:d2c7e75d-7ec4-4c6d-86bf-0bcc2e350569</guid><dc:creator>colporteur</dc:creator><slash:comments>4</slash:comments><comments>https://community.element14.com/thread/53605?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/53605/member-insight-with-ubuntu-pro-esm-apps/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p&gt;I did a command line software update and came across esm-apps. Well there was a lot more printing on the screen than what I would expect so I gained some knowledge.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;The following security updates require Ubuntu Pro with &amp;#39;esm-apps&amp;#39; enabled:&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After some research I discovered Ubuntu Pro has been a service available since Jan 2023. For personal use (that&amp;#39;s me) the service is free for up to five machines. I&amp;#39;m thinking of dipping my toe in the water.&lt;/p&gt;
&lt;p&gt;My primary O/S is Ubuntu and has been for years. CentOS was what I used up until I retired. RedHat was the companies Linux, so CentOS allowed me to play in Linux for work without a licence. When I retired I switched to Ubuntu and haven&amp;#39;t look at any others.&lt;/p&gt;
&lt;p&gt;I&amp;#39;m new to the Ubuntu Pro party and was wondering if any other members who&amp;#39;s dedicated operating system (O/S) is Ubuntu have any insight.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>x2 or x4 clock problem ATxMEGA128C3</title><link>https://community.element14.com/thread/52438?ContentTypeID=0</link><pubDate>Thu, 09 Feb 2023 13:09:53 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:2d25b444-7c33-44c5-ab69-6123243a2433</guid><dc:creator>ElectroMiam</dc:creator><slash:comments>0</slash:comments><comments>https://community.element14.com/thread/52438?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/52438/x2-or-x4-clock-problem-atxmega128c3/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p&gt;&lt;span style="font-weight:400;"&gt;I am trying to get the clock out of pin 23 (PORTC7) of the ATxMEGA128C3 but some parameters are not working.&amp;nbsp;The clock is well generated by the code below but when going to x2 or x4, it stops.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:400;"&gt;The current initialization is like this:&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:400;"&gt;PORTC_PIN7CTRL |= 0x07;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:400;"&gt;PORTCFG_VPCTRLA = 0x10;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:400;"&gt;PORTCFG_VPCTRLB = 0x32;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:400;"&gt;PORTCFG_CLKEVOUT = 0b00000001;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:400;"&gt;But the clock multiplier on CLKOUTSEL (01 or 10) is not taken into account and disables the output.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:400;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-weight:400;"&gt;Someone would have an idea or an example to share with me to solve this problem ?&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>anyone investigating, learning or using the recent c++ or STL functionality?</title><link>https://community.element14.com/thread/52102?ContentTypeID=0</link><pubDate>Fri, 02 Dec 2022 17:56:26 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:107ecb29-65e7-48ac-a754-eb832bdb324a</guid><dc:creator>Jan Cumps</dc:creator><slash:comments>13</slash:comments><comments>https://community.element14.com/thread/52102?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/52102/anyone-investigating-learning-or-using-the-recent-c-or-stl-functionality/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p&gt;What the title says &lt;span class="emoticon" data-url="https://community.element14.com/cfs-file/__key/system/emoji/1f642.svg" title="Slight smile"&gt;&amp;#x1f642;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Since autumn 2021, I&amp;#39;m learning the c++ 20 language evolutions. Almost finished. Is anyone else into this?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>Tenma 72-8710A DSO software</title><link>https://community.element14.com/thread/10901?ContentTypeID=0</link><pubDate>Sat, 02 May 2020 16:44:29 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:1ff97822-a9f7-4c5f-8d08-8abf78ef29a9</guid><dc:creator>huroniatech</dc:creator><slash:comments>0</slash:comments><comments>https://community.element14.com/thread/10901?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/10901/tenma-72-8710a-dso-software/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p style="margin:0;"&gt;Are there any drivers for the software included with the 72-8710A for Windows 10 v1909? &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>Could not create SCTP socket</title><link>https://community.element14.com/thread/39139?ContentTypeID=0</link><pubDate>Tue, 03 Mar 2020 21:30:20 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:bbf984ef-fbd2-4ae8-859d-1f2d92e01759</guid><dc:creator>jaypeng</dc:creator><slash:comments>1</slash:comments><comments>https://community.element14.com/thread/39139?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/39139/could-not-create-sctp-socket/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p style="margin:0;"&gt; Dear all,&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;I do have an issue regarding SCTP socket. I am using srsLTE to setup test environment. srsEPC is acting as LTE core network and srsENB is acting as LTE access network. Both of two applications need to run on the same Ultrazed board. After I do local compile on a linux box which is Intel CPU supported, it works fine. But when I do cross compile for Ultrazed board which is for ARM platform and run srsEPC, I got error in console - &amp;quot;Could not create SCTP socket&amp;quot;.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;Below is the source code of srsEPC&lt;/p&gt;&lt;p style="margin:0;"&gt;&amp;nbsp; m_s1ap_log-&amp;gt;info(&amp;quot;S1-MME Initializing\n&amp;quot;);&lt;/p&gt;&lt;p style="margin:0;"&gt;&amp;nbsp; sock_fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);&lt;/p&gt;&lt;p style="margin:0;"&gt;&amp;nbsp; if (sock_fd == -1) {&lt;/p&gt;&lt;p style="margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_s1ap_log-&amp;gt;console(&amp;quot;Could not create SCTP socket\n&amp;quot;);&lt;/p&gt;&lt;p style="margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return -1;&lt;/p&gt;&lt;p style="margin:0;"&gt;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;I will very appreciate it if any expert can share your experience on how to fix it. Looking forward to your reply. &lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;Bests,&lt;/p&gt;&lt;p style="margin:0;"&gt;Jay&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>3D scanning software</title><link>https://community.element14.com/thread/9086?ContentTypeID=0</link><pubDate>Mon, 06 Aug 2018 06:38:27 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:6f3c096d-9dd5-4483-b53f-c8780d1271c9</guid><dc:creator>claytond</dc:creator><slash:comments>0</slash:comments><comments>https://community.element14.com/thread/9086?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/9086/3d-scanning-software/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p style="margin:0;"&gt;&amp;nbsp;&amp;nbsp; Hello! Are there any experienced people in 3d scanning? I&amp;#39;m looking for a compatible software for my Kinect V2 and all I&amp;#39;ve found so far is &lt;a class="jive-link-external-small" href="http://skanect.occipital.com/" rel="nofollow ugc noopener" target="_blank"&gt;Skanect&lt;/a&gt; (is not a good option for me cause of limited polygon export), &lt;a class="jive-link-external-small" href="https://lmi3d.com/kscan3d-software" rel="nofollow ugc noopener" target="_blank"&gt;KScan3D&lt;/a&gt; (but it seems like this project &amp;quot;died&amp;quot; for some reason) and &lt;a class="jive-link-external-small" href="https://www.artec3d.com/3d-software/artec-studio" rel="nofollow ugc noopener" target="_blank"&gt;Artec Studio&lt;/a&gt; (professinal software with 30day trial version)? Any help will be greatly appreciated.&lt;/p&gt;&lt;p style="margin:0;"&gt;&amp;nbsp;&amp;nbsp; Clayton&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>Ver 8.6.3 New CAM processor operation tutorial</title><link>https://community.element14.com/thread/32376?ContentTypeID=0</link><pubDate>Tue, 13 Mar 2018 02:10:08 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:c18c95d9-e07e-4f53-a2dc-f4245875ce22</guid><dc:creator>rdmurg</dc:creator><slash:comments>0</slash:comments><comments>https://community.element14.com/thread/32376?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/32376/ver-8-6-3-new-cam-processor-operation-tutorial/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p style="margin:0;"&gt;Upgraded to 8.6.3 and the CAM processor has changed.&lt;/p&gt;&lt;p style="margin:0;"&gt;is there some documentation on the changed operation&lt;/p&gt;&lt;p style="margin:0;"&gt;...Rod&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>Virtual Inc.</title><link>https://community.element14.com/thread/8597?ContentTypeID=0</link><pubDate>Thu, 15 Feb 2018 15:56:21 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:eb8bf303-7ee9-49b5-abb7-b9bbe13c5155</guid><dc:creator>bradnorwood</dc:creator><slash:comments>0</slash:comments><comments>https://community.element14.com/thread/8597?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/8597/virtual-inc/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p style="margin:0;"&gt;Hello,&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; I am assembling a virtual team across USA for software and web design. If anyone is interested in networking with our current 10 members, please reply. We are forming now, looking to work on projects from government, already registered and active with all federal agencies for NASA, DOD, DOE, DOA, and planning for state and local governments for a better day...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>PCBWeb Designer schematic issue</title><link>https://community.element14.com/thread/32267?ContentTypeID=0</link><pubDate>Sun, 11 Feb 2018 04:39:44 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:bf3c820f-81bd-4be1-beb1-dcc5043bf2b8</guid><dc:creator>nweller922</dc:creator><slash:comments>0</slash:comments><comments>https://community.element14.com/thread/32267?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/32267/pcbweb-designer-schematic-issue/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p style="margin:0;color:#000000;font-family:sans-serif;font-size:12.8px;"&gt;Hello,&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;color:#000000;font-family:sans-serif;font-size:12.8px;"&gt;I&amp;#39;ve been using PCBWeb Designer recently and happened across a problem I can&amp;#39;t find a solution to anywhere. I am trying to put the TE Connectivity 1-5499786-1 into my design, pulled from the Arrow parts catalog within PCBWeb. Its listing within the catalog shows two schematic symbols, A and B, which each make up half of the 60 pins in the connector. I have successfully placed the first symbol – J1A – but cannot for the life of me figure out how to place J1B.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;color:#000000;font-family:sans-serif;font-size:12.8px;"&gt;If anyone who knows anything about this software could shed some light on this situation, it would be much appreciated.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;color:#000000;font-family:sans-serif;font-size:12.8px;"&gt;Thank you!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>3D Printing Software</title><link>https://community.element14.com/thread/8228?ContentTypeID=0</link><pubDate>Thu, 26 Oct 2017 12:36:12 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:a4944633-9204-4983-af66-0be834c65006</guid><dc:creator>realjg21</dc:creator><slash:comments>4</slash:comments><comments>https://community.element14.com/thread/8228?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/8228/3d-printing-software/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p style="margin:0;"&gt;Does anyone have any experience with 3D printing software &lt;a class="jive-link-external-small" href="http://selfcad.com/" rel="nofollow ugc noopener" target="_blank"&gt;SelfCAD&lt;/a&gt;. My class has been using Tinkercad and need something with sculpting and dimensions. Its all free for Class&amp;#39;s and browser based which will allow me to get it on all of our computers without calling IT &lt;span&gt;&lt;a href="https://community.element14.com/resized-image/__size/16x16/__key/communityserver-discussions-components-files/126/contentimage_5F00_1.png"&gt;&lt;img alt="image" src="https://community-storage.element14.com/communityserver-components-secureimagefileviewer/communityserver/discussions/components/files/126/contentimage_1.png-16x16.png?sv=2016-05-31&amp;amp;sr=b&amp;amp;sig=ZG0bULIkvZ04odcShVkbMW9TxWNlV4PO3pouZjb13K4%3D&amp;amp;se=2026-05-23T23%3A59%3A59Z&amp;amp;sp=r&amp;amp;_=zGEM7pHL10Vt71gae75OdA==" style="max-height: 16px;max-width: 16px;" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>WEBINAR: Why using an SDK for automotive development?</title><link>https://community.element14.com/thread/8048?ContentTypeID=0</link><pubDate>Wed, 06 Sep 2017 15:39:53 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:6d97d01c-28fc-4656-b5d1-f003e3001263</guid><dc:creator>yoSoyTono</dc:creator><slash:comments>0</slash:comments><comments>https://community.element14.com/thread/8048?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/8048/webinar-why-using-an-sdk-for-automotive-development/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p style="margin:0;"&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;font-weight:bold;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;SDK &lt;/span&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;is the acronym for “&lt;/span&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;font-style:italic;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;Software Development Kit&lt;/span&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;” and usually refers to a set of software development tools that allow engineers to create systems and produce applications for hardware kits, software frameworks, or development platforms. SDKs are implementation tools for developing &lt;/span&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;source-codes for almost any software modern users are interacting with.&lt;/span&gt;&lt;/span&gt;&lt;span class="LineBreakBlob DragDrop BlobObject SCXW97114953" style="color:#000000;font-size:9pt;"&gt;&lt;span class="SCXW97114953"&gt; &lt;/span&gt;&lt;br class="SCXW97114953" /&gt;&lt;/span&gt;&lt;span class="EmptyTextRun SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:11pt;"&gt;&lt;/span&gt;&lt;span class="LineBreakBlob DragDrop BlobObject SCXW97114953" style="color:#000000;font-size:11pt;"&gt;&lt;span class="SCXW97114953"&gt; &lt;/span&gt;&lt;br class="SCXW97114953" /&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;SDKs usually contain &lt;/span&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;font-weight:bold;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;APIs&lt;/span&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt; (&lt;/span&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;font-style:italic;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;Application Programming Interfaces&lt;/span&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;) as they are required when an SDK is being used to create an application that needs to connect with other application. An API typically communicates and &lt;/span&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;can&lt;/span&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;not&lt;/span&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt; be used to create applications by itself. APIs allow application functioning within the SDKs defined parameters.&lt;/span&gt;&lt;/span&gt;&lt;span class="LineBreakBlob DragDrop BlobObject SCXW97114953" style="color:#000000;font-size:9pt;"&gt;&lt;span class="SCXW97114953"&gt; &lt;/span&gt;&lt;br class="SCXW97114953" /&gt;&lt;/span&gt;&lt;span class="EmptyTextRun SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:11pt;"&gt;&lt;/span&gt;&lt;span class="LineBreakBlob DragDrop BlobObject SCXW97114953" style="color:#000000;font-size:11pt;"&gt;&lt;span class="SCXW97114953"&gt; &lt;/span&gt;&lt;br class="SCXW97114953" /&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;SDK commonly provides a package of tools (libraries, APIs, code samples, documentation, and guides) to create software applications on a dedicated platform. Engineers get SDKs from a system developer for both easing their development process and fostering an ecosystem for them. SDKs are a driving force to expedite time-to-market for application development, that is especially useful in stringent industries, like transportation.&lt;/span&gt;&lt;/span&gt;&lt;span class="LineBreakBlob DragDrop BlobObject SCXW97114953" style="color:#000000;font-size:9pt;"&gt;&lt;span class="SCXW97114953"&gt; &lt;/span&gt;&lt;br class="SCXW97114953" /&gt;&lt;/span&gt;&lt;span class="EmptyTextRun SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:11pt;"&gt;&lt;/span&gt;&lt;span class="LineBreakBlob DragDrop BlobObject SCXW97114953" style="color:#000000;font-size:11pt;"&gt;&lt;span class="SCXW97114953"&gt; &lt;/span&gt;&lt;br class="SCXW97114953" /&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;NXP has a free-early release for a full automotive-grade SDK that supports the Power Architecture&lt;span class="emoticon" data-url="https://community.element14.com/cfs-file/__key/system/emoji/00ae.svg" title="Registered"&gt;&amp;#x00ae;&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;a class="jive-link-external-small" href="http://www.nxp.com/products/automotive-products/microcontrollers-and-processors/32-bit-power-architecture/ultra-reliable-mpc57xx-32-bit-automotive-industrial-microcontrollers-mcus/ultra-reliable-mcus-for-automotive-industrial-control-and-gateway:MPC574xB-C-G" rel="nofollow ugc noopener" style="font-family:&amp;#39;Segoe UI&amp;#39;, Arial, Verdana, sans-serif;font-size:12px;color:inherit;" target="_blank"&gt;&lt;span class="Underlined SCXW97114953 TextRun" lang="EN-US" style="color:#0563c1;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;MPC5748G MCU&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;font-weight:bold;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;focused on gateway solutions. Their SDK includes software stacks &amp;amp; middleware (TCP/IP, Ethernet AVB, USB, and SDHC) and also offers Safety and Security software to comply with Functional Safety requirements.&lt;/span&gt;&lt;/span&gt;&lt;span class="LineBreakBlob DragDrop BlobObject SCXW97114953" style="color:#000000;font-size:9pt;"&gt;&lt;span class="SCXW97114953"&gt; &lt;/span&gt;&lt;br class="SCXW97114953" /&gt;&lt;/span&gt;&lt;span class="EmptyTextRun SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:11pt;"&gt;&lt;/span&gt;&lt;span class="LineBreakBlob DragDrop BlobObject SCXW97114953" style="color:#000000;font-size:11pt;"&gt;&lt;span class="SCXW97114953"&gt; &lt;/span&gt;&lt;br class="SCXW97114953" /&gt;&lt;/span&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;They are hosting a webinar (Wednesday, September 13th 10:00 am EDT) to show the MPC57 family SDK and explain how development projects can be started right away with graphical-based configurations in their &lt;/span&gt;&lt;/span&gt;&lt;a class="jive-link-external-small" href="http://www.nxp.com/products/automotive-products/microcontrollers-and-processors/arm-mcus-and-mpus/ea-series-automotive-m0-plus/s32-design-studio-ide:S32DS" rel="nofollow ugc noopener" style="font-family:&amp;#39;Segoe UI&amp;#39;, Arial, Verdana, sans-serif;font-size:12px;color:inherit;" target="_blank"&gt;&lt;span class="Underlined SCXW97114953 TextRun" lang="EN-US" style="color:#0563c1;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;S32 Design Studio IDE&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;. &lt;/span&gt;&lt;/span&gt;&lt;span class="LineBreakBlob DragDrop BlobObject SCXW97114953" style="color:#000000;font-size:9pt;"&gt;&lt;span class="SCXW97114953"&gt; &lt;/span&gt;&lt;br class="SCXW97114953" /&gt;&lt;/span&gt;&lt;span class="EmptyTextRun SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:11pt;"&gt;&lt;/span&gt;&lt;span class="LineBreakBlob DragDrop BlobObject SCXW97114953" style="color:#000000;font-size:11pt;"&gt;&lt;span class="SCXW97114953"&gt; &lt;/span&gt;&lt;br class="SCXW97114953" /&gt;&lt;/span&gt;&lt;span class="EmptyTextRun SCXW97114953 TextRun" style="color:#000000;font-size:11pt;"&gt;&lt;/span&gt;&lt;a class="jive-link-external-small" href="https://event.webcasts.com/starthere.jsp?ei=1155790" rel="nofollow ugc noopener" style="font-family:&amp;#39;Segoe UI&amp;#39;, Arial, Verdana, sans-serif;font-size:12px;color:inherit;" target="_blank"&gt;&lt;span class="Underlined SCXW97114953 TextRun" lang="EN-US" style="color:#0563c1;font-weight:bold;font-size:9pt;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt;Register today&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="SCXW97114953 TextRun" lang="EN-US" style="color:#000000;font-size:9pt;font-weight:bold;"&gt;&lt;span class="NormalTextRun SCXW97114953" style="background-color:inherit;"&gt; to learn how to simplify and accelerate application development with an SDK for Power Architecture MCUs!&lt;/span&gt;&lt;/span&gt;&lt;span class="SCXW97114953 EOP" style="color:#000000;font-size:9pt;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>Suggestions on the Best Free EDA tool for Beginners</title><link>https://community.element14.com/thread/28906?ContentTypeID=0</link><pubDate>Fri, 06 Nov 2015 04:24:23 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:58c9a2a3-7008-4e1d-b1b9-ae8a753c9ec7</guid><dc:creator>hadleywhite</dc:creator><slash:comments>7</slash:comments><comments>https://community.element14.com/thread/28906?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/28906/suggestions-on-the-best-free-eda-tool-for-beginners/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p style="margin:0;"&gt;　　Hello everyone, just a quick opinion survey, what EDA do you think is best and why? Something that is hopefully often updated and is stable. I have looked into &lt;span style="font-size:13.3333px;"&gt;&lt;a class="jive-link-external-small" href="https://easyeda.com/" rel="nofollow ugc noopener" target="_blank"&gt;EasyEDA&lt;/a&gt;&lt;/span&gt;&amp;nbsp; and &lt;span style="font-size:13.3333px;"&gt;Design spark&lt;/span&gt;, but are there any other EDAs there?&lt;/p&gt;&lt;p style="margin:0;"&gt;　　Opinions are highly appreciated, Thanks&lt;span&gt;&lt;a href="https://community.element14.com/resized-image/__size/16x16/__key/communityserver-discussions-components-files/126/8508.contentimage_5F00_1.png"&gt;&lt;img alt="image" src="https://community-storage.element14.com/communityserver-components-secureimagefileviewer/communityserver/discussions/components/files/126/8508.contentimage_1.png-16x16.png?sv=2016-05-31&amp;amp;sr=b&amp;amp;sig=Zmo8hCSXtt1A%2B5AlE%2FhNKKcllIQun4W17AGy4do6BBE%3D&amp;amp;se=2026-05-23T23%3A59%3A59Z&amp;amp;sp=r&amp;amp;_=zGEM7pHL10Vt71gae75OdA==" style="max-height: 16px;max-width: 16px;" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>Java</title><link>https://community.element14.com/thread/28688?ContentTypeID=0</link><pubDate>Wed, 30 Sep 2015 18:38:50 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:fa4f43de-d0f5-4bf5-8524-59ba84fc94b0</guid><dc:creator>nick123</dc:creator><slash:comments>1</slash:comments><comments>https://community.element14.com/thread/28688?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/28688/java/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p style="margin:0;"&gt;I have a Java Circuit simulator that I used on Windows, When I had it and It worked just fine. When I migrated to linux, I installed Java Runtime 6 which Let&amp;#39;s me run java apps. Well, Now my Java Circuit simulator looks like This:&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;This makes me mad, as I used this on&amp;nbsp; a daily basis just to have fun, and design projects I&amp;#39;m planning and to experiment and learn.&lt;/p&gt;&lt;p style="margin:0;"&gt;Does anyone else use this simulator?&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;&lt;span&gt;&lt;a href="https://community.element14.com/resized-image/__size/620x461/__key/communityserver-discussions-components-files/126/0083.contentimage_5F00_61266.png"&gt;&lt;img alt="image" src="https://community-storage.element14.com/communityserver-components-secureimagefileviewer/communityserver/discussions/components/files/126/0083.contentimage_61266.png-620x461.png?sv=2016-05-31&amp;amp;sr=b&amp;amp;sig=b7dqt8DrOcX7ANz2nis4AMB1r3PuFCXTEclYarrpDHA%3D&amp;amp;se=2026-05-23T23%3A59%3A59Z&amp;amp;sp=r&amp;amp;_=CtcT1MxAvUzzKqX3FFoCGA==" style="max-height: 461px;max-width: 620px;" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;"&gt;It&amp;#39;s broken, I doesn&amp;#39;t work, The menus have gone. Could it have something to do with Java Runtime? or The OS.&lt;/p&gt;&lt;p style="margin:0;"&gt;This worked on Windows Flawlessly.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>Software Guys, How Does This Happen?</title><link>https://community.element14.com/thread/27987?ContentTypeID=0</link><pubDate>Wed, 03 Jun 2015 06:05:57 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:fe5ea28d-81d4-4137-acd0-abb40e56aea4</guid><dc:creator>michaelwylie</dc:creator><slash:comments>0</slash:comments><comments>https://community.element14.com/thread/27987?ContentTypeID=0</comments><wfw:commentRss>https://community.element14.com/products/devtools/software/f/forum/27987/software-guys-how-does-this-happen/rss?ContentTypeId=0</wfw:commentRss><description>&lt;p style="margin:0;"&gt;O.K. software guys, you&amp;#39;re up. This happens too often for me. Seriously, though, how does this happen? Three tabs open: Element14, GMail, and Twitter.&lt;/p&gt;&lt;p style="margin:0;padding:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin:0;text-align:center;"&gt;&lt;span&gt;&lt;a href="https://community.element14.com/resized-image/__size/620x513/__key/communityserver-discussions-components-files/126/5861.contentimage_5F00_56569.png"&gt;&lt;img alt="image" src="https://community-storage.element14.com/communityserver-components-secureimagefileviewer/communityserver/discussions/components/files/126/5861.contentimage_56569.png-620x513.png?sv=2016-05-31&amp;amp;sr=b&amp;amp;sig=QckMLbkYE4d25%2B9J8qmJCpw0yfY22%2FpRle5Zaa9pBIA%3D&amp;amp;se=2026-05-23T23%3A59%3A59Z&amp;amp;sp=r&amp;amp;_=T/1Ouf/MWpVhNOvs3kgK9A==" style="max-height: 513px;max-width: 620px;" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>