Page 1 of 1
4.31 Strange procedure behaviour
Posted: Mon Jun 22, 2009 5:48 pm
by RE-A
I'm new to PB and this is my first post on this forum.
I'm experiencing a strange procedure behaviour (Ubuntu 9.04). Because the build-in serial communication functions don't work(?), I'm trying to use the Linux api's to control the com port with the standard “tcgetattr” function to set the port settings, baud, etc… The code works fine if used outside a procedure, if used inside I get a “Invalid memory access” error on the Endprocedure line.
I was able to reproduce the problem:
Code: Select all
#O_RDWR = 02
#O_NOCTTY = 0400
#O_NONBLOCK = 04000
#O_NDELAY = #O_NONBLOCK
Structure termios
c_iflag.i
c_oflag.i
c_cflag.i
c_lflag.i
c_line.c
c_cc.s{17}
EndStructure
#TestProcedure = 1 ; 0 - 1
Procedure TestCom()
lngCommHandle = open_("/dev/ttyS0", #O_NDELAY | #O_NOCTTY | #O_RDWR , 0)
tcgetattr_(lngCommHandle, @mTer.termios) ;???
MessageRequester("", Str(mTer\c_cflag))
close_(lngCommHandle)
EndProcedure ;Invalid memory access error??????
OpenConsole()
If #TestProcedure
TestCom()
Else
lngCommHandle = open_("/dev/ttyS0", #O_NDELAY | #O_NOCTTY | #O_RDWR , 0)
tcgetattr_(lngCommHandle, @mTer.termios)
MessageRequester("", Str(mTer\c_iflag))
close_(lngCommHandle)
EndIf
Debug "Test"
CloseConsole()
I’ve found this thread on the forum:
http://www.purebasic.fr/english/viewtop ... +procedure
but this was only for imported functions.
Is there some work-around for this problem?
Posted: Mon Jun 22, 2009 6:52 pm
by dhouston
There appears to be no rhyme nor reason to the
Invalid Memory Access message. In my experience, the line flagged is seldom the line causing the problem, making it hard to troubleshoot. And, I have also seen cases where in-line code works but causes
Invalid Memory Access when the same code is called in a function.
You might want to look at the code I posted in the
http://www.purebasic.fr/english/viewtop ... highlight= thread. It shows two working methods for serial comms as well as the non-working native commands. You can make a simple loopback adapter to test both sending/receiving.
Posted: Mon Jun 22, 2009 7:15 pm
by RE-A
I'm very new to Linux programming and was not sure if I made a mistake, maybe this is something for the "bug" section.
I've seen and tested your code and came to the same results. The PB native commands don't work. The library Serial[Linux] does but I need to use the com port in bit-bang mode and need to set or reset every pin available on the port. My problem with that is the TXD line that seems to be not supported by the library and is one of those lines that I need to control. So I’m stuck with the api commands also

Posted: Mon Jun 22, 2009 8:34 pm
by dhouston
Yeah - I have some applications where I need to send a Break signal to get the attention of an embedded device so controlling TXD is necessary. If Purebasic ever gets the serial functions working in Linux, perhaps they can add control of all the pins.
Posted: Mon Jun 22, 2009 8:53 pm
by freak
Your termios structure is wrong. The c_cc array has 32 entries according to my bits/termios.h definition. Also there are two more entries for input and output speed.
Try this one:
Code: Select all
#NCCS = 32
Structure termios
c_iflag.l ; .l because .i changes size with the x64 version
c_oflag.l
c_cflag.l
c_lflag.l
c_line.b ; .b because .c changes size in unicode mode (you can keep using .c only if you don't use unicode mode)
c_cc.b[#NCCS]
c_ispeed.l
c_ospeed.l
EndStructure
Posted: Mon Jun 22, 2009 10:08 pm
by RE-A
Thanks Freak, that did it. I found some definitions on the net but none of them defined 32 NCC bytes to be returned. Maybe you know some good com port linux programming resources
It still leaves me with the strange memory error, very confusing that this error occurred on exiting the procedure instead on the actual error line.
Posted: Tue Jun 23, 2009 9:30 am
by Trond
Run this. It prints some numbers, which should be equal. If the printed number changes, then you know something messed up the stack.
Code: Select all
Global _regout
Macro regout(register)
!push register
!pop [v__regout]
!pushad
Debug _regout
!popad
EndMacro
#O_RDWR = 02
#O_NOCTTY = 0400
#O_NONBLOCK = 04000
#O_NDELAY = #O_NONBLOCK
Structure termios
...
EndStructure
Procedure TestCom()
regout(esp)
lngCommHandle = open_("/dev/ttyS0", #O_NDELAY | #O_NOCTTY | #O_RDWR , 0)
regout(esp)
tcgetattr_(lngCommHandle, @mTer.termios) ;???
regout(esp)
MessageRequester("", Str(mTer\c_cflag))
regout(esp)
close_(lngCommHandle)
regout(esp)
EndProcedure ;Invalid memory access error??????
OpenConsole()
TestCom()
Debug "Test"
CloseConsole()
Posted: Tue Jun 23, 2009 3:59 pm
by RE-A
Thanks Trond, I tried the macro but it returned always the same number for a good or bad termios definition. So the stack should be ok.
Posted: Tue Jun 23, 2009 5:16 pm
by freak
You passed a too small structure to a function which expects a larger input, so the function writes past the end of your input structure and overwrites the procedure return address on the stack. Thats why you get the crash when you try to leave the procedure.
Posted: Tue Jun 23, 2009 6:06 pm
by Trond
freak wrote:You passed a too small structure to a function which expects a larger input, so the function writes past the end of your input structure and overwrites the procedure return address on the stack. Thats why you get the crash when you try to leave the procedure.
But he said he got the problem even with your structure, shouldn't that one be correct?
Posted: Tue Jun 23, 2009 7:10 pm
by freak
As I understood it, he only wants to know why the crash happened the way it did with his original definition.
Posted: Tue Jun 23, 2009 8:31 pm
by Trond
Aha.
It still leaves me with the strange memory error
Posted: Tue Jun 23, 2009 10:55 pm
by freak
RE-A wrote:... very confusing that this error occurred on exiting the procedure instead on the actual error line.
Anyway, the code doesn't crash here anymore so it should be correct now.