ESP8266 repeatedly throws Exception(0) - exception

I am making an IoT weighing scale with a load cell connected to an Arduino. The Arduino then sends data to an ESP8266 connected by serial which would subsequently update my database on Google's Firebase. However, my ESP8266 throws an exception when it starts. Half of the time it works perfectly fine. The other half throws the following error when I connect my serial cable. This error runs repeatedly so I think it might be an error inside void loop() but I can't seem to figure out what exactly is the problem. Also, my cables are not the best quality but I am not sure if that affects anything
Exception (0):
epc1=0x4025803e epc2=0x00000000 epc3=0x00000000 excvaddr=0x0000000a depc=0x00000000
>>>stack>>>
ctx: sys
sp: 3fffe0c0 end: 3fffffb0 offset: 01a0
3fffe260: 00000000 00000000 00000000 00000000
3fffe270: 00000000 00000000 00000000 40104b72
3fffe280: 40104b54 3fffc100 0000001a 00000000
3fffe290: 00000000 4025803e 00000000 00000000
3fffe2a0: 400005e1 00000000 00000000 00000000
3fffe2b0: 4025803e 00000033 00000010 00000000
3fffe2c0: 4025803e 40266fd0 00000000 00000001
3fffe2d0: fbf8ffff 04000002 3feffe00 00000100
3fffe2e0: 0000001a 00000018 04000102 40104b54
3fffe2f0: 3fffc100 0000001a 00000000 00000000
3fffe300: 00000000 00000000 00000000 00000000
3fffe310: 00000000 00000000 00000000 00000000
3fffe320: 00000000 00000000 00000000 00000000
3fffe330: 00000000 00000000 00000000 00000000
3fffe340: 00000000 00000000 00000000 00000000
3fffe350: 00000000 00000000 00000000 00000000
3fffe360: 00000000 00000000 00000000 00000000
3fffe370: 00000000 00000000 00000000 00000000
3fffe380: 00000000 00000000 00000000 00000000
3fffe390: 00000000 00000000 00000000 00000000
3fffe3a0: 00000000 00000000 00000000 00000000
3fffe3b0: 00000000 00000000 00000000 00000000
3fffe3c0: 00000000 00000000 00000000 40104b72
3fffe3d0: 40104b54 3fffc100 0000001a 00000000
3fffe3e0: 00000000 4025803e 00000000 00000000
3fffe3f0: 400005e1 00000000 00000000 00000000
3fffe400: 4025803e 00000033 00000010 00000000
3fffe410: 4025803e 40266fd0 00000000 00000001
3fffe420: fbf8ffff 04000002 3feffe00 00000100
3fffe430: 0000001a 00000018 04000102 40104b54
3fffe440: 3fffc100 0000001a 00000000 00000000
3fffe450: 00000000 00000000 00000000 00000000
3fffe460: 00000000 00000000 00000000 00000000
3fffe470: 00000000 00000000 00000000 00000000
3fffe480: 00000000 00000000 00000000 00000000
3fffe490: 00000000 00000000 00000000 00000000
3fffe4a0: 00000000 00000000 00000000 00000000
3fffe4b0: 00000000 00000000 00000000 00000000
3fffe4c0: 00000000 00000000 00000000 00000000
3fffe4d0: 00000000 00000000 00000000 00000000
3fffe4e0: 00000000 00000000 00000000 00000000
3fffe4f0: 00000000 00000000 00000000 00000000
3fffe500: 00000000 00000000 00000000 00000000
3fffe510: 00000000 00000000 00000000 40104b72
3fffe520: 40104b54 3fffc100 0000001a 00000000
3fffe530: 00000000 4025803e 00000000 00000000
3fffe540: 400005e1 00000000 00000000 00000000
3fffe550: 4025803e 00000033 00000010 00000000
3fffe560: 4025803e 40266fd0 00000000 00000001
3fffe570: fbf8ffff 04000002 3feffe00 00000100
3fffe580: 0000001a 00000018 04000102 40104b54
3fffe590: 3fffc100 0000001a 00000000 00000000
3fffe5a0: 00000000 00000000 00000000 00000000
3fffe5b0: 00000000 00000000 00000000 00000000
3fffe5c0: 00000000 00000000 00000000 00000000
3fffe5d0: 00000000 00000000 00000000 00000000
3fffe5e0: 00000000 00000000 00000000 00000000
3fffe5f0: 00000000 00000000 00000000 00000000
3fffe600: 00000000 00000000 00000000 00000000
3fffe610: 00000000 00000000 00000000 00000000
3fffe620: 00000000 00000000 00000000 00000000
3fffe630: 00000000 00000000 00000000 00000000
3fffe640: 00000000 00000000 00000000 00000000
3fffe650: 00000000 00000000 00000000 00000000
3fffe660: 00000000 00000000 00000000 40104b72
3fffe670: 40104b54 3fffc100 0000001a 00000000
3fffe680: 00000000 4025803e 00000000 00000000
3fffe690: 400005e1 00000000 00000000 00000000
3fffe6a0: 4025803e 00000033 00000010 00000000
3fffe6b0: 4025803e 40266fd0 00000000 00000001
3fffe6c0: fbf8ffff 04000002 3feffe00 00000100
3fffe6d0: 0000001a 00000018 04000102 40104b54
3fffe6e0: 3fffc100 0000001a 00000000 00000000
3fffe6f0: 00000000 00000000 00000000 00000000
3fffe700: 00000000 00000000 00000000 00000000
3fffe710: 00000000 00000000 00000000 00000000
3fffe720: 0af8a400 00000001 647a4f3a 00000000
3fffe730: 0af8a400 00000001 647a4f3a 00000000
3fffe740: 00000000 00000000 00000000 00000000
3fffe750: 00000000 00000000 00000000 00000000
3fffe760: 00000000 00000000 00000000 00000000
3fffe770: 00000000 15f14800 000015f1 00004800
3fffe780: 0000c8f4 000215f1 00000000 00000000
3fffe790: c8f49e74 00009e74 00000000 00000000
3fffe7a0: 00000000 00000000 00000000 00000000
3fffe7b0: 00000000 00000000 00000000 40104b72
3fffe7c0: 40104b54 3fffc100 0000001a 00000000
3fffe7d0: 00000000 4025803e 647a4f3a 00000000
3fffe7e0: 400005e1 00000002 000000ad 00000000
3fffe7f0: 4025803e 00000033 00000010 004e11a5
3fffe800: 4025803e 40266fd0 00000000 00000001
3fffe810: fbf8ffff 04000002 3feffe00 00000100
3fffe820: 0000001a 00000018 04000102 40104b54
3fffe830: 3fffc100 0000001a 00000000 00000000
3fffe840: ffffffff 00000000 00000001 00000000
3fffe850: 00005201 00000000 4026492a ffffffff
3fffe860: 00000000 fffffffd 00000000 00000000
3fffe870: 00000000 00000000 00000001 40006545
3fffe880: 00000000 00000000 00000000 40006545
3fffe890: 00000001 00000001 00000000 40006589
3fffe8a0: 00000000 3fffe922 00000000 40264b1e
3fffe8b0: 40264b32 00000001 00000000 00000000
3fffe8c0: 3fffe8d3 00000000 00000000 40006545
3fffe8d0: 000005e0 3fffe918 3ffef288 40226a30
3fffe8e0: 00000608 00000000 00000000 00000000
3fffe8f0: 00000000 00000020 402532c3 00000001
3fffe900: ffffffff 00000000 3ffe8e91 40104b72
3fffe910: 40104b54 3fffc100 0000001a 00000000
3fffe920: 00000000 4025803e 00000020 401001a4
3fffe930: 400005e1 00000000 00000000 401015bc
3fffe940: 4025803e 00000033 00000010 3ffed11c
3fffe950: 4025803e 40266fd0 00000000 00000001
3fffe960: fbf8ffff 04000002 3feffe00 00000100
3fffe970: 0000001a 00000018 04000102 40104b54
3fffe980: 3fffc100 0000001a 00000000 00000000
3fffe990: 00000000 00000002 3ffee8a0 402660a3
3fffe9a0: c0266089 7fffffff 00000002 40211114
3fffe9b0: 3ffe8765 00000002 3ffee898 4026608a
3fffe9c0: 00000000 7fffffff 3fff17ec 3ffed29c
3fffe9d0: 00000000 3ffeea48 3ffe8765 40222cde
3fffe9e0: 3fffea00 3ffeea1c 3ffe8765 3ffeea78
3fffe9f0: 3ffe8765 3ffeea9c 3ffe8765 40222cde
3fffea00: 3fffea20 3ffeebb4 3ffeeb24 3ffed29c
3fffea10: 3ffe8765 00000000 3ffee678 402063e8
3fffea20: 40247cf1 00000000 3ffeeaa8 402037d8
3fffea30: ffffffff 00000000 3ffeeaa8 402109af
3fffea40: 00000000 00000000 00000001 401001a4
3fffea50: 3ffedffc 3ffee028 3ffe8abc 40104b72
3fffea60: 40104b54 3fffc100 0000001a 00000000
3fffea70: 00000000 4025803e 00000001 402587be
3fffea80: 400005e1 00001000 40104e0d 000003fd
3fffea90: 4025803e 00000033 00000010 00000000
3fffeaa0: 4025803e 40266fd0 00000000 00000001
3fffeab0: fbf8ffff 04000002 3feffe00 00000100
3fffeac0: c_⸮⸮rS⸮
This is my code on the ESP8266. I apologize for any bad programming habits.
#include <ESP8266WiFi.h>
#include <FirebaseESP8266.h>
//Hidden for security
#define WIFINAME
#define WIFIPASSWORD
#define BAUTRATE 9600
#define FIREBASE_HOST
#define FIREBASE_COMMAND_ADDRESS
#define FIREBASE_AUTH
WiFiClientSecure client;
FirebaseData firebaseData;
unsigned long previousTime;
String firebaseWriteAddress;
String firebaseReadAddress;
String weight; // Stored in a string to accomodate the "loading" text
bool maxWRead;
bool minWRead;
bool displayPrefRead;
bool instructedToConnectWifi;
void readWeights(){
// function to read the min and max weights, then send to Arduino
if (!maxWRead){
String maxWAddress = firebaseReadAddress + "/Product/MaxW";
if (Firebase.get(firebaseData,maxWAddress)){
if (firebaseData.dataType() == "string"){
String maxWMessage = "max:"+ firebaseData.stringData();
Serial.println(maxWMessage);
maxWRead = true;
}
}
}
if (!minWRead){
String minWAddress = firebaseReadAddress + "/Product/MinW";
if (Firebase.get(firebaseData,minWAddress)){
if (firebaseData.dataType() == "string"){
String minWMessage = "min:"+ firebaseData.stringData();
Serial.println(minWMessage);
minWRead = true;
}
}
}
}
void readDisplayPref(){
String displayAddress = firebaseReadAddress + "/Display";
if (Firebase.get(firebaseData,displayAddress)){
if (firebaseData.dataType() == "string"){
String displayMessage = "dsp:"+ firebaseData.stringData();
Serial.println(displayMessage);
displayPrefRead = true;
}
}
}
void sendFireBase(){
// function to send data to Firebase Real-time Database
Firebase.setString(firebaseData, firebaseWriteAddress,weight);
}
void readFireBase(){
Firebase.begin(FIREBASE_HOST,FIREBASE_AUTH);
if(Firebase.get(firebaseData, FIREBASE_COMMAND_ADDRESS)){
if (firebaseData.dataType() == "string"){
String data = firebaseData.stringData();
String command = data.substring(0,4);
if (command == "read"){
firebaseReadAddress = "/UserData/" + data.substring(4);
readWeights();
firebaseWriteAddress = "/UserData/" + data.substring(4)
+ "/Weight";
}
}
}
}
void connectWifi(){
WiFi.begin(WIFINAME, WIFIPASSWORD);
byte wifiCounter = 0;
// Allow some buffer time to connect to WiFi
while (WiFi.status() != WL_CONNECTED) {
delay(100);
wifiCounter ++;
if (wifiCounter > 50){
// tries for 5 sec.
break;
}
}
if (WiFi.status() == WL_CONNECTED){
Serial.print("WiFi Connected!\n");
instructedToConnectWifi = true;
}
else {
Serial.print("Can't Connect. Trying Again\n");
connectWifi();
}
}
void readArd(){
// function to read Serial inputs from arduino
String message = Serial.readStringUntil('\n');
if (message == "ConnectWifi"){
connectWifi();
}
else{
weight = message;
// stores weight without the percentage sign. Only stores if its within 0-100
sendFireBase();
}
}
void setup() {
Serial.begin(BAUTRATE);
previousTime = millis();
maxWRead = false;
minWRead = false;
displayPrefRead = false;
instructedToConnectWifi = false;
}
void loop() {
if (Serial.available()){
readArd();
}
if (instructedToConnectWifi){
// if wifi disconnects halfway, auto connect back
if (WiFi.status() != WL_CONNECTED){
connectWifi();
}
}
unsigned long currentTime = millis();
if (currentTime - previousTime >2000){
// cycles every 2 sec to prevent spam
// TODO: fix overflow problem (49 days) if it becomes product
if (instructedToConnectWifi){
if (!minWRead || !maxWRead){
// stop once max and min has been read
readFireBase();
previousTime = currentTime;
}
else {
readDisplayPref();
previousTime = currentTime;
}
}
}
}

