<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.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>Data from callback initialiser to callback?</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/12087/data-from-callback-initialiser-to-callback</link><description>I have a bluetooth service which I want to have to initialise a TWI transaction (using app_twi). I want to get the data back from the TWI transaction, but I can&amp;#39;t figure quite the best way to do that. I have the ble service and TWI working separately</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 29 Feb 2016 06:36:09 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/12087/data-from-callback-initialiser-to-callback" /><item><title>RE: Data from callback initialiser to callback?</title><link>https://devzone.nordicsemi.com/thread/45751?ContentTypeID=1</link><pubDate>Mon, 29 Feb 2016 06:36:09 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:485d54fa-2fd9-4d0d-b97d-03ba223e5699</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;You are right, of course. This is actually a typo in my comment. You should keep the transaction static, but remove const and set &lt;code&gt;transaction.p_user_data&lt;/code&gt; outside the initialization, as described (i will update the comment to keep it static). The reason for this is as describer in your quote above, that the memory must be valid after the function has returned, thus it cannot be located on the stack.&lt;/p&gt;
&lt;p&gt;I see no problem with moving your &lt;code&gt;ble_os_t m_our_service&lt;/code&gt;. As long as you can access it from where you need it, you should be OK.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Data from callback initialiser to callback?</title><link>https://devzone.nordicsemi.com/thread/45749?ContentTypeID=1</link><pubDate>Sun, 28 Feb 2016 16:51:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:171f900b-fd6a-4d71-91a6-e6a1001f324a</guid><dc:creator>Sensors</dc:creator><description>&lt;p&gt;As a follow up to your comment about removing the &lt;code&gt;static&lt;/code&gt; from the transaction...&lt;/p&gt;
&lt;p&gt;I went back to some older code and found this comment:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// [these structures have to be &amp;quot;static&amp;quot; - they cannot be placed on stack
//  since the transaction is scheduled and these structures most likely
//  will be referred after this function returns]
&lt;/code&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Data from callback initialiser to callback?</title><link>https://devzone.nordicsemi.com/thread/45750?ContentTypeID=1</link><pubDate>Fri, 26 Feb 2016 14:13:36 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:15904715-6b14-4167-8284-9dd1a2a5bbdc</guid><dc:creator>Sensors</dc:creator><description>&lt;p&gt;Accidentally converted this to an answer.&lt;/p&gt;
&lt;p&gt;What I was &lt;em&gt;trying&lt;/em&gt; to do, was ask about the dangers of making the &lt;code&gt;ble_os_t m_our_service&lt;/code&gt; local to service.c.&lt;/p&gt;
&lt;p&gt;I figure by doing this I remove the pain of having to pass that in, it&amp;#39;s then accessible to every function, and I can&amp;#39;t see much reason to instantiate it in main.c when it&amp;#39;s only ever used in the service file.&lt;/p&gt;
&lt;p&gt;My service file would then look like this: &lt;a href="https://gist.github.com/anonymous/02be1cb5af43b5145fb5"&gt;gist.github.com/.../02be1cb5af43b5145fb5&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Data from callback initialiser to callback?</title><link>https://devzone.nordicsemi.com/thread/45748?ContentTypeID=1</link><pubDate>Thu, 25 Feb 2016 13:53:45 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:67a49206-424a-4562-8c49-ba87f6db760d</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Yes, this is a sensible solution given that you do not need to schedule more than one transaction at a time. You should also remember to make sure that you poll the flag in a lower priority than you update the flag with, if not you risk a deadlock.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Data from callback initialiser to callback?</title><link>https://devzone.nordicsemi.com/thread/45747?ContentTypeID=1</link><pubDate>Thu, 25 Feb 2016 13:01:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1d3a9e7b-8948-4641-9757-fa0377696678</guid><dc:creator>Sensors</dc:creator><description>&lt;p&gt;Though polling isn&amp;#39;t ideal, it should only cause a polling delay if I&amp;#39;ve broken the rule of trying to sample faster than the sampling period.&lt;/p&gt;
&lt;p&gt;Does this sounds like a reasonably safe solution?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Data from callback initialiser to callback?</title><link>https://devzone.nordicsemi.com/thread/45746?ContentTypeID=1</link><pubDate>Thu, 25 Feb 2016 13:01:03 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1c1f2bc1-1ddb-4cac-99b3-f239fc65fdb5</guid><dc:creator>Sensors</dc:creator><description>&lt;p&gt;Okay, I&amp;#39;ll try that for now. If I was making other transfers at different frequencies they would be instantiated in relation to other services in their own respective files. That would mean I&amp;#39;d have to have a new instance of &lt;code&gt;app_twi_transaction_t&lt;/code&gt; anyway.&lt;/p&gt;
&lt;p&gt;In this case the only thing that still may cause an issue, as you pointed out, would be making another call to &lt;code&gt;rh_read()&lt;/code&gt;. The transfers should be instantiated by a timer, so I just need to make sure the timer can&amp;#39;t tick over faster than the sample period for each sensor. To avoid the scenario of corruption, I suppose I could just have a variable local to each service file to confirm the callback has completed, and in &lt;code&gt;rh_read()&lt;/code&gt; do something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while(!callback_complete); 
APP_ERROR_CHECK(app_twi_schedule(&amp;amp;m_app_twi, &amp;amp;transaction));
&lt;/code&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Data from callback initialiser to callback?</title><link>https://devzone.nordicsemi.com/thread/45745?ContentTypeID=1</link><pubDate>Thu, 25 Feb 2016 12:08:30 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c4da1d12-895a-48b9-8c92-a33c1bcd913b</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;The problem here is that the &lt;code&gt;transaction&lt;/code&gt; is static, therefore the initializer is only run &lt;em&gt;once&lt;/em&gt;, and cannot be dynamic. You &lt;em&gt;can&lt;/em&gt; remove &lt;code&gt;const&lt;/code&gt;, and set &lt;code&gt;transaction.p_user_data&lt;/code&gt; outside the static initialization. However, this may be dangerous in your case, as that means that if you make a subsequent call to your &lt;code&gt;rh_read()&lt;/code&gt; function before the previous transfer has completed, you will modify (corrupt) the transfer struct that is to be used in the previously scheduled transaction.&lt;/p&gt;
&lt;p&gt;Therefore, if you want to schedule multiple transfers simultaneously, you need multiple instances of &lt;code&gt;app_twi_transaction_t&lt;/code&gt;. How you do this depend on your code, but it does not have to be complex.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Data from callback initialiser to callback?</title><link>https://devzone.nordicsemi.com/thread/45744?ContentTypeID=1</link><pubDate>Wed, 24 Feb 2016 15:46:45 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:da07b9e4-43d8-46fb-8afd-3ddcd6e076d3</guid><dc:creator>Sensors</dc:creator><description>&lt;p&gt;This is how I tried to do it to get the error that &amp;#39;initialiser is not a compile-time constant&amp;#39;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void rh_read(ble_os_t *m_our_service)
{
	
	static app_twi_transfer_t transfers[] = 
	{
		SHT21_RH_READ(&amp;amp;m_sht21_buffer[0])
	};
	static app_twi_transaction_t const transaction =
	{
	.callback            = rh_read_callback,
	.p_user_data         = &amp;amp;m_our_service,
	.p_transfers         = transfers,
	.number_of_transfers = sizeof(transfers) / sizeof(transfers[0])
	};
	
	APP_ERROR_CHECK(app_twi_schedule(&amp;amp;m_app_twi, &amp;amp;transaction));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This function is called from main.c, where the &lt;code&gt;ble_os_t m_our_service;&lt;/code&gt; is also instantiated.&lt;/p&gt;
&lt;p&gt;EDIT: the app_twi_transaction_t is populated as a &lt;code&gt;const&lt;/code&gt;. I don&amp;#39;t know why, but that&amp;#39;s what it was in the app_twi example so I didn&amp;#39;t want to change it.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Data from callback initialiser to callback?</title><link>https://devzone.nordicsemi.com/thread/45743?ContentTypeID=1</link><pubDate>Wed, 24 Feb 2016 12:58:17 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9d2e5b93-0df3-4663-ba57-613bff72c1af</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;How do you populate the &lt;code&gt;app_twi_transaction_t&lt;/code&gt; instance and call &lt;code&gt;app_twi_schedule()&lt;/code&gt;? I do not see why it should be a requirement that the pointer is a constant.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Data from callback initialiser to callback?</title><link>https://devzone.nordicsemi.com/thread/45742?ContentTypeID=1</link><pubDate>Wed, 24 Feb 2016 12:38:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:90a00078-0737-4fe2-8100-0c32884b9543</guid><dc:creator>Sensors</dc:creator><description>&lt;p&gt;I can&amp;#39;t pass it as &lt;code&gt;p_user_data&lt;/code&gt; in the transaction data since an &lt;code&gt;m_our_service&lt;/code&gt; argument passed into the function is &amp;#39;not a compile time constant&amp;#39;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Data from callback initialiser to callback?</title><link>https://devzone.nordicsemi.com/thread/45741?ContentTypeID=1</link><pubDate>Wed, 24 Feb 2016 12:22:35 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6f60d97e-0119-4e04-8c8a-c3a06f6068d9</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;The TWI transaction manager is intended for this type of situations, and &lt;code&gt;app_twi_schedule()&lt;/code&gt; should do the trick. As stated in the &lt;a href="http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v11.0.0/lib_app_twi.html"&gt;documentation&lt;/a&gt;, transactions can be requested from different contexts, including interrupt handlers. The library takes care of proper synchronization.&lt;/p&gt;
&lt;p&gt;You should be able to pass user data between where you schedule the transaction and the callback using &lt;code&gt;p_user_data&lt;/code&gt; - it is exactly what it is intended for. Why can you not do that?&lt;/p&gt;
&lt;p&gt;Static variables, such as your &lt;code&gt;m_our_service&lt;/code&gt;, cannot be accessed outside that file. There are a number of ways of managing this however. The dirty way, which I do not recommend, is to remove the &lt;code&gt;static&lt;/code&gt; keyword from the declaration, and declare the same variable name as &lt;code&gt;extern&lt;/code&gt; where you need it (or in a header file that you include). This would then be a global variable. Another possible approach, which is much cleaner, is to move the data you want to share to a separate .c file. Then you can create an accompanying header file with an accessor function (à la &lt;code&gt;m_our_service_t * our_service_ptr_get() {return &amp;amp;m_our_service;};&lt;/code&gt;).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>