Capture of Target Device by Option TargetDevice

Discussion of issues related to writing ZBasic applications for targets other than ZX devices, i.e. generic targets.
Post Reply
DocJC
Posts: 112
Joined: 16 March 2006, 6:23 AM
Location: Cleveland, OH
Contact:

Capture of Target Device by Option TargetDevice

Post by DocJC »

I wrote my first ZBasic program, an LCD driver, for the XMega64A1.
I used two Options, TargetDevice and ClockFrequency
It worked :)

I deleted 90% of the program to look at a simple LED Chaser.
I retained the two Options above.

The compiler now gives me a SetBits Error, and after closer scrutiny it appears that it is trying to compile for the ZX-24, not for the Xmega64A1.

I'm not sure why it doesn't capture the target device from the Options Instruction.

Guidance appreciated, as always!

I am getting an Error Message using SetBits():

Extracted from a slightly longer program:

Code: Select all

  option TargetDevice ATXmega64A1    'Define the micros
  option DeviceParameter ClockFrequency 2000000 'Xmega Clock Freq, Default 2 MHz 

   Dim J As Byte
   Dim D As Byte         'LCD Chaser LED Counter
   Dim Lc As Byte        'LED Chaser Counter

Sub called from Main:

Code: Select all

Sub Ledflash2()
   'LED Chaser for the Eight Port F LEDs.
   'Uses Exponential for Bit Chaser.
   J = 0                                                    'Init bit pattern
   For Lc = 1 To 10                                         'Do 10 LED Chases
      For D = 0 To 7                                        'Loop Counter for 1 Chase
         J = 2 ^ D                                          'Single bit riples high
         Call SetBits(Register.PortF, &HFF, J)
		 Call Delay(0.05)
      Next D
  Next Lc
End Sub
Error generated:
>"C:\Program Files (x86)\ZBasic\zbasic.exe" --target-device=ZX24 --directory="C:\Users\Jay\Desktop\ZBasic Compiler Beta\ZBasic Progs\Char LCD Driver/" "ZBasic XMega Test SetBits V1.bas"
ZBasic XMega Test SetBits V1.bas:218: Error: reference to undefined identifier "Register.PortF"
1 error.
>Exit code: 1


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

Re: Capture of Target Device by Option TargetDevice

Post by dkinzer »

DocJC wrote:I'm not sure why it doesn't capture the target device from the Options Instruction.
When the compiler is invoked, the --target-device parameter is set from the current device selection, irrespective of any Option TargetDevice directive that might exist in the source code. Generally, it is best to select the desired target device using the Device Options... entry on the Options menu. That said, the way that you're doing it should work; we'll look into why it isn't.
- Don Kinzer
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: Capture of Target Device by Option TargetDevice

Post by dkinzer »

DocJC wrote:

Code: Select all

Error: reference to undefined identifier "Register.PortF"
None of the xmega devices have a register named PortF. The xmega I/O ports have a different structure comprising many more registers compared to the mega/tiny devices. I think the register that you wanted was Register.PortF_Out.
- Don Kinzer
DocJC
Posts: 112
Joined: 16 March 2006, 6:23 AM
Location: Cleveland, OH
Contact:

Post by DocJC »

Register.PortF_Out
That should fix that, Thank you.

Also, I would have thought that the Option TargetDevice within the source code would override the setting in the IDE, but only because that is the priority I am use to. I can see how either method has its pros & cons.

Perhaps adding another line within the manual, under the Options TargetDevice paragraph, stating that the IDE setting overrides the setting within the code, if that is the intended method, would be worth while.

I guess my preference would be for the source code setting to override the IDE setting, and for the compiler to generate a warning if they don't match, (but go ahead and compile to the source code specified target device).

Clearly if one is using the compiler then one has the source code to then either change the line in the code, or REM out the "incorrect" Option TargetDevice line in the source code, if they are compiling for a different device.

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

Post by dkinzer »

DocJC wrote:I would have thought that the Option TargetDevice within the source code would override the setting in the IDE
It does. The IDE's device setting provides the initial value for the target device (the one that appears in the compiler's invocation) and that can superseded by one or more Option TargetDevice directives in the source code.

So, the bottom line is that you can continue to use Option TargetDevice in the source code if you wish and it should produce the correct result irrespective of the setting in the IDE.
- Don Kinzer
DocJC
Posts: 112
Joined: 16 March 2006, 6:23 AM
Location: Cleveland, OH
Contact:

Post by DocJC »

Good.

I see now, having corrected my mistake in naming the Xmega Port, that:

While the program contains an error, the compiler output lists the (incorrect) target device as the ZX24, and does not update this with the Option TargetDevice data from within the program.

When the program is error free the compiler output correctly sites the target device as the Xmega, as per the Option TargetDevice line in the code, (overriding the IDE device setting).

JC
Don_Kirby
Posts: 341
Joined: 15 October 2006, 3:48 AM
Location: Long Island, New York

Post by Don_Kirby »

DocJC wrote:While the program contains an error, the compiler output lists the (incorrect) target device as the ZX24, and does not update this with the Option TargetDevice data from within the program.
I think what happens in this case is that the compiler stops during the precompiling stage if it finds an error; it never gets the chance to see the Option TargetDevice statement. In the absence of that directive, the default IDE setting is used.

