This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

uint8_t type variables behave unexpectedly on nRF832? converting to int32_t

Stack - nRF52 DK, SDK 15.0.0, Segger Embedded Studio, Windows. Using code examples described below.

So my high level goal is to read data from registers in an I2C sensor and send these values via Bluetooth. I'm reading I2C data using "nrf_drv_twi" rx and tx, which stores the read sensor data in variables of type uint8_t. To send data via bluetooth, I'm working out of this tutorial (https://devzone.nordicsemi.com/tutorials/b/bluetooth-low-energy/posts/ble-characteristics-a-beginners-tutorial), which in step "Step 3.F, Update the characteristic with temperature data", passes data as int32_t type variables. I'm having a lot of problems converting the uint8_t variables into any variables that aren't uint8_t (e.g. program behaves unexpectedly when storing values in uint16_t, int8_t, int32_t, etc).

So for example, I created a standalone project in Eclipse to check my sanity, just debugged locally with no build target:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main(void) {
	uint8_t a = 0x12;
	uint8_t b = 0x34;
	int16_t c = 0;
	c = a;
	c = c<<8;
	c = c + b;
	return EXIT_SUCCESS;
}

When debugging, variables expect exactly as I expect. After all the code is run, the debug console shows:

this is my desired output. essentially, I want to "concatenate" all the values together and parse after sending to an iOS app.

However, running the same code snippet contained in main() within a project built for the nRF52DK gives bizarre results:

I'm now noticing other weird behavior. When I first start debugging, a/b/c all have these values to start. when I change a/b to other values, e.g. 0x56 / 0x78, the debug values in the watch list remain unchanged even after those lines of code have been run. I tried setting breakpoints on each of the lines where they're running, but SES won't stop on those breakpoints and catches on one a couple lines down...

What can I do to get this code to behave as it does when building in Eclipse without a target?

Or maybe I can circumvent this problem entirely. Is there an easier way to send TWI sensor data via BLE?

Parents
  • Two things:

    First, you might want to make c a uint16_t rather than int16_t. If you make a and b 0xb9, then the result 0xb9b9 is larger than 32767, which is the largest signed value you can represent with a signed 16-bit integer. This may lead to some confusion.

    Second, in your code snippet, you're not doing anything with c. If you're building your project with optimization enabled, then the compiler will notice that the result of adding c and b is never used, and it will optimize the code away. This would explain setting breakpoints at those lines of code has no effect: the compiler is silently discarding them because it knows they have no effect. Even if you do something like add a printf() to force the compiler to use c, a and b are assigned constant values, which means the compiler might still optimize things (it is possible for the compiler to determine what c would be at compile time, so it may just print a constant value.)

    To defeat this, you can try adding the volatile keyword to the declarations for a, b and c. This should force the compiler to generate code for these lines.

Reply
  • Two things:

    First, you might want to make c a uint16_t rather than int16_t. If you make a and b 0xb9, then the result 0xb9b9 is larger than 32767, which is the largest signed value you can represent with a signed 16-bit integer. This may lead to some confusion.

    Second, in your code snippet, you're not doing anything with c. If you're building your project with optimization enabled, then the compiler will notice that the result of adding c and b is never used, and it will optimize the code away. This would explain setting breakpoints at those lines of code has no effect: the compiler is silently discarding them because it knows they have no effect. Even if you do something like add a printf() to force the compiler to use c, a and b are assigned constant values, which means the compiler might still optimize things (it is possible for the compiler to determine what c would be at compile time, so it may just print a constant value.)

    To defeat this, you can try adding the volatile keyword to the declarations for a, b and c. This should force the compiler to generate code for these lines.

Children
No Data
Related