Omnimaga
Calculator Community => TI Calculators => Calculator C => Topic started by: fb39ca4 on July 03, 2011, 08:29:36 pm
-
I'm just going to create a thread for all of the questions I have in regard to nspire C programming, so there isn't like 20 threads with my questions.
First question: Is there a way to make printf display output while a program is running? When I do it, everything gets printed at once after I exit the program. I'd like to see stuff printed while I run the program for debugging purposes.
-
New question? Why is my program giving me this error in the emulator:
data abort exception, lr=1107a4d0
the calc then resets.
Apparently, that means my program tried to write to an illegal memory address, so how do I stop it from doing so?
-
For the first question, try using NU_Local_Control_Interrupts(0x00000000) or NU_Local_Control_Interrupts(0xFFFFFFFF). I don't remember which one, but one of them enables interrupts and the other disables interrupts. You'll want them enabled for console output.
For the second question, it might help if I saw the C code in question.
-
Yes, you should use TCT_Local_Control_Interrupts(0); . See samples/hello.c in the Ndless SDK.
To debug exceptions you don't understand, try a C debugger (http://hackspire.unsads.com/wiki/index.php/Debugging_programs). Setting it up is not easy, and I haven't yet released a version of Ncubate compatible with the latest Nspire OS, but its still quite useful for nasty bugs.
-
Am I allowed to post only part of the code? I know the contest rules forbid posting the whole code but it doesn't say anything about a section of it (which happens to be most of the code right now).
Also, I tried using arm-eabi-none-gdb, but after typing in "break main", then typing "n" or "s" it tells me "Cannot find bounds of current function" ???
-
Try "c" after "break main", then run your program from the Documents menu.
-
Here's another problem I can't seem to figure out:
The compiler gives me the error "math.h:2:13: error: expected identifier or '(' before '{' token" and I have no idea why. Here's the entire contents of the math.h and math.c files:
extern float sqrt(float x);
extern long abs(long x);
extern float fabs(float x);
extern float sin(float X);
extern float cos(float x);
#include "math.h"
float sqrt(float x) {
float r = x / 2;
int i;
for (i = 0; i < 10; i++) {
r = 0.5 * (r + x / r);
}
return r;
}
long abs(long x) {
return (x > 0) ? x : -x;
}
float fabs(float x) {
if (x > 0) return x;
if (x < 0) return -x;
return x;
}
float cos(float x) {
x = x - TWOPI * ((int) (x / TWOPI));
float x2 = x * x;
return 1 + x2 * (-.5 + x2 * (.0417 - x2 * 0.00138));
}
float sin(float x) {
x = x - TWOPI * ((int) (x / TWOPI));
float x2 = x * x;
return x * (1 + x2 * (-0.1667 + .00833 * (x2 - .0002 * x2 )));
}
-
math.h is a default library, so it should be included with <>, #include <math.h>.
Oh wait, are you creating your own math.h? I think you should give it a new name, so it doesn't conflit with the default.
-
Well, ndless doesn't have a math.h so it shouldn't be an issue. I have compiled programs previously that use math.c and math.h and they work fine.
-
I figured out why...ndless already has an absolute value function. Now my code compiles fine :)
-
I have an array of the struct sprite, is there a way for me to take one struct in the array and set all the values at once?
struct sprite {long type; float x; float y; float velocityX; float velocityY;};
struct sprite sprite[numSprites];
sprite[0] = {1, 6.5, 17.5, 0, 0};
The compiler rejects what I tried to do in that last line, so basically, what would be the syntax for replacing the contents of one struct with another's?
-
Here's another question: How do I tell if the ON key is pressed? I can't do it with isKeyPressed.
-
For your first question this complies with C99:
struct sprite sprite = {.type = 1, .x = 6.5, .y = 17.5, .velocityX = 0, .velocityY = 0};
But it strangely fails if sprite[0] is used, I don't know why.
For you second question, check 900B0028 bit 4, see http://hackspire.unsads.com/wiki/index.php/Memory-mapped_I/O_ports#900B0000_-_Power_management .
-
So I could do this, right?
inline long is_on_key_pressed() {
return !(*0x900B0028 & 0x00000008);
}
-
Rather this (untested):
inline int is_on_key_pressed() {
return !(*(volatile int*)0x900B0028 & 4);
}
-
Ok, but shouldn't it be & 8? 4 in binary is 100, 8 is 1000.
-
Actually, it should be & 16 :P
-
Good point, I forgot to start counting from zero.
EDIT: Works great, this needs to be added to the ndless SVN.
-
calc84maniac: oops, right :)
t0xic_kitt3n: sure! Commited as on_key_pressed().
-
I tried compiling my C code and I get an error when using for loops. It says they're only allowed in C99 mode. What do I do in my makefile to change to C99?
Edit: Never mind, a quick Google found it for me. Still weird, though.
-
I suppose you were trying to declare a variable within the "for" statement.
-
Yes, that was the issue, but a simple change in the makefile fixed it.
I'm now looking for a good alphabet for displaying text. I stole a file from this program, http://www.ticalc.org/archives/files/fileinfo/430/43054.html (http://www.ticalc.org/archives/files/fileinfo/430/43054.html), which has text similar to (or maybe the exact same as) the text seen in the GBC emulator when selecting a ROM. I truly appreciate the maker's hard work, but I am looking for a font that looks more like the default kind found on the Nspire OS.
In addition, my program has the potential to use a LOT of RAM, so is there any way to track how much RAM is left, or how much is being used? It would be convenient for users to know.
-
You could edit the array with the font (though that will take quite a bit of work), but I think someone just discovered an OS routine to display text at an arbitrary location on the screen, which is worth looking at, but I don't remember the thread :(
I don't think it is possible to show the amount of free RAM right now, but unless you are using amounts into multiple megabytes, there shouldn't be a problem. How much RAM does your program use? The largest executable I made was 100kb in size, and that runs fine. Just keep away from large arrays of static variables and you'll be fine.
-
Please point me to the thread if you find it! Anyways, my program is a bignum library, so it will use as much RAM as is available, so it would be useful if that were possible, but in the meantime I might just implement something that measures how much RAM my own program uses, or just skip RAM measurement entirely.
-
Well, you should be fine then with at least hundred-thousand digit numbers.
-
Just try to malloc() or realloc() and check a NULL return.
We could also try to export in Ndless the Nucleus memory pool object used by the OS and make possible direct reads of the free space value from the structure.
-
Trying malloc() is a good way of ensuring enough RAM is available, which I guess is the only thing that matters. Would the second thing you mentioned require a modification to Ndless itself?
-
no, just another library, I believe. Ndless already has access to tons of OS calls.
I defer to any higher (any) authority on this matter though :P
-
Actually yes, the OS variable is currently not exported.
-
There's a higher authority for ya XD guess I was wrong again.
-
Awww... whatever, it's not crucial to my program anyways.
-
Here's another question I have:
To handle input in my program, I have made a
char input[500];
This means the input can only be 500 characters, but if I use fancier dynamic allocation methods this problem still remains: sometimes when I type, weird characters will be outputted in front of the useful text, only to be overwritten as I type more. I might type in "12345", and then have it suddenly turn into "12345[=$_L?<". As I type in more characters, they get overwritten into "123459843406", but more random symbols may pop up later. I really don't know what would be causing that to happen, because my string drawing function has already worked on other things, and I can't find anything wrong with the key detection code. Any ideas?
-
We would need the code snippet which fills up "input[] to be able to help you, the problem may be there.
-
Could it be a problem with null-termination? You can't assume that a dynamically allocated buffer (or a fixed-size local buffer) will be filled with 0.
-
Yeah, it kinda sounds like a problem with null termination. You should never assume allocated memory is clean, the safest bet would be to do a
memset(input, 0, bytes allocated);
after allocation and see if it still does it.
-
Or use calloc().
-
Yay, it works! Thanks again!
-
Or use calloc().
I've never used calloc ever since I came across the post on cprogramming's discussion board:
malloc will return an uninitialized chunk of memory for you to use.
calloc ( clear alloc ) will attempt to initialize that chunk of memory to all bits zero.
Note that when I say attempt, I mean that this may not be possible so you shouldn't rely on it. Other than that the only difference is how they are called and how they are implemented. So in the end, which one you choose to use is a matter of preference.
ref: http://cboard.cprogramming.com/c-programming/20505-malloc-vs-calloc.html#post132635 (http://cboard.cprogramming.com/c-programming/20505-malloc-vs-calloc.html#post132635)
-
I'm getting a weird problem creating arrays now. Here's the code:
int numInts1 = ceil(operationPos, 4);
int numInts2 = ceil((inputLen - operationPos - 1), 4);
int *in1 = (int*)calloc(numInts1, sizeof(int));
int *in2 = (int*)calloc(numInts2, sizeof(int));
Using the Eclipse debugger, numInts1 is what it's supposed to be, and same as numInts2, but the arrays in1 and in2 are always only one int long. Attached a screenshot of the debugger. (What it's showing means that the arrays are one int long, right? Otherwise I wouldn't know what's wrong with my program)
-
Never mind - got it all fixed. It turns out that Eclipse can't figure out what's an array and what's not when they are dynamically allocated. Just click on the variable and then "Display as an Array."
-
How do you use the show_msgbox function?
I have the following code:
#include <os.h>
int main()
{
void show_msgbox("Hello World", "Hello Omnimaga");
return 0;
}
And it's not compiling with the error:
Tom@AdmirableCoffee /c/Users/Tom/Desktop/Programs/Ndless/Hello_World
$ make
nspire-gcc -Os -nostdlib -Wall -W -marm -c main.c
main.c: In function 'main':
main.c:5:10: error: expected declaration specifiers or '...' before string const
ant
main.c:5:10: error: expected declaration specifiers or '...' before string const
ant
main.c:5:10: error: expected declaration specifiers or '...' before numeric cons
tant
make: *** [main.o] Error 1
Tom@AdmirableCoffee /c/Users/Tom/Desktop/Programs/Ndless/Hello_World
$
-
Lose the "void" since you're calling the function, not declaring it. As far as making sure you're calling the function with the proper arguments, I can't help you there because I don't know anything about device-specific C development.
-
It works. Thanks :D
I honestly feel I should hit myself over the head hard for something so obvious :P