I've thought alot about how to better handle the ability to set the same setting in multiple places (such as this case). Beyond proper documentation, which Don has done exceedingly well, there isn't a nice way to avoid this. It does force the user to look deeper into what their settings are set to, which is not necessarily a bad thing.

-Don Kirby
DocJC
Posts: 112
Joined: 16 March 2006, 6:23 AM
Location: Cleveland, OH
Contact:

Post by DocJC »

Understood.

I guess it really doesn't matter while there are still bugs in the program that prevent the program from compiling. It just caught my eye as I was debugging a program, and it wasn't at first clear what the issues were.

It is now clear that the compiler correctly grabs the correct device from the Options Target Device line within the program when there are no errors present.

Bottom line: It works, so fix the bugs and ignore the listing for the Target Device.

JC
stevech
Posts: 715
Joined: 22 February 2006, 20:56 PM

Post by stevech »

Trouble is, that process is counter-intuitive from the source code writer's viewpoint.

IMO: the CPU target should be in the GUI of the IDE and removed as keywords/pragmas in the source. This could prevent such quagmires. That's what I'm accustomed to with IAR and Keil.
Don_Kirby
Posts: 341
Joined: 15 October 2006, 3:48 AM
Location: Long Island, New York

Post by Don_Kirby »

IMO: the CPU target should be in the GUI of the IDE and removed as keywords/pragmas in the source.
That would irrevocably tie the code and the compiler to the IDE, which are all separate components. Currently, the compiler can be called from any application, editor, or directly from the command line. This is done purposefully, I would think, so as to retain as much implementation flexibility as possible. If the source code didn't have the target instructions embedded in it, the compiler would have no way to know which device to compile for, unless it were being invoked via the IDE. While the percentage is small, I think that there are some users who don't use the IDE and either call the compiler manually from the command line, or use a different editor. I've always felt as though the IDE was a feature, but not the actual product. The compiler is where the magic happens, and its' written to be able to be used independently.

That said, these details have bitten me in the past. I've often set the IDE to one setting, and the code to another, then couldn't figure out what was happening when things didn't work as I intended. This issue is more severe than one would think, as you can set the same option in a total of 4 places, the GUI of the IDE, the project file, the module level code, and perhaps conditional compilation blocks. I still don't see any better method except for documenting how it all works. The only possible modification I would make is to issue warnings in the IDE during compiling, indicating that the IDE's settings are being overridden by code/project files/conditional compilation/etc...


-Don
stevech
Posts: 715
Joined: 22 February 2006, 20:56 PM

Post by stevech »

Don_Kirby wrote:
IMO: the CPU target should be in the GUI of the IDE and removed as keywords/pragmas in the source.
...

That said, these details have bitten me in the past. I've often set the IDE to one setting, and the code to another, then couldn't figure out what was happening when things didn't work as I intended.
-Don
Yep. Been there, done that too. Many times. My experiences with this in various IDEs/tools is why I recommended eliminating the pragma. If you move the source to a different IDE, then adapt that one. But not often does the code make such a move.

Pramas themselves are compiler-tool-specific, not well standardized. In the ARM world, there is a list of standardized pragmas. But such is n/a in our context.
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

Don_Kirby wrote:
DocJC wrote:While the program contains an error, the compiler output lists the (incorrect) target device as the ZX24, and does not update this with the Option TargetDevice data from within the program.
I think what happens in this case is that the compiler stops during the precompiling stage if it finds an error; it never gets the chance to see the Option TargetDevice statement.
The IDE target device setting is used to set the initial target device on the compiler invocation line. This can be overridden by other --target-device options (e.g. in the project file) or by one or more 'Option TargetDevice' directives in the source code. Only the first source module processed may contain an 'Option TargetDevice' directive and, if present, it may only appear in the 'Options section", i.e. before any data definition (constant, variable class, structure enum) and before any procedure definition. Each option directive is processed in the order in which it occurs in the source files and changes are made at that time to the compiler's "state" as indicated by the directive.

So, for the case originally described by Jay, the compiler was invoked with the default target device; that's why --target-device=ZX24 appears in the compiler invocation line. However, he specified 'Option TargetDevice atxmega64a1' in the source code so that when the SetBits() call with Register.PortF in it was encountered, the compiler had already switched to targetting the xmega64a1 for which that register is invalid (it was also invalid, of course, for the initial target).

It appears to me that everything is working as expected. It might be misleading to see the --target-device-ZX24 in the compiler invocation line but that makes sense because the neither the IDE nor the compiler have yet processed the project file and the source code and therefore can't know what target device either might specify.

I mentioned in an earlier post that it was preferable to set the target device via the IDE's Options|Device Options... dialog. This is probably more important for generic devices because the IDE uses its target device setting to select the download method. At download time, if the selected target device is a ZX or if the target is configured as having a ZBasic-compatible bootloader then the standard download protocol is used. Otherwise, the special downloading command given by the setting of command.project.avr.go in the User Properties is used. Note, too, that this command may incorporate $(target_device) macro and the text for this macro is derived from the currently selected target in the IDE.
- Don Kinzer
DocJC
Posts: 112
Joined: 16 March 2006, 6:23 AM
Location: Cleveland, OH
Contact:

Post by DocJC »

I agree, it is working appropriately.

I just did not correctly understand the entire process when I made the original post.

I do appreciate everyone's patience and guidance as I come up to speed.

JC
Post Reply