Yes, the code now checks and skips function call with NULL address. I was trying to figure out if this is a bug in the code or intended behavior. This code was adapted from Unix to PC long ago... I'm now thinking it's a bug somewhere.
Hasn't happened again though, so maybe it was a fluke. Got my eye on it though...
}
`
Based on where the Include file was the compiler would generate a call to the pointer to the function and in the other case generate a call to the function.
I ended up adding an & in front of the function so that it would use the address of instead of the pointer to get around it.
Looks like code blocks are not working for C code.
@iseries : I think there's a problem (or more accurately an inconsistency) with trying to print a function address. In printf() function addresses are not converted to full method pointers, but whenever they are passed to a function that's expecting a function pointer they are. That's weird, but I don't think it'll actually mess anything up (except perhaps making debugging a bit harder). But I think you've hit on the work-around, always use & in front of functions if you want function pointers.
@Rayman : calling a NULL pointer is always a bug, on every platform. What it ends up doing will vary by platform (and on some platforms it may be benign) but the C standard is pretty clear that you shouldn't do that.
Yes, it took me about 10 hours to find that bad function call. All I was getting is double printing of my code as it rebooted and ran the code twice and stopped.
Had to start by tracing the code with LED's to see where it was stopping. Since it was a passed function call back it made it a little harder to find.
Printing the function pointer didn't help as it printed some strange value not an address to the function that corresponded to the assembly code. Tried several configuration to see if I could get the correct address but to no avail.
Finally just added the Ampersand to the function and it worked. Not the outcome I was looking for as it makes the code inconsistent as all the other calls do not have the Ampersand.
@iseries said:
Yes, it took me about 10 hours to find that bad function call. All I was getting is double printing of my code as it rebooted and ran the code twice and stopped.
Had to start by tracing the code with LED's to see where it was stopping. Since it was a passed function call back it made it a little harder to find.
Printing the function pointer didn't help as it printed some strange value not an address to the function that corresponded to the assembly code. Tried several configuration to see if I could get the correct address but to no avail.
Finally just added the Ampersand to the function and it worked. Not the outcome I was looking for as it makes the code inconsistent as all the other calls do not have the Ampersand.
Mike
This is a case where you need a source code debugger with singlestepping. You can find such an error in minutes.
@JRoark said:
@ersmith I hit a snag in defining two-dimensional arrays in FlexBASIC 5.0.9.
This syntax works: dim myArray(0 to 8) as long dim myArray2(8, 16) as long
But when it comes to defining a 2-dimensional array with explicit upper and lower bounds like below, the compiler throws an error: dim myArray2(0 to 8, 0 to 16)
That was actually documented under the ARRAYS section of the manual. I can relax things a little bit and allow the "to" form, but both dimensions in a two dimensional array will have to start at the same place (so dim myArray(0 to 8, 1 to 6) will not work. (There's an internal limitation, arrays only have one "base" field at present, which was why I only allowed the "to" form on one dimensional arrays.)
Is something wrong with isprint() ?
I'm getting errors like this trying to use it: 1>C:/FlexSpin/include/libc/misc/isprint.c:7: error: __ctype is not an array
Trying it like this after including ctype.h int x1 = isprint((int)'x');//test
Yes, it looks like isprint() is broken. I'll fix it in the next release. For now I suggest working around by using some of the other isxxx() functions, or just doing something like:
~~Should something like this work? I seem to remember something about a structure not being able to reference itself...
It compiles, but something is wrong...~~
`
typedef struct Line Line;
struct Line {
char *s; /* string content */
size_t l; /* length excluding \0 */
size_t v; /* visual length */
size_t m; /* multiples of LINSIZ? */
Line *p; /* previous line */
Line *n; /* next line */
};
`
Nevermind... It works... (Trying to strike out the text above doesn't work though...)
@ersmith
I have a problem and I think it's linked to my old problem of relative addressing in the compilers.
In my code I have a big set of variables that contain values and address pointers that get passed to child objects, some of which are pure pasm drivers.
Here is a snippet
dat { port/slots configuration, parameters and buffers}
'' orgh
'' ====================================================================================================================
'' WARNING: Within the following groups, the order and size must be maintained !!!
port_lcd_config {3 longs} '\ LCD configuration
long @port_params '| ptr to port_params
byte 0<<7 | LCD_SLOT '| inactive | slot# where: 1=active, bbbb=slot#
byte LCD_CE '| LCD: Serial clock enable pin
byte LCD_RST '| LCD: Reset pin (can be reset by software)
byte LCD_DC '| LCD: Data / Command selection pin
byte LCD_SDA '| LCD: Serial Data MOSI pin
byte LCD_CLK '| LCD: Serial Clock pin
byte LCD_LED '| LCD: LED backlight enable pin (hi to enable - ~2.4mA)
byte LCD_SDO '/ LCD: Serial Data MISO pin
This compiles to this from the listing
01ed4 |
01ed4 | port_lcd_config {3 longs} '\ LCD configuration
01ed4 20 00 00 00 | long @port_params '| ptr to port_params
01ed8 02 | byte 0<<7 | LCD_SLOT '| inactive | slot# where: 1=active, bbbb=slot#
01ed9 2F | byte LCD_CE '| LCD: Serial clock enable pin
01eda 2E | byte LCD_RST '| LCD: Reset pin (can be reset by software)
01edb 2D | byte LCD_DC '| LCD: Data / Command selection pin
01edc 2C | byte LCD_SDA '| LCD: Serial Data MOSI pin
01edd 2B | byte LCD_CLK '| LCD: Serial Clock pin
01ede 2A | byte LCD_LED '| LCD: LED backlight enable pin (hi to enable - ~2.4mA)
01edf 29 | byte LCD_SDO '/ LCD: Serial Data MISO pin
01ee0 |
.....
01ef4 |
01ef4 | port_params {16*4 = 64 longs} '\ max (16 ports) of 4 longs... port[slot]: buffer ptrs to p_head, p_tail, p_start, p_end
01ef4 20 01 00 00 | long {0} @BUF0 '| \ {slot 0} p_head SERIAL-RX (ptr to current head of buffer)
01ef8 20 01 00 00 | long @BUF0 '| | p_tail " (ptr to current tail of buffer)
01efc 20 01 00 00 | long @BUF0 '| | p_start " (ptr to start of buffer)
01f00 60 01 00 00 | long @BUF0+BUF_SIZE '| / p_end " (ptr to end+1 of buffer)
The real hub address is $1ef4 but when I pull out the long from hub it contains the wrong address.
Is there any way around this problem???
I have >100 lines of parameters mixed with addresses.
Due to this problem I decided to not pass parameters to routines just to set a pile of pointers and constants as it became unwieldly to call the routines/objects to do this and overly made the program so complex it was embarassing.
Help!!!
In flexspin you can use @@@ in PASM to get the absolute address. So in all of the DAT blocks if you replace "@" with "@@@" it will probably do what you want. But that's flexspin only, I don't think Chip's Spin2 has anything like that.
One alternative is to fix up the DAT section at run time as part of your start routine. As you've seen, @ does the right thing in Spin methods (because it's evaluated as a run time rather than compile time expression) so you could add something to your start function like:
if not fixup_done
fixup_done := 1
port_params[0] := @buf0
port_params[1] := @buf0
' and so on
No doubt you can come up with a more elegant variation e.g. involving a loop. The value stored in the DAT section for a plain @ is the offset from the start of the object, so you could fix up by adding the object starting address to everything that need it.
Another alternative is to store only offsets in the structure (which is effectively what @ does at compile time) and then do the calculations at run time, using the structure values as indices into an array.
Unfortunately no it can’t be filled in at runtime, only adjusted as it’s the user who fills in the table. I will give the @@@ a try tomorrow. Thanks Eric.
@ersmith Been at least a day since I asked for anything...
What do you thing about adding vsnprintf() ?
A vi-like editor I'm looking at uses this to print the status line at the bottom of the screen.
I substituted in vsprintf(), which looks to do about the same thing, but doesn't clip the size of the result (if I see it right).
Eric,
Is there any way you could add using a DAT section with ORGH $someaddress when using it with spin mixed in?
These DAT sections could be after all spin code. It would probably need to be zero padded to fill to the ORGH address tho this can be done easily as we do with pasm only. I can use the @@@ to get absolute addresses - thanks for this
I need to get some hubexec pasm code and some buffers and variables into upper fixed hub addresses, where they will remain resident. It’s for my P2 OS and Z80/CPM emulator too. I probably need to use $7B000-$7BFFF which is immediately below the dual mapped top 16KB that Chip’s using for debug and shortly to be the spin interpreter too.
Now I realise why I’ve been having so many problems getting my pasm SD Driver working with spin code. Been using @ where I should be using @@@.
@Rayman: as you guessed, tabs are determined by the terminal program. I think most default to having 8 characters between tab stops.
snprintf() should be easy to add, I'll do that.
@iseries: I think that should work, but as you can see it doesn't in the current flexcc. It seems something is broken in the set-up for two dimensional character arrays. If you change it to an array of pointers (so declare Values as "char *Values[]" instead of "char Values[][10]") then it should be OK.
@Cluso99 : Making ORGH work with Spin code present would be a serious headache, I don't think it's practical.
Can you compile the "stay resident" stuff seperately? flexspin lets you build at any starting address, so you could certainly build a binary blob that goes at $78000 and then a main program that goes at $0, but you'd have to arrange to copy the binary blob to the correct final address at boot time (or else use loadp2 to load it there; loadp2 is able to put multiple files into memory before starting the first one).
@ersmith said:
@Cluso99 : Making ORGH work with Spin code present would be a serious headache, I don't think it's practical.
Can you compile the "stay resident" stuff seperately? flexspin lets you build at any starting address, so you could certainly build a binary blob that goes at $78000 and then a main program that goes at $0, but you'd have to arrange to copy the binary blob to the correct final address at boot time (or else use loadp2 to load it there; loadp2 is able to put multiple files into memory before starting the first one).
Yes, I may have to resort to loading a separately compiled binary blob. Not sure yet. At least I've found a reason why I've been chasing bugs for month's with different results. I've probably been overwriting lower hub indiscriminately
Comments
I guess it could just be a user-defined thing - i.e. if the code has a
__handle_nullcall
function, call that, otherwise hang.how about calling reset instead of calling address 0?
Or simply ignoring a call to address 0?
Mike
Yes, the code now checks and skips function call with NULL address. I was trying to figure out if this is a bug in the code or intended behavior. This code was adapted from Unix to PC long ago... I'm now thinking it's a bug somewhere.
Hasn't happened again though, so maybe it was a fluke. Got my eye on it though...
Yes, I found a problem with some code I was converting that used call backs.
`#include <stdio.h>
include <propeller.h>
typedef long (*test)(int x, int y);
int main(int argc, char** argv)
{
printf("Starting\n");
}
long callback(int x, int y)
{
printf("X: %d, Y: %d\n", x, y);
return -1;
}
void callit(int x, int y, test v)
{
int i;
}
`
Based on where the Include file was the compiler would generate a call to the pointer to the function and in the other case generate a call to the function.
I ended up adding an & in front of the function so that it would use the address of instead of the pointer to get around it.
Looks like code blocks are not working for C code.
Mike
They are, but the button to insert code blocks doesn't insert the right kind.
Do this:
```
Your code here
```
@iseries : I think there's a problem (or more accurately an inconsistency) with trying to print a function address. In printf() function addresses are not converted to full method pointers, but whenever they are passed to a function that's expecting a function pointer they are. That's weird, but I don't think it'll actually mess anything up (except perhaps making debugging a bit harder). But I think you've hit on the work-around, always use & in front of functions if you want function pointers.
@Rayman : calling a NULL pointer is always a bug, on every platform. What it ends up doing will vary by platform (and on some platforms it may be benign) but the C standard is pretty clear that you shouldn't do that.
Yes, it took me about 10 hours to find that bad function call. All I was getting is double printing of my code as it rebooted and ran the code twice and stopped.
Had to start by tracing the code with LED's to see where it was stopping. Since it was a passed function call back it made it a little harder to find.
Printing the function pointer didn't help as it printed some strange value not an address to the function that corresponded to the assembly code. Tried several configuration to see if I could get the correct address but to no avail.
Finally just added the Ampersand to the function and it worked. Not the outcome I was looking for as it makes the code inconsistent as all the other calls do not have the Ampersand.
Mike
This is a case where you need a source code debugger with singlestepping. You can find such an error in minutes.
@ersmith I hit a snag in defining two-dimensional arrays in FlexBASIC 5.0.9.
This syntax works:
But when it comes to defining a 2-dimensional array with explicit upper and lower bounds like below, the compiler throws an error:
That was actually documented under the ARRAYS section of the manual. I can relax things a little bit and allow the "to" form, but both dimensions in a two dimensional array will have to start at the same place (so
dim myArray(0 to 8, 1 to 6)
will not work. (There's an internal limitation, arrays only have one "base" field at present, which was why I only allowed the "to" form on one dimensional arrays.)@ersmith I’m not sure how I missed that. Oops.
In that case it is probably best to leave the syntax as it is.
Is something wrong with isprint() ?
I'm getting errors like this trying to use it:
1>C:/FlexSpin/include/libc/misc/isprint.c:7: error: __ctype is not an array
Trying it like this after including ctype.h
int x1 = isprint((int)'x');//test
Yes, it looks like isprint() is broken. I'll fix it in the next release. For now I suggest working around by using some of the other isxxx() functions, or just doing something like:
~~Should something like this work? I seem to remember something about a structure not being able to reference itself...
It compiles, but something is wrong...~~
`
`
Nevermind... It works... (Trying to strike out the text above doesn't work though...)
@ersmith
I have a problem and I think it's linked to my old problem of relative addressing in the compilers.
In my code I have a big set of variables that contain values and address pointers that get passed to child objects, some of which are pure pasm drivers.
Here is a snippet
This compiles to this from the listing
In spin if I get @port_params
with this result on the screen
The real hub address is $1ef4 but when I pull out the long from hub it contains the wrong address.
Is there any way around this problem???
I have >100 lines of parameters mixed with addresses.
Due to this problem I decided to not pass parameters to routines just to set a pile of pointers and constants as it became unwieldly to call the routines/objects to do this and overly made the program so complex it was embarassing.
Help!!!
In flexspin you can use @@@ in PASM to get the absolute address. So in all of the DAT blocks if you replace "@" with "@@@" it will probably do what you want. But that's flexspin only, I don't think Chip's Spin2 has anything like that.
One alternative is to fix up the DAT section at run time as part of your start routine. As you've seen, @ does the right thing in Spin methods (because it's evaluated as a run time rather than compile time expression) so you could add something to your start function like:
No doubt you can come up with a more elegant variation e.g. involving a loop. The value stored in the DAT section for a plain @ is the offset from the start of the object, so you could fix up by adding the object starting address to everything that need it.
Another alternative is to store only offsets in the structure (which is effectively what @ does at compile time) and then do the calculations at run time, using the structure values as indices into an array.
Unfortunately no it can’t be filled in at runtime, only adjusted as it’s the user who fills in the table. I will give the @@@ a try tomorrow. Thanks Eric.
Woohoo![:smiley: :smiley:](https://forums.parallax.com/resources/emoji/smiley.png)
@@@ works.
Not sure if this solves everything but it sure helps.
I've spent days chasing some bugs that are all probably to do with this problem.
Thanks Eric![:smiley: :smiley:](https://forums.parallax.com/resources/emoji/smiley.png)
@ersmith Been at least a day since I asked for anything...![:) :)](https://forums.parallax.com/resources/emoji/smile.png)
What do you thing about adding vsnprintf() ?
A vi-like editor I'm looking at uses this to print the status line at the bottom of the screen.
I substituted in vsprintf(), which looks to do about the same thing, but doesn't clip the size of the result (if I see it right).
What decides how many spaces you get with a tab using printf() ?
After thinking about this, I guess it's the terminal program that decides...
Is this suppose to work:
Mike
Seems to work with this:
char* Values[10] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
Eric,
Is there any way you could add using a DAT section with ORGH $someaddress when using it with spin mixed in?
These DAT sections could be after all spin code. It would probably need to be zero padded to fill to the ORGH address tho this can be done easily as we do with pasm only. I can use the @@@ to get absolute addresses - thanks for this![:) :)](https://forums.parallax.com/resources/emoji/smile.png)
I need to get some hubexec pasm code and some buffers and variables into upper fixed hub addresses, where they will remain resident. It’s for my P2 OS and Z80/CPM emulator too. I probably need to use $7B000-$7BFFF which is immediately below the dual mapped top 16KB that Chip’s using for debug and shortly to be the spin interpreter too.
Now I realise why I’ve been having so many problems getting my pasm SD Driver working with spin code. Been using @ where I should be using @@@.
@Rayman: as you guessed, tabs are determined by the terminal program. I think most default to having 8 characters between tab stops.
snprintf() should be easy to add, I'll do that.
@iseries: I think that should work, but as you can see it doesn't in the current flexcc. It seems something is broken in the set-up for two dimensional character arrays. If you change it to an array of pointers (so declare Values as "char *Values[]" instead of "char Values[][10]") then it should be OK.
@Cluso99 : Making ORGH work with Spin code present would be a serious headache, I don't think it's practical.
Can you compile the "stay resident" stuff seperately? flexspin lets you build at any starting address, so you could certainly build a binary blob that goes at $78000 and then a main program that goes at $0, but you'd have to arrange to copy the binary blob to the correct final address at boot time (or else use loadp2 to load it there; loadp2 is able to put multiple files into memory before starting the first one).
@ersmith regarding the asmclk thing...
Is there a subroutine around that we could use to do something like this:
Is there a way to launch a compiled PASM2 binary from within Spin2? Something like this:
Yes, I may have to resort to loading a separately compiled binary blob. Not sure yet. At least I've found a reason why I've been chasing bugs for month's with different results. I've probably been overwriting lower hub indiscriminately![:( :(](https://forums.parallax.com/resources/emoji/frowning.png)
@Rayman: Chip gives a definition for asmclk in his Spin2 document. I'll look again at it later, maybe I can hack something in.
As for launching a compiled binary from within Spin2, sure, your example should work fine.