Passing a structure BYRef

Discussion about the ZBasic language including the System Library. If you're not sure where to post your message, do it here. However, do not make test posts here; that's the purpose of the Sandbox.
Post Reply
victorf
Posts: 342
Joined: 01 January 2006, 4:08 AM
Location: Schenectady, New York

Passing a structure BYRef

Post by victorf »

If I have defined a structure:

Code: Select all

Structure SensorDataType
	tiltx as Single
	tilty as Single
	heading as Single
End Structure
and created an instance of the stucture thusly:

Code: Select all

Dim x as SensorDataType
can the variable x be passed to a routine as a ByRef variable like this:

Code: Select all

Call mySub(x)

Code: Select all

Public mySub(ByRef sd as SensorDataType)
End Sub
Any enlightenment will be appreciated

Vic
Vic Fraenckel
KC2GUI
windswaytoo ATSIGN gmail DOT com
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

[Can a structure] be passed to a routine as a ByRef variable [...]?
Yes.

Structures may also be passed ByVal. However, in that case the structure variable is read-only in that subroutine. This is the same way that strings are handled. It is important to note that when a structure is passed ByVal, behind the scenes it is really passed by reference. This means that the same amount of stack space is used to pass a structure by value irrespective of the size of the structure.
- Don Kinzer
stevech
Posts: 715
Joined: 22 February 2006, 20:56 PM

Post by stevech »

If I recall correctly, if you don't declare byval in the sub/function prototype, the compiler defaults to byref, as does VB
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

If I recall correctly, if you don't declare ByVal [...] the compiler defaults to byref, as does VB.
That is true.
- Don Kinzer
liam.zbasic
Posts: 163
Joined: 24 March 2008, 23:33 PM
Location: Southern California (Blue)

Post by liam.zbasic »

Hello,

If the structure includes a member defined as an array, can the structure still be passed to a function or subroutine, or does that array still need to be committed to RAM?

Liam
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

liam.zbasic wrote:If the structure includes a member defined as an array, can the structure still be passed to a function or subroutine[...]
Yes. Here is a simple example:

Code: Select all

Structure bar
  Dim i as Integer
  Dim a(1 to 10) as Byte
End Structure

Dim b1 as bar
Dim i as Integer

Sub Main()
  Call foo(b1)
End Sub

Sub foo(ByRef b as bar)
  Debug.Print b.a(i)
End Sub
Note that if the structure is passed ByVal it is read-only in the receiving procedure.
liam.zbasic wrote:[...] or does that array still need to be committed to RAM?
I'm not sure what you're getting at. All data (other than Program Memory data and Persistent data) resides in RAM. Do you have some example code that isn't doing what you expect it to do?
- Don Kinzer
liam.zbasic
Posts: 163
Joined: 24 March 2008, 23:33 PM
Location: Southern California (Blue)

Post by liam.zbasic »

I've been reading the documentation on passing arrays because I need to streamline my code. But I'm a bit confused. I was under the impression that an array defined in the main module, similar to your example above, resides in Program Memory, by default.

The ZbasicRef (2.2.8) on page 47 shows the allowed parameter passing methods. It says that a Program Memory Array can not be passed to a sub or function. So I thought I way around that was to embed the array in a structure (I was reaching here).

Overall I think this thread is helping. Here's my thinking:

1. Write code in ZBASIC IDE (let's use your simple example above)
2. Compile and Download to ZX-40A
3. ZX-40A... code resides in program memory (64K available, ~100,000 write cycles permitted)
4. All variables defined in simple example reside in RAM. As variables & arrays get updated during ZX-40A code execution, do updates count against the chip write cycles?

What still confuses me is that program memory is also RAM, and separately there is User RAM (3584 bytes). I know there is more, but its not worth mentioning until I get the fundamentals.
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

liam.zbasic wrote:3. ZX-40A... code resides in program memory (64K available, ~100,000 write cycles permitted)
One source of confusion is that the memory spaces and write cycle limitations are somewhat different depending on which ZX device is being considered. On VM devices like the ZX-24a, ZX-40a, etc. your code is stored in an EEPROM that is external to the AVR chip. On those devices, then Program Memory is the external EEPROM chip and the write cycle limit is a million cycles. On larger VM devices (e.g. ZX-1281, ZX-1280) and on all native mode devices, your code is stored in Flash memory that is internal to the AVR chip. Flash memory has a lower write cycle limit, on the order of 10,000 cycles.
liam.zbasic wrote:4. All variables defined in simple example reside in RAM. As variables & arrays get updated during ZX-40A code execution, do updates count against the chip write cycles?
The first statement is correct. Note that writes to RAM do not count against the write cycle limit of Program Memory. Practically speaking, RAM has no write cycle limit.
liam.zbasic wrote:What still confuses me is that program memory is also RAM, and separately there is User RAM (3584 bytes).
The AVR chip has only one block of RAM, the size of which varies by device. On VM-mode devices, some of the RAM is reserved for system use (stack, data structures, etc.) and the remainder is called User RAM. The User RAM is further divided into three functional areas: statically allocated data items (e.g. variables defined at the module level), the task stack for the Main() task, and the heap. (The heap is primarily used for the actual characters of a string variable, allocated as needed, but it can also be used for other run-time allocated data.)

For any given program, the size of the statically allocated data is known at compile time. Consequently, the Main() task stack and the heap nominally split the remaining User RAM. (Things are a bit more complicated than that but that will suffice for now, at least for VM mode devices.)

On native mode devices, none of the RAM is reserved for "system" use. Rather, depending on the set of System Library routines that you used, the statically allocated portion includes more or fewer of the "system" data structures in addition to the statically allocated variables that you define and use in your program. As in the VM mode case, the remaining RAM is split between the task stack for Main() and the heap. With native mode devices, you have to think about heap and stack usage a bit more when coding your application than you do with VM mode devices due to some technical peculiarities of native mode.

More information on how RAM is partitions can be found in the ZBasic User Manual.
http://www.zbasic.net/doc/ZBasicRef.php?page=95

To complete the discussion of memory areas, we must also mention Persistent memory. Persistent memory is a non-volatile memory implemented using the internal EEPROM of the AVR. The Persistent memory has a write cycle limit of 100,000 cycles.

Lastly, you should also be aware that you can create both read-only and writeable data items in Program Memory. Although ProgramMemory data items are typically used for table data and are consequently read-only, you can define them to be read-write so that you can update them if you wish.
- Don Kinzer
stevech
Posts: 715
Joined: 22 February 2006, 20:56 PM

Post by stevech »

I've long wondered why one would want to pass a structure or array byval, esp. on a small-memory micro.
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

stevech wrote:I've long wondered why one would want to pass a structure or array byval, esp. on a small-memory micro.
Even when you specify ByVal, the structure/array actually gets passed by reference behind the scenes. To further the impression that it is passed by value it is marked as read-only in the receiving procedure.

The bottom line is that there is no "cost" to passing an array or structure by value in ZBasic as there might be in other languages where the data item is actually replicated and truly passed by value.
- Don Kinzer
stevech
Posts: 715
Joined: 22 February 2006, 20:56 PM

Post by stevech »

Ah, makes sense. But that's an implementation issue. I suppose no dope would implement byval as a struct/array copy to RAM allocated off the stack.
Post Reply