4.31 Strange procedure behaviour

Linux specific forum
RE-A
User
User
Posts: 39
Joined: Thu Aug 21, 2008 4:19 pm
Location: Belgium
Contact:

4.31 Strange procedure behaviour

Post 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?
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Post 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.
RE-A
User
User
Posts: 39
Joined: Thu Aug 21, 2008 4:19 pm
Location: Belgium
Contact:

Post 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 :cry:
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Post 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.
freak
PureBasic Team
PureBasic Team
Posts: 5948
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post 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
quidquid Latine dictum sit altum videtur
RE-A
User
User
Posts: 39
Joined: Thu Aug 21, 2008 4:19 pm
Location: Belgium
Contact:

Post 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.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post 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()

RE-A
User
User
Posts: 39
Joined: Thu Aug 21, 2008 4:19 pm
Location: Belgium
Contact:

Post 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.
freak
PureBasic Team
PureBasic Team
Posts: 5948
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post 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.
quidquid Latine dictum sit altum videtur
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post 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?
freak
PureBasic Team
PureBasic Team
Posts: 5948
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

As I understood it, he only wants to know why the crash happened the way it did with his original definition.
quidquid Latine dictum sit altum videtur
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Aha.
It still leaves me with the strange memory error
freak
PureBasic Team
PureBasic Team
Posts: 5948
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

RE-A wrote:... very confusing that this error occurred on exiting the procedure instead on the actual error line.
:P

Anyway, the code doesn't crash here anymore so it should be correct now.
quidquid Latine dictum sit altum videtur
Post Reply