These exeption analysed gives me the following result:
Exception 0: Illegal instruction
looking deeper into the error reveals:
std::basic_string , std::allocator >::basic_string(char const*, std::allocator const&)
This error pattern is typical for the String class.
Replace all Strings with fixed char arrays (not dynamicly created ones(!))
Reason: the String class tends to fracture the heap which causes the ESPs to crash (8266 as well ESP32). Why those? Because we use them (opposite to "normal" Arduinos to 99% in WiFi scenarios (IoT). So there is a lot happening in memory.What to do? Get rid of String class (and delay() if used)
String firebaseWriteAddress;
String firebaseReadAddress;
String weight; // Stored in a string to accomodate the "loading" text
These above in combination with functions like (dynamicly defined String vars)
String data = firebaseData.stringData();
String command = data.substring(0,4);
if (command == "read"){
firebaseReadAddress = "/UserData/" + data.substring(4);
readWeights();
firebaseWriteAddress = "/UserData/" + data.substring(4)
+ "/Weight";
will ensure that the ESP crashes very quickly. Since there is no garbagge collection (and would have not enough memory anyway) you write at some point into occupied memory - see first line of my error analysis - crash.Why work fixed chars? - they are compiled into flash and you operate most of the time with pointers. So all "fixed" text messages go into flash (example)
char firebaseReadAddress[64] = {'\0'}; //Takes 63 chars
used like
strcpy(firebaseReadAddress, "/UserData/");
strcat(firebaseReadAddress, dataContent);
to check wether a char array starts with "read" you use this method:
if (strncmp( command, "read", 4) == 0) { /** Compare the first 4 characters - returns 0 if they are equal */
The handling is as easy as String class, but it lets your app run forever (at least as long there is a power source)Check also used libraries for heavy String use (especially if they are not dedicated for ESPs). If they do - ditch them or rewrite them ;-) The firebase lib is a positive example no use of dynamic Strings and heavy use of char arrays. Sorry for the bad newsRewrite your program if you ever want a stable app, I can assist you if there are special questions - just leave a comment here.

Related

In MIPS, how exactly are command line arguments stored in $a1?

Consider the following code, which reads the first command line argument and then prints it:
lw $a0, 0($a1)
li $v0, 4
syscall
This makes sense, because arguments are always stored in word-aligned offsets from $a1. However, supposes the first program argument is 'jklfjdsaklfjdsklfjsdklfjsklfjsklfjsdaklfjlsdkjfjfksalfjsadlkf'. There's no way this gigantic string fits into the four bytes between 0($a1) and 4($a1). Yet the code still runs and prints the string. Why?
Also how does the entire string get put into $a0? Because again it shouldn't really fit.
char fun0 ( char *x )
{
return(x[11]);
}
char fun1 ( char **x )
{
return(x[1][1]);
}
mips
00000000 <fun0>:
0: 8082000b lb $2,11($4)
4: 03e00008 jr $31
8: 00000000 nop
0000000c <fun1>:
c: 8c820004 lw $2,4($4)
10: 00000000 nop
14: 80420001 lb $2,1($2)
18: 03e00008 jr $31
1c: 00000000 nop
arm
00000000 <fun0>:
0: e5d0000b ldrb r0, [r0, #11]
4: e12fff1e bx lr
00000008 <fun1>:
8: e5903004 ldr r3, [r0, #4]
c: e5d30001 ldrb r0, [r3, #1]
10: e12fff1e bx lr
x86
0000000000000000 <fun0>:
0: 0f b6 47 0b movzbl 0xb(%rdi),%eax
4: c3 retq
5: 90 nop
6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
d: 00 00 00
0000000000000010 <fun1>:
10: 48 8b 47 08 mov 0x8(%rdi),%rax
14: 0f b6 40 01 movzbl 0x1(%rax),%eax
18: c3 retq
so when you have int main ( int argc, char *argv[]) argv is an address and the compiler passes that address. If you are working at a different level, then the operating system/environment defines that the command line string is passed that way and that would cover the "why" question. You didnt provide enough information to answer the question.
And it basically has nothing to do with mips, it has to do with an implementation of some system that is targeted to mips. The same types of implementations can be used on non-mips targets as well.

Troubleshooting Sony Spresense Hard Fault

I have been working with the Sony Spresense board for a couple of days now but I am continuously getting a "hard fault". I have created multiple versions of the same code, but all get the same error. I am trying to copy the characters from a file on an SD card, inserted in the built-in SD Module and process them.
I have no idea what to do, the error just pops up at random points in the code, even if the board does not work with the SD Module at that point. If I comment out some lines of code before the point where the error message is sent, the error message is sent later on in the code.
The error message just gets printed to the serial monitor suddenly, the error seems to be present with all of my recent sketches. It looks like this.
up_hardfault: PANIC!!! Hard fault: 40000000
up_assert: Assertion failed at file:armv7-m/up_hardfault.c line: 171 task: init
up_dumpstate: sp: 0d0262d4
up_dumpstate: IRQ stack:
up_dumpstate: base: 0d026300
up_dumpstate: size: 00000800
up_dumpstate: used: 00000128
up_stackdump: 0d0262c0: 0d0262d8 0d01dc11 00000000 0d0262d8 0d00de13 00000003 00000000 0d00de1b
up_stackdump: 0d0262e0: 0d00ddf9 0d00dded 000000e0 0d02e804 00000047 0d02e8ec 0d024594 0d00d5f5
up_dumpstate: sp: 0d02e8d8
up_dumpstate: User stack:
up_dumpstate: base: 0d02ee18
up_dumpstate: size: 00001fec
up_dumpstate: used: 00000860
up_stackdump: 0d02e8c0: 00000000 00000000 00000000 00000000 00000000 0d000963 0d024c28 00000047
up_stackdump: 0d02e8e0: 0d02e934 0d0015c9 198b37d8 00000047 00007fff 0d0003e9 0d0351e0 0000000b
up_stackdump: 0d02e900: 0000000b 0d020e78 00000000 000003e8 deadbeef 0d035700 0d02cbb4 000000cc
up_stackdump: 0d02e920: 00000000 00000000 0d034e20 00000000 00000000 0d034e30 00000000 00000000
up_stackdump: 0d02e940: 0d034e40 00000000 00000000 deadbeef deadbeef deadbeef deadbeef deadbeef
up_stackdump: 0d02e960: deadbeef 0d034e50 00000000 00000000 0d034e60 00000000 00000000 0d034e70
up_stackdump: 0d02e980: 00000000 00000000 deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
up_stackdump: 0d02e9a0: 0d034e80 00000000 00000000 0d034e90 00000000 00000000 0d034ea0 00000000
up_stackdump: 0d02e9c0: 00000000 deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef 0d034eb0
up_stackdump: 0d02e9e0: 00000000 00000000 0d034ec0 00000000 00000000 0d034ed0 00000000 00000000
up_stackdump: 0d02ea00: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef 0d034ee0 00000000
up_stackdump: 0d02ea20: 00000000 0d034ef0 00000000 00000000 0d034f00 00000000 00000000 deadbeef
up_stackdump: 0d02ea40: deadbeef deadbeef deadbeef deadbeef deadbeef 0d034f10 00000000 00000000
up_stackdump: 0d02ea60: 0d034f20 00000000 00000000 0d034f30 00000000 00000000 deadbeef deadbeef
up_stackdump: 0d02ea80: deadbeef deadbeef deadbeef deadbeef 0d034f40 00000000 00000000 0d034f50
up_stackdump: 0d02eaa0: 00000000 00000000 0d034f60 00000000 00000000 deadbeef deadbeef deadbeef
up_stackdump: 0d02eac0: deadbeef deadbeef deadbeef 0d034f70 00000000 00000000 0d034f80 00000000
up_stackdump: 0d02eae0: 00000000 0d034f90 00000000 00000000 deadbeef deadbeef deadbeef deadbeef
up_stackdump: 0d02eb00: deadbeef deadbeef 0d034fa0 00000000 00000000 0d034fb0 00000000 00000000
up_stackdump: 0d02eb20: 0d034fc0 00000000 00000000 deadbeef deadbeef deadbeef deadbeef deadbeef
up_stackdump: 0d02eb40: deadbeef 0d034fd0 00000000 00000000 0d034fe0 00000000 00000000 0d034ff0
up_stackdump: 0d02eb60: 00000000 00000000 0d034c90 ffffffe9 00000000 00000000 00000000 00000000
up_stackdump: 0d02eb80: 0d035000 00000000 00000000 0d035010 00000000 00000000 0d035020 00000000
up_stackdump: 0d02eba0: 00000000 00000000 00000000 00000000 00000002 0d02c8f8 0d025954 0d035030
up_stackdump: 0d02ebc0: 00000000 00000000 0d035040 00000000 00000000 0d035050 00000000 00000000
up_stackdump: 0d02ebe0: 00000000 00000000 00000000 00000000 00000000 00000000 0d035060 00000000
up_stackdump: 0d02ec00: 00000000 0d035070 00000000 00000000 0d035080 00000000 00000000 0d02ec70
up_stackdump: 0d02ec20: 0000003c 0d015777 0d0244f4 0d015843 00000000 0d035090 00000000 00000000
up_stackdump: 0d02ec40: 0d0350a0 00000000 00000000 0d0350b0 00000000 00000000 0000000a 0d0164ed
up_stackdump: 0d02ec60: 0d027390 00000005 0d034c60 0d01de65 0d0350c0 00000000 00000000 0d0350d0
up_stackdump: 0d02ec80: 00000000 00000000 0d0350e0 00000000 00000000 0000ffff 00000026 0d035c60
up_stackdump: 0d02eca0: 00000000 00000004 00000080 0d0350f0 00000000 00000000 0d035100 00000000
up_stackdump: 0d02ecc0: 00000000 0d035110 00000000 00000000 000000e0 0000002a 0d02edd8 0d021348
up_stackdump: 0d02ece0: 0d024594 00000000 0d035120 00000000 00000000 0d035130 00000000 00000000
up_stackdump: 0d02ed00: 0d035140 00000000 00000000 0d003cd1 00000001 00000000 00000000 00000075
up_stackdump: 0d02ed20: 0d0245f4 0d035150 00000000 00000000 0d035160 00000000 00000000 0d035170
up_stackdump: 0d02ed40: 00000000 00000000 041ac000 0d014cf3 041ac000 0d006d01 0d006a75 0d0245e8
up_stackdump: 0d02ed60: 0d035180 00000000 00000000 0d035190 00000000 00000000 0d0351a0 00000000
up_stackdump: 0d02ed80: 00000000 000000e0 000000e0 041ac000 00000002 0d0068ef 0d0068cf 0d0351b0
up_stackdump: 0d02eda0: 00000000 00000000 0d0351c0 00000000 00000000 0d0351d0 00000000 00000000
up_stackdump: 0d02edc0: 00000000 0d0062f9 00000000 0d000f11 000003ff 0d000f29 0d02459c 0d02459c
up_stackdump: 0d02ede0: 0d000000 0d024594 00000000 00000000 00000000 0d000b51 0d008707 00000101
up_stackdump: 0d02ee00: 00000000 00000000 00000000 0d00920f 00000000 00000000 deadbeef 0d02ee24
up_registerdump: R0: 198b37d8 0d02e8ec 00000001 00000000 198b37d8 00000047 0d02e8ec 0d024594
up_registerdump: R8: 00000000 00000000 0000003c 00000000 00000002 0d02e8d8 0d0015c9 0d00156e
up_registerdump: xPSR: 21000000 BASEPRI: 000000e0 CONTROL: 00000000
up_registerdump: EXC_RETURN: ffffffe9
up_taskdump: Idle Task: PID=0 Stack Used=0 of 0
up_taskdump: hpwork: PID=1 Stack Used=584 of 2028
up_taskdump: lpwork: PID=2 Stack Used=352 of 2028
up_taskdump: lpwork: PID=3 Stack Used=352 of 2028
up_taskdump: lpwork: PID=4 Stack Used=352 of 2028
up_taskdump: init: PID=5 Stack Used=2144 of 8172
up_taskdump: cxd56_pm_task: PID=6 Stack Used=320 of 996
up_taskdump: <pthread>: PID=7 Stack Used=312 of 1020
It is basically printed in the middle of another serial print that I defined.
I played around with the code, and as previously said, the error just gets triggered at a random point, as it seems. It seems to be present in pretty much all the sketches I tried with the SD Module and the error pops up even if the device is not actively using the SD module.
This is the code that I am currently trying to use
#include <SDHCI.h>
SDClass SD;
File myFile;
struct Landmark
{
// strings
String name;
String sound;
String rawLocation;
// actual location
float latitude;
float longitude;
// grid co-ordinates
float p1;
float p2;
float p3;
float p4;
};
bool proDebug = true; // debugging?
void getData()
{
Serial.println("Getting Data");
Serial.println("________________________________________");
Serial.println("Locating File");
Serial.println(" OK - Preparing Variables");
Landmark landmark[20];
int newLine;
int space;
int comma;
Serial.println(" OK - Opening File 'datalog.txt'");
String buffer = "datalog.txt";
myFile = SD.open(buffer);
Serial.println(" OK - Verifying Presence");
if(myFile)
{
Serial.println(" Success - File Loaded");
Serial.println("");
Serial.println("Extracting Data");
Serial.println(" OK - Beginning Final Extraction");
while(myFile.available())
{
char c = myFile.read();
if(c == '\n')
{
newLine++;
}
else if(c == ' ')
{
space++;
}
else
{
if(space == 0)
{
landmark[newLine].name += c;
}
else if(space == 1)
{
if(c == ',')
{
comma++;
landmark[newLine].rawLocation += c;
}
if(comma == 0)
{
landmark[newLine].latitude += c;
}
else
{
landmark[newLine].longitude += c;
}
landmark[newLine].rawLocation += c;
}
else if(space == 2)
{
landmark[newLine].sound += c;
}
}
}
}
else
{
Serial.println(" Error - File not Present");
Serial.println(" OK - Terminating Algorithm");
Serial.println("________________________________________");
Serial.println("");
while(1) {};
}
myFile.close();
Serial.println(" Success - Data Loaded Locally");
Serial.println("");
Serial.println("Data Feedback");
Serial.println(" OK - Dumping All Data");
Serial.println("");
for(int i = 0; i < (newLine + 1); i++)
{
Serial.print("Struct "); Serial.println(i);
Serial.print(" location name "); Serial.println(landmark[i].name);
Serial.print(" sound file "); Serial.println(landmark[i].sound);
Serial.print(" raw location "); Serial.println(landmark[i].rawLocation);
Serial.print(" latitude "); Serial.println(landmark[i].latitude);
Serial.print(" longitude "); Serial.println(landmark[i].longitude);
}
Serial.println("");
Serial.println(" Success - Data Dumped");
Serial.println("________________________________________");
Serial.println("");
}
void setup()
{
Serial.begin(115200);
while(!Serial) {};
Serial.println("");
Serial.println("");
getData();
}
void loop()
{
}
I found this documentation to be very useful : https://www.nuttx.org/doku.php?id=wiki:howtos:cortexm-hardfault
Also your best hope is to use a jtag probe and see with a debugger & breakpoints what happens and where in the code

How to extract values in bits from a register and use them to replace bits in a different register? (MIPs assembly language)

I need to extract the value in bits 22 down to 4 from register $t0, compute the half of this value (assumed unsigned integer), and use the new value to replace bits 24 down to 6 in register $t1 without changing the others bits in $t1. The value isn't given but I don't think that should be an issue. There are 32 bits per register
I'm a bit new to MIPs so I'm not sure how to go about solving this problem
I've broken down the invidual steps of the algorithm. I then created a C prototype/test program. And, finally, I created a mips asm program.
Those are the steps I would recommend for you [or anybody else], particularly when getting started.
Writing the code in C first [or at least prototyping it in C-like pseudo code], makes debugging of the algorithm easier.
From the C program, I was able to create test data for the mips program. The test data includes the solution that the C program got.
The mips program would treat this as a pass/fail diagnostic. This might seem like overkill, but in the first version of the asm program, there was a bug. I had used a wrong register in the srlv instruction's third argument and the diagnostic actually failed the tests (e.g. I used $t0 instead of $t1).
Terminology:
This is the matchup of the terms:
xval: $t0
xhi: 22
xlo: 4
yval: $t1
yhi: 24
ylo: 6
Extract step (1):
Given a value xval, whenever you see "extract bits xhi to xlo", the first thing to do is right shift xval by xlo:
xshf = xval >> xlo
But now, xshf still has the bits that were to the left of xhi, so we need to mask them.
Formulas:
The bit width of an "inclusive" bit range is:
wid = (hi - lo) + 1
So, the "right justified" mask is:
rmsk = (0xFFFFFFFF >> (32 - wid))
The "left justified" mask is:
lmsk = (rmsk << lo)
Note: The above equations work dynamically [as above]. Or, if we have fixed numbers, we can calculate the final values by hand to produce constants.
Extract step (2):
So, to get the isolated value for the bit range, we now apply the mask:
xshf &= xrmsk
This is the first part of the problem. We've isolated the necessary bits, so they are now in the rightmost bits of xshf (i.e. bits (xwid-1) to 0).
Extract step (3):
The above was for general bit extraction. The specific problem requires that we divide by 2:
xshf >>= 1
Merge step (1):
The second part of the problem is that we have to apply the xshf to the target value yval.
yval has a different range: yhi to ylo. We apply the formulas to get the appropriate values for yval.
We must clear out the old bits in yval:
yval &= ~ylmsk
Merge step (2):
We need to do two things to xshf:
"clean up" xshf so that only the correct bits in yval get modified
Shift xshf into the correct position for merging with yval
We can accomplish this in one of two ways. The following two sequences are equivalent:
xshf &= yrmsk
xshf <<= ylo
Or:
xshf <<= ylo
xshf &= ylmsk
Note: Because the bit widths in the specific problem are the same, the masking step can be eliminated (i.e. xshf had already been masked by xrmsk and it is the same as yrmsk. So, either masking step is not required).
Merge step (3):
Now, we merge in the shifted value:
yval |= xshf
That's it--we're done ...
Prototype:
Here's some C code that combines all this.
Because the bit range values are fixed, the mask values are precalculated once. If they had to vary, the mask code would have to recalculate them on each merge call.
Also note that the masks are constants because the ranges are fixed.
#include <stdio.h>
#include <stdlib.h>
int opt_v;
typedef unsigned int u32;
u32 xval;
#define XHI 22
#define XLO 4
u32 yval;
#define YHI 24
#define YLO 6
u32 xrmsk;
u32 xlmsk;
u32 yrmsk;
u32 ylmsk;
#define WID(_hi,_lo) (((_hi) - (_lo)) + 1)
#define RMSK(_hi,_lo) (0xFFFFFFFF >> (32 - WID(_hi,_lo)))
#define LMSK(_hi,_lo) (RMSK(_hi,_lo) << (_lo))
#define SHOW(_sym) \
show(_sym,#_sym)
#define SHOWX(_sym) \
if (opt_v) \
SHOW(_sym)
void
show(u32 val,const char *sym)
{
u32 bitmsk;
u32 bitval;
printf("%8.8X ",val);
for (bitmsk = 1u << 31; bitmsk != 0; bitmsk >>= 1) {
bitval = val & bitmsk;
printf("%d",bitval ? 1 : 0);
}
printf(" %s\n",sym);
}
void
merge(void)
{
u32 xshf;
SHOW(xval);
SHOW(yval);
// extract (1):
xshf = xval >> XLO;
SHOW(xshf);
// extract (2):
SHOWX(xrmsk);
xshf &= xrmsk;
SHOW(xshf);
// extract (3):
xshf >>= 1;
SHOW(xshf);
// merge (1):
SHOWX(yrmsk);
SHOWX(ylmsk);
yval &= ~ylmsk;
SHOW(yval);
// merge (2):
xshf &= yrmsk; // belt and ...
SHOW(xshf);
xshf <<= YLO;
SHOW(xshf);
xshf &= ylmsk; // ... suspenders
SHOW(xshf);
// merge (3)
yval |= xshf;
SHOW(yval);
}
void
test(u32 y,u32 x)
{
printf("\n");
yval = y;
xval = x;
merge();
}
// main -- main program
int
main(int argc,char **argv)
{
char *cp;
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
cp = *argv;
if (*cp != '-')
break;
switch (cp[1]) {
case 'v':
opt_v = ! opt_v;
break;
default:
break;
}
}
xrmsk = RMSK(XHI,XLO);
SHOW(xrmsk);
xlmsk = LMSK(XHI,XLO);
SHOW(xlmsk);
yrmsk = RMSK(YHI,YLO);
SHOW(yrmsk);
ylmsk = LMSK(YHI,YLO);
SHOW(ylmsk);
test(0,~0);
test(~0,0);
for (int idx = 0; idx <= 5; ++idx)
test(rand(),rand());
return 0;
}
Output:
0007FFFF 00000000000001111111111111111111 xrmsk
007FFFF0 00000000011111111111111111110000 xlmsk
0007FFFF 00000000000001111111111111111111 yrmsk
01FFFFC0 00000001111111111111111111000000 ylmsk
FFFFFFFF 11111111111111111111111111111111 xval
00000000 00000000000000000000000000000000 yval
0FFFFFFF 00001111111111111111111111111111 xshf
0007FFFF 00000000000001111111111111111111 xshf
0003FFFF 00000000000000111111111111111111 xshf
00000000 00000000000000000000000000000000 yval
0003FFFF 00000000000000111111111111111111 xshf
00FFFFC0 00000000111111111111111111000000 xshf
00FFFFC0 00000000111111111111111111000000 xshf
00FFFFC0 00000000111111111111111111000000 yval
00000000 00000000000000000000000000000000 xval
FFFFFFFF 11111111111111111111111111111111 yval
00000000 00000000000000000000000000000000 xshf
00000000 00000000000000000000000000000000 xshf
00000000 00000000000000000000000000000000 xshf
FE00003F 11111110000000000000000000111111 yval
00000000 00000000000000000000000000000000 xshf
00000000 00000000000000000000000000000000 xshf
00000000 00000000000000000000000000000000 xshf
FE00003F 11111110000000000000000000111111 yval
6B8B4567 01101011100010110100010101100111 xval
327B23C6 00110010011110110010001111000110 yval
06B8B456 00000110101110001011010001010110 xshf
0000B456 00000000000000001011010001010110 xshf
00005A2B 00000000000000000101101000101011 xshf
32000006 00110010000000000000000000000110 yval
00005A2B 00000000000000000101101000101011 xshf
00168AC0 00000000000101101000101011000000 xshf
00168AC0 00000000000101101000101011000000 xshf
32168AC6 00110010000101101000101011000110 yval
643C9869 01100100001111001001100001101001 xval
66334873 01100110001100110100100001110011 yval
0643C986 00000110010000111100100110000110 xshf
0003C986 00000000000000111100100110000110 xshf
0001E4C3 00000000000000011110010011000011 xshf
66000033 01100110000000000000000000110011 yval
0001E4C3 00000000000000011110010011000011 xshf
007930C0 00000000011110010011000011000000 xshf
007930C0 00000000011110010011000011000000 xshf
667930F3 01100110011110010011000011110011 yval
74B0DC51 01110100101100001101110001010001 xval
19495CFF 00011001010010010101110011111111 yval
074B0DC5 00000111010010110000110111000101 xshf
00030DC5 00000000000000110000110111000101 xshf
000186E2 00000000000000011000011011100010 xshf
1800003F 00011000000000000000000000111111 yval
000186E2 00000000000000011000011011100010 xshf
0061B880 00000000011000011011100010000000 xshf
0061B880 00000000011000011011100010000000 xshf
1861B8BF 00011000011000011011100010111111 yval
2AE8944A 00101010111010001001010001001010 xval
625558EC 01100010010101010101100011101100 yval
02AE8944 00000010101011101000100101000100 xshf
00068944 00000000000001101000100101000100 xshf
000344A2 00000000000000110100010010100010 xshf
6200002C 01100010000000000000000000101100 yval
000344A2 00000000000000110100010010100010 xshf
00D12880 00000000110100010010100010000000 xshf
00D12880 00000000110100010010100010000000 xshf
62D128AC 01100010110100010010100010101100 yval
238E1F29 00100011100011100001111100101001 xval
46E87CCD 01000110111010000111110011001101 yval
0238E1F2 00000010001110001110000111110010 xshf
0000E1F2 00000000000000001110000111110010 xshf
000070F9 00000000000000000111000011111001 xshf
4600000D 01000110000000000000000000001101 yval
000070F9 00000000000000000111000011111001 xshf
001C3E40 00000000000111000011111001000000 xshf
001C3E40 00000000000111000011111001000000 xshf
461C3E4D 01000110000111000011111001001101 yval
3D1B58BA 00111101000110110101100010111010 xval
507ED7AB 01010000011111101101011110101011 yval
03D1B58B 00000011110100011011010110001011 xshf
0001B58B 00000000000000011011010110001011 xshf
0000DAC5 00000000000000001101101011000101 xshf
5000002B 01010000000000000000000000101011 yval
0000DAC5 00000000000000001101101011000101 xshf
0036B140 00000000001101101011000101000000 xshf
0036B140 00000000001101101011000101000000 xshf
5036B16B 01010000001101101011000101101011 yval
MIPS program:
This is set up for the mars simulator. In particular, the syscall 34 to print a value in hex only exists in mars and not in spim. So, either get mars: http://courses.missouristate.edu/KenVollmar/mars/ or [using spim] change the 34 to 1 to print in decimal
# these work for the mars simulator
.eqv XHI 22
.eqv XLO 4
.eqv YHI 24
.eqv YLO 6
# these work for the spim simulator
###XHI = 22
###XLO = 4
###YHI = 24
###YLO = 6
.data
testdata:
.word 0xFFFFFFFF,0x00000000,0x00FFFFC0
.word 0x00000000,0xFFFFFFFF,0xFE00003F
.word 0x6B8B4567,0x327B23C6,0x32168AC6
.word 0x643C9869,0x66334873,0x667930F3
.word 0x74B0DC51,0x19495CFF,0x1861B8BF
.word 0x2AE8944A,0x625558EC,0x62D128AC
.word 0x238E1F29,0x46E87CCD,0x461C3E4D
.word 0x3D1B58BA,0x507ED7AB,0x5036B16B
edata:
msg_nl: .asciiz "\n"
msg_xrmsk: .asciiz "xrmsk "
msg_xlmsk: .asciiz "xlmsk "
msg_yrmsk: .asciiz "yrmsk "
msg_ylmsk: .asciiz "ylmsk "
msg_xval: .asciiz "xval "
msg_yval: .asciiz "yval "
msg_pass: .asciiz "pass "
msg_fail: .asciiz "FAIL "
msg_ans: .asciiz "answ "
.text
.globl main
main:
jal setup2
la $s6,testdata
la $s7,edata
main_loop:
jal test
addiu $s6,$s6,12
blt $s6,$s7,main_loop
li $v0,10
syscall
# test -- test the merge
test:
subu $sp,$sp,4
sw $ra,0($sp)
li $v0,4
la $a0,msg_nl
syscall
lw $t0,0($s6) # get source value
lw $t1,4($s6) # get destination value
lw $t2,8($s6) # get solution value
# print the X value
la $a0,msg_xval
move $a1,$t0
jal print
# print the Y value
la $a0,msg_yval
move $a1,$t1
jal print
# do the operation
jal merge
bne $t1,$t2,test_fail
la $a0,msg_pass
move $a1,$t1
jal print
j test_done
test_fail:
la $a0,msg_fail
move $a1,$t1
jal print
# print the result
la $a0,msg_ans
move $a1,$t2
jal print
test_done:
lw $ra,0($sp)
addu $sp,$sp,4
jr $ra
# print -- print number
#
# arguments:
# a0 -- string
# a1 -- value
print:
# output the string
li $v0,4
syscall
li $v0,34 # syscall print hex
move $a0,$a1
syscall
li $v0,4
la $a0,msg_nl
syscall
jr $ra
# merge -- merge the data
#
# arguments:
# t0 -- source value
# t1 -- target value
#
# registers:
# t7 -- xshf
# t6 -- ~ylmsk
merge:
srl $t7,$t0,XLO # E1: xshf = xval >> xlo
and $t7,$t7,$s0 # E2: xshf &= xrmsk
srl $t7,$t7,1 # E3: xshf >>= 1
not $t6,$s3 # M1: get ~ylmsk
and $t1,$t1,$t6 # M1: yval &= ~ylmsk
sll $t7,$t7,YLO # M2: xshf <<= ylo
and $t7,$t7,$s3 # M2: xshf &= ylmsk
or $t1,$t1,$t7 # M3: yval |= xshf
jr $ra # return
# setup2 -- set up the mask values
#
# RETURNS:
# s0 -- xrmsk
# s1 -- xlmsk
# s2 -- yrmsk
# s3 -- ylmsk
#
# registers:
# a0 -- hi bit value
# a1 -- lo bit value
setup2:
subu $sp,$sp,4
sw $ra,0($sp)
# set up the xval masks
li $a0,XHI
li $a1,XLO
jal setup1
move $s0,$v0
move $s1,$v1
la $a0,msg_xrmsk
move $a1,$s0
jal print
la $a0,msg_xlmsk
move $a1,$s1
jal print
# set up the yval masks
li $a0,YHI
li $a1,YLO
jal setup1
move $s2,$v0
move $s3,$v1
la $a0,msg_yrmsk
move $a1,$s2
jal print
la $a0,msg_ylmsk
move $a1,$s3
jal print
lw $ra,0($sp)
addu $sp,$sp,4
jr $ra # return
# setup1 -- set up the mask values
#
# RETURNS:
# v0 -- rmsk
# v1 -- lmsk
#
# arguments:
# a0 -- hi bit value
# a1 -- lo bit value
#
# registers:
# t0 -- wid
# t1 -- 32 - wid
setup1:
sub $t0,$a0,$a1 # wid = hi - lo
addi $t0,$t0,1 # wid += 1
li $v0,0xFFFFFFFF # rmsk = 0xFFFFFFFF
# get 32 - wid
li $t1,32
sub $t1,$t1,$t0
srlv $v0,$v0,$t1 # rmsk >>= (32 - wid)
sllv $v1,$v0,$a1 # lmsk = rmsk << lo
jr $ra # return

cuda-gdb with cuda-memcheck error

I have this cuda code, that when I execute with cuda-memcheck it returns no errors, it exits normally, and the results I get are actually the expected...
At the same time, there is a file "cuda-memcheck-(put various mumbers here).out" created, that is empty.
When I run the same program under cuda-gdb, it also exits normally with no error reports.
But when I do "set cuda memcheck on" (under cuda-gdb) and then run the program, then a file "cuda-memcheck.out" is created that says:
Starting cuda-memcheck...
cuda-memcheck encountered an error (3,2,2)
that happens as soon as I execute 'run' from within cuda-gdb. Then, soon after the execution starts (and actually very close to a CUFFT kernel execution) i get the following:
Program received signal CUDA_EXCEPTION_1, Lane Illegal Address.
[Switching focus to CUDA kernel 81, grid 82, block (0,0,0), thread (1,17,0), device 0, sm 0, warp 2, lane 5]
*** glibc detected *** cuda-gdb: double free or corruption (!prev): 0x000000001070e5d0 ***
======= Backtrace: =========
/lib/libc.so.6(+0x774b6)[0x7f597c4814b6]
/lib/libc.so.6(cfree+0x73)[0x7f597c487c83]
/lib/libc.so.6(obstack_free+0x48)[0x7f597c48b128]
cuda-gdb[0x5c5a25]
cuda-gdb[0x4352d0]
cuda-gdb[0x5649c4]
cuda-gdb[0x5e42d7]
cuda-gdb[0x5e45fd]
cuda-gdb[0x56436c]
cuda-gdb[0x50d772]
cuda-gdb[0x50e3c3]
cuda-gdb[0x51373b]
cuda-gdb[0x50faff]
cuda-gdb[0x510194]
cuda-gdb[0x51373b]
cuda-gdb[0x50eaac]
cuda-gdb[0x504311]
cuda-gdb[0x50a09d]
cuda-gdb[0x4ffc4f]
cuda-gdb[0x410b9d]
cuda-gdb[0x519c48]
cuda-gdb[0x51a82c]
cuda-gdb[0x5f9b57]
cuda-gdb[0x519cb9]
cuda-gdb[0x5186c8]
cuda-gdb[0x51995a]
cuda-gdb[0x51373b]
cuda-gdb[0x4a1a40]
cuda-gdb[0x407529]
cuda-gdb[0x51373b]
cuda-gdb[0x408056]
cuda-gdb[0x51373b]
cuda-gdb[0x407464]
cuda-gdb[0x40742e]
/lib/libc.so.6(__libc_start_main+0xfe)[0x7f597c428d8e]
cuda-gdb[0x407339]
======= Memory map: ========
00400000-008b6000 r-xp 00000000 08:01 190634 /usr/local/cuda/bin/cuda-gdb
00ab5000-00ab6000 r--p 004b5000 08:01 190634 /usr/local/cuda/bin/cuda-gdb
00ab6000-00ac9000 rw-p 004b6000 08:01 190634 /usr/local/cuda/bin/cuda-gdb
00ac9000-0f0f8000 rw-p 00000000 00:00 0
0fef3000-11b2c000 rw-p 00000000 00:00 0 [heap]
7f5974000000-7f5974021000 rw-p 00000000 00:00 0
7f5974021000-7f5978000000 ---p 00000000 00:00 0
7f597a4df000-7f597aacc000 rw-p 00000000 00:00 0
7f597aacc000-7f597aacd000 rw-p 00000000 00:00 0
7f597b538000-7f597b54d000 r-xp 00000000 08:01 954799 /lib/libgcc_s.so.1
7f597b54d000-7f597b74c000 ---p 00015000 08:01 954799 /lib/libgcc_s.so.1
7f597b74c000-7f597b74d000 r--p 00014000 08:01 954799 /lib/libgcc_s.so.1
7f597b74d000-7f597b74e000 rw-p 00015000 08:01 954799 /lib/libgcc_s.so.1
7f597b75d000-7f597b764000 r-xp 00000000 08:01 954961 /lib/libthread_db-1.0.so
7f597b764000-7f597b963000 ---p 00007000 08:01 954961 /lib/libthread_db-1.0.so
7f597b963000-7f597b964000 r--p 00006000 08:01 954961 /lib/libthread_db-1.0.so
7f597b964000-7f597b965000 rw-p 00007000 08:01 954961 /lib/libthread_db-1.0.so
7f597b965000-7f597b966000 ---p 00000000 00:00 0
7f597b966000-7f597c166000 rw-p 00000000 00:00 0
7f597c166000-7f597c40a000 r--p 00000000 08:01 49399 /usr/lib/locale/locale-archive
7f597c40a000-7f597c584000 r-xp 00000000 08:01 954957 /lib/libc-2.12.1.so
7f597c584000-7f597c783000 ---p 0017a000 08:01 954957 /lib/libc-2.12.1.so
7f597c783000-7f597c787000 r--p 00179000 08:01 954957 /lib/libc-2.12.1.so
7f597c787000-7f597c788000 rw-p 0017d000 08:01 954957 /lib/libc-2.12.1.so
7f597c788000-7f597c78d000 rw-p 00000000 00:00 0
7f597c78d000-7f597c78f000 r-xp 00000000 08:01 954973 /lib/libdl-2.12.1.so
7f597c78f000-7f597c98f000 ---p 00002000 08:01 954973 /lib/libdl-2.12.1.so
7f597c98f000-7f597c990000 r--p 00002000 08:01 954973 /lib/libdl-2.12.1.so
7f597c990000-7f597c991000 rw-p 00003000 08:01 954973 /lib/libdl-2.12.1.so
7f597c991000-7f597c9b7000 r-xp 00000000 08:01 954792 /lib/libexpat.so.1.5.2
7f597c9b7000-7f597cbb7000 ---p 00026000 08:01 954792 /lib/libexpat.so.1.5.2
7f597cbb7000-7f597cbb9000 r--p 00026000 08:01 954792 /lib/libexpat.so.1.5.2
7f597cbb9000-7f597cbba000 rw-p 00028000 08:01 954792 /lib/libexpat.so.1.5.2
7f597cbba000-7f597cc3c000 r-xp 00000000 08:01 954964 /lib/libm-2.12.1.so
7f597cc3c000-7f597ce3b000 ---p 00082000 08:01 954964 /lib/libm-2.12.1.so
7f597ce3b000-7f597ce3c000 r--p 00081000 08:01 954964 /lib/libm-2.12.1.so
7f597ce3c000-7f597ce3d000 rw-p 00082000 08:01 954964 /lib/libm-2.12.1.so
7f597ce3d000-7f597ce53000 r-xp 00000000 08:01 954914 /lib/libz.so.1.2.3.4
7f597ce53000-7f597d053000 ---p 00016000 08:01 954914 /lib/libz.so.1.2.3.4
7f597d053000-7f597d054000 r--p 00016000 08:01 954914 /lib/libz.so.1.2.3.4
7f597d054000-7f597d055000 rw-p 00017000 08:01 954914 /lib/libz.so.1.2.3.4
7f597d055000-7f597d095000 r-xp 00000000 08:01 954818 /lib/libncurses.so.5.7
7f597d095000-7f597d294000 ---p 00040000 08:01 954818 /lib/libncurses.so.5.7
7f597d294000-7f597d298000 r--p 0003f000 08:01 954818 /lib/libncurses.so.5.7
7f597d298000-7f597d299000 rw-p 00043000 08:01 954818 /lib/libncurses.so.5.7
7f597d299000-7f597d2b1000 r-xp 00000000 08:01 954959 /lib/libpthread-2.12.1.so
7f597d2b1000-7f597d4b0000 ---p 00018000 08:01 954959 /lib/libpthread-2.12.1.so
7f597d4b0000-7f597d4b1000 r--p 00017000 08:01 954959 /lib/libpthread-2.12.1.so
7f597d4b1000-7f597d4b2000 rw-p 00018000 08:01 954959 /lib/libpthread-2.12.1.so
7f597d4b2000-7f597d4b6000 rw-p 00000000 00:00 0
7f597d4b6000-7f597d4d6000 r-xp 00000000 08:01 954965 /lib/ld-2.12.1.so
7f597d4df000-7f597d672000 rw-p 00000000 00:00 0
7f597d672000-7f597d678000 r--p 00a01000 08:06 26722558 /home/user/workspace/cuda/fullcu/current_debug/Default/shl_3D_cu
7f597d678000-7f597d67e000 r--p 00a15000 08:06 26722558 /home/user/workspace/cuda/fullcu/current_debug/Default/shl_3D_cu
7f597d67e000-7f597d687000 r--p 00a06000 08:06 26722558 /home/user/workspace/cuda/fullcu/current_debug/Default/shl_3D_cu
7f597d687000-7f597d6c0000 r--p 009c5000 08:06 26722558 /home/user/workspace/cuda/fullcu/current_debug/Default/shl_3D_cu
7f597d6c0000-7f597d6c5000 rw-p 00000000 00:00 0
7f597d6c5000-7f597d6ca000 r--p 009fd000 08:06 26722558 /home/user/workspace/cuda/fullcu/current_debug/Default/shl_3D_cu
7f597d6cb000-7f597d6cd000 rw-p 00000000 00:00 0
7f597d6cd000-7f597d6d4000 r--s 00000000 08:01 49265 /usr/lib/gconv/gconv-modules.cache0x000000000366a8d0 in fdividef<<<(16,1,1),(4,64,1)>>> (Aborted
and cuda-gdb crashes.
Should I take it that there is actually a faulty mem access in my code? or is it the error that hits upon the initialization of cuda-memcheck???
anyone seen that behaviour before??
Thank you for any ideas.
It looks like you have a memcheck-detectable error in your application. For some reason, cuda-gdb crashes when your application is suspended on the breakpoint.
Does your cuda-gdb crash when you stop on regular breakpoints in the device code?
What CUDA Toolkit and NVIDIA display driver versions are you using? We recommend you trying the latest CUDA Toolkit 5.0RC build as it has numerous stability and functionality improvements.
It would be invaluable if you could contact out team directly at cudatools#nvidia.com to provide more information (this way we may be able to fix the problem in the next CUDA Toolkit version). Can you also provide the application that triggers the crash?
Thank you in advance.
Based on Eugene's question on what happens on regular breakpoints, I added some in key points in the code ('key' with respect to the debugging output I have gotten until now) and I have the following 'odd' gdb output to report:
The following is from a CUFFT kernel call:
[Launch of CUDA Kernel 41 (spVector0016B_kernelTex<(fftDirection_t)-1><<<(16,1,1),(4,64,1)>>>) on Device 0]
0x00007ffff569c8b3 in select () from /lib/libc.so.6
(cuda-gdb) n
Single stepping until exit from function select, which has no line number information.
0x00007ffff3fe8de7 in ?? () from /usr/lib/libcuda.so
Is '??' normal output in that case because it's a CUFFT kernel?
The following is from another kernel launch, mine this time and I don't understand why it says 'no such file':
Breakpoint 5, BCSG<<<(1,1,1),(512,1,1)>>> (glerror=0x200620df8,
sL=0x2009ffff8, ijL=0x200aa7ffc, X=0x2006035f8, D=0x2006075f8,
Pre=0x200941ff8,
error=1.00000001e-10, L=700, N=1024, flag=0x200c00000, r=0x2006095f8, r0=0x20060b5f8, p1=0x20060d5f8, p2=0x20060f5f8,
vv=0x2006115f8, s1=0x2006135f8,
s2=0x2006155f8, t=0x2006175f8, T=0x2006195f8, r1=0x20061b600, a=0x20061cbf8, w=0x20061e1f8, beta=0x20061f7f8, ns1=0x200affffc) at
BCGC_solver.cu:96
96 BCGC_solver.cu: No such file or directory.
in BCGC_solver.cu
Also i would like to ask if this:
warning: Warp(s) other than the current warp had to be single-stepped.
...happens because of the execution within cuda-gdb, or if it is something that would happen in normal program execution as well. I do have the program hanging at parts of the code, soon after it freezes for good. But I think that if it was only a matter of serial execution, it would continue soon after, as it does in conventional code.
To well trace this issue, it is better to file a bug to Nvidia. The steps of filing a bug is listed as below:
1. Open page http://developer.nvidia.com/cuda/join-cuda-registered-developer-program;
2. If not registered, please click "Join Now", otherwise click "Login Now";
3. Input e-mail and password to login;
4. On the left panel, there is a "Bug Report" item in Home section, click it to file a bug;
5. Fill the required itmes, other items are optional, but detailed information will help us to target and fix the issue a lot;
6. If necessary, an attachment should be uploaded;
7. For Linux system, it is better to attach an nvidia-bug-report;
8. If an issue is related to specific code pattern, a sample code and instructions to compile it are desired for reproduction.

How do I display the binary representation of a float or double?

I'd like to display the binary (or hexadecimal) representation of a floating point number. I know how to convert by hand (using the method here), but I'm interested in seeing code samples that do the same.
Although I'm particularly interested in the C++ and Java solutions, I wonder if any languages make it particularly easy so I'm making this language agnostic. I'd love to see some solutions in other languages.
EDIT: I've gotten good coverage of C, C++, C#, and Java. Are there any alternative-language gurus out there who want to add to the list?
C/C++ is easy.
union ufloat {
float f;
unsigned u;
};
ufloat u1;
u1.f = 0.3f;
Then you just output u1.u.
Doubles just as easy.
union udouble {
double d;
unsigned long u;
}
because doubles are 64 bit.
Java is a bit easier: use Float.floatToRawIntBits() combined with Integer.toBinaryString() and Double.doubleToRawLongBits combined with Long.toBinaryString().
In C:
int fl = *(int*)&floatVar;
&floatVar would get the adress memory then (int*) would be a pointer to this adress memory, finally the * to get the value of the 4 bytes float in int.
Then you can printf the binary format or hex format.
Java: a google search finds this link on Sun's forums
specifically (I haven't tried this myself)
long binary = Double.doubleToLongBits(3.14159);
String strBinary = Long.toBinaryString(binary);
Apparently nobody cared to mention how trivial is to obtain hexadecimal exponent notation, so here it is:
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
// C++11 manipulator
cout << 23.0f << " : " << std::hexfloat << 23.0f << endl;
// C equivalent solution
printf("23.0 in hexadecimal is: %A\n", 23.0f);
}
In .NET (including C#), you have BitConverter that accepts many types, allowing access to the raw binary; to get the hex, ToString("x2") is the most common option (perhaps wrapped in a utility method):
byte[] raw = BitConverter.GetBytes(123.45);
StringBuilder sb = new StringBuilder(raw.Length * 2);
foreach (byte b in raw)
{
sb.Append(b.ToString("x2"));
}
Console.WriteLine(sb);
Oddly, base-64 has a 1-line conversion (Convert.ToBase64String), but base-16 takes more effort. Unless you reference Microsoft.VisualBasic, in which case:
long tmp = BitConverter.DoubleToInt64Bits(123.45);
string hex = Microsoft.VisualBasic.Conversion.Hex(tmp);
I did it this way:
/*
#(#)File: $RCSfile: dumpdblflt.c,v $
#(#)Version: $Revision: 1.1 $
#(#)Last changed: $Date: 2007/09/05 22:23:33 $
#(#)Purpose: Print C double and float data in bytes etc.
#(#)Author: J Leffler
#(#)Copyright: (C) JLSS 2007
#(#)Product: :PRODUCT:
*/
/*TABSTOP=4*/
#include <stdio.h>
#include "imageprt.h"
#ifndef lint
/* Prevent over-aggressive optimizers from eliminating ID string */
extern const char jlss_id_dumpdblflt_c[];
const char jlss_id_dumpdblflt_c[] = "#(#)$Id: dumpdblflt.c,v 1.1 2007/09/05 22:23:33 jleffler Exp $";
#endif /* lint */
union u_double
{
double dbl;
char data[sizeof(double)];
};
union u_float
{
float flt;
char data[sizeof(float)];
};
static void dump_float(union u_float f)
{
int exp;
long mant;
printf("32-bit float: sign: %d, ", (f.data[0] & 0x80) >> 7);
exp = ((f.data[0] & 0x7F) << 1) | ((f.data[1] & 0x80) >> 7);
printf("expt: %4d (unbiassed %5d), ", exp, exp - 127);
mant = ((((f.data[1] & 0x7F) << 8) | (f.data[2] & 0xFF)) << 8) | (f.data[3] & 0xFF);
printf("mant: %16ld (0x%06lX)\n", mant, mant);
}
static void dump_double(union u_double d)
{
int exp;
long long mant;
printf("64-bit float: sign: %d, ", (d.data[0] & 0x80) >> 7);
exp = ((d.data[0] & 0x7F) << 4) | ((d.data[1] & 0xF0) >> 4);
printf("expt: %4d (unbiassed %5d), ", exp, exp - 1023);
mant = ((((d.data[1] & 0x0F) << 8) | (d.data[2] & 0xFF)) << 8) |
(d.data[3] & 0xFF);
mant = (mant << 32) | ((((((d.data[4] & 0xFF) << 8) |
(d.data[5] & 0xFF)) << 8) | (d.data[6] & 0xFF)) << 8) |
(d.data[7] & 0xFF);
printf("mant: %16lld (0x%013llX)\n", mant, mant);
}
static void print_value(double v)
{
union u_double d;
union u_float f;
f.flt = v;
d.dbl = v;
printf("SPARC: float/double of %g\n", v);
image_print(stdout, 0, f.data, sizeof(f.data));
image_print(stdout, 0, d.data, sizeof(d.data));
dump_float(f);
dump_double(d);
}
int main(void)
{
print_value(+1.0);
print_value(+2.0);
print_value(+3.0);
print_value( 0.0);
print_value(-3.0);
print_value(+3.1415926535897932);
print_value(+1e126);
return(0);
}
Running on a SUN UltraSPARC, I got:
SPARC: float/double of 1
0x0000: 3F 80 00 00 ?...
0x0000: 3F F0 00 00 00 00 00 00 ?.......
32-bit float: sign: 0, expt: 127 (unbiassed 0), mant: 0 (0x000000)
64-bit float: sign: 0, expt: 1023 (unbiassed 0), mant: 0 (0x0000000000000)
SPARC: float/double of 2
0x0000: 40 00 00 00 #...
0x0000: 40 00 00 00 00 00 00 00 #.......
32-bit float: sign: 0, expt: 128 (unbiassed 1), mant: 0 (0x000000)
64-bit float: sign: 0, expt: 1024 (unbiassed 1), mant: 0 (0x0000000000000)
SPARC: float/double of 3
0x0000: 40 40 00 00 ##..
0x0000: 40 08 00 00 00 00 00 00 #.......
32-bit float: sign: 0, expt: 128 (unbiassed 1), mant: 4194304 (0x400000)
64-bit float: sign: 0, expt: 1024 (unbiassed 1), mant: 2251799813685248 (0x8000000000000)
SPARC: float/double of 0
0x0000: 00 00 00 00 ....
0x0000: 00 00 00 00 00 00 00 00 ........
32-bit float: sign: 0, expt: 0 (unbiassed -127), mant: 0 (0x000000)
64-bit float: sign: 0, expt: 0 (unbiassed -1023), mant: 0 (0x0000000000000)
SPARC: float/double of -3
0x0000: C0 40 00 00 .#..
0x0000: C0 08 00 00 00 00 00 00 ........
32-bit float: sign: 1, expt: 128 (unbiassed 1), mant: 4194304 (0x400000)
64-bit float: sign: 1, expt: 1024 (unbiassed 1), mant: 2251799813685248 (0x8000000000000)
SPARC: float/double of 3.14159
0x0000: 40 49 0F DB #I..
0x0000: 40 09 21 FB 54 44 2D 18 #.!.TD-.
32-bit float: sign: 0, expt: 128 (unbiassed 1), mant: 4788187 (0x490FDB)
64-bit float: sign: 0, expt: 1024 (unbiassed 1), mant: 2570638124657944 (0x921FB54442D18)
SPARC: float/double of 1e+126
0x0000: 7F 80 00 00 ....
0x0000: 5A 17 A2 EC C4 14 A0 3F Z......?
32-bit float: sign: 0, expt: 255 (unbiassed 128), mant: 0 (0x000000)
64-bit float: sign: 0, expt: 1441 (unbiassed 418), mant: -1005281217 (0xFFFFFFFFC414A03F)
Well both the Float and Double class (in Java) have a toHexString('float') method so pretty much this would do for hex conversion
Double.toHexString(42344);
Float.toHexString(42344);
Easy as pie!
I had to think about posting here for a while because this might inspire fellow coders to do evil things with C. I decided to post it anyway but just remember: do not write this kind of code to any serious application without proper documentation and even then think thrice.
With the disclaimer aside, here we go.
First write a function for printing for instance a long unsigned variable in binary format:
void printbin(unsigned long x, int n)
{
if (--n) printbin(x>>1, n);
putchar("01"[x&1]);
}
Unfortunately we can't directly use this function to print our float variable so we'll have to hack a little. The hack probably looks familiar to everyone who have read about Carmack's Inverse Square Root trick for Quake. The idea is set a value for our float variable and then get the same bit mask for our long integer variable. So we take the memory address of f, convert it to a long* value and use that pointer to get the bit mask of f as a long unsigned. If you were to print this value as long unsigned, the result would be a mess, but the bits are the same as in the original float value so it doesn't really matter.
int main(void)
{
long unsigned lu;
float f = -1.1f;
lu = *(long*)&f;
printbin(lu, 32);
printf("\n");
return 0;
}
If you think this syntax is awful, you're right.
In Haskell, there is no internal representation of floating points accessible. But you can do binary serialiazation from many formats, including Float and Double. The following solution is generic to any type that has instance of Data.Binary supports:
module BinarySerial where
import Data.Bits
import Data.Binary
import qualified Data.ByteString.Lazy as B
elemToBits :: (Bits a) => a -> [Bool]
elemToBits a = map (testBit a) [0..7]
listToBits :: (Bits a) => [a] -> [Bool]
listToBits a = reverse $ concat $ map elemToBits a
rawBits :: (Binary a) => a -> [Bool]
rawBits a = listToBits $ B.unpack $ encode a
Conversion can be done with rawBits:
rawBits (3.14::Float)
But, if you need to access the float value this way, you are probably doing something wrong. The real question might be How to access exponent and significand of a floating-point number? The answers are exponent and significand from Prelude:
significand 3.14
0.785
exponent 3.14
2
Python:
Code:
import struct
def float2bin(number, hexdecimal=False, single=False):
bytes = struct.pack('>f' if single else '>d', number)
func, length = (hex, 2) if hexdecimal else (bin, 8)
byte2bin = lambda byte: func(ord(byte))[2:].rjust(length, '0')
return ''.join(map(byte2bin, bytes))
Sample:
>>> float2bin(1.0)
'0011111111110000000000000000000000000000000000000000000000000000'
>>> float2bin(-1.0)
'1011111111110000000000000000000000000000000000000000000000000000'
>>> float2bin(1.0, True)
'3ff0000000000000'
>>> float2bin(1.0, True, True)
'3f800000'
>>> float2bin(-1.0, True)
'bff0000000000000'
You can easy convert float variable to int variable (or double to long) using such code in C#:
float f = ...;
unsafe
{
int i = *(int*)&f;
}
For future reference, C++ 2a introduce a new function template bit_cast that does the job.
template< class To, class From >
constexpr To bit_cast(const From& from) noexcept;
We can simply call,
float f = 3.14;
std::bit_cast<int>(f);
For more details, see https://en.cppreference.com/w/cpp/numeric/bit_cast
In C++ you can show the binary representation it in this way:
template <class T>
std::bitset<sizeof(T)*8> binary_representation(const T& f)
{
typedef unsigned long TempType;
assert(sizeof(T)<=sizeof(TempType));
return std::bitset<sizeof(T)*8>(*(reinterpret_cast<const TempType*>(&f)));
}
the limit here is due the fact that bitset longer parameter is an unsigned long,
so it works up to float, you can use something else than bitset and the extend
that assert.
BTW, cletus suggestion fails in the sense that you need an "unsingned long long" to cover a double, anyway you need something that shows the binary (1 or 0) representation.