Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
November 21, 2024, 01:11:44 13:11


Login with username, password and session length


Pages: [1]
Print
Author Topic: Using Proteus to simulate Arduino uising extenally generated .elf file  (Read 5022 times)
0 Members and 2 Guests are viewing this topic.
chicowood
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 101
-Receive: 29


« on: August 08, 2020, 11:12:58 23:12 »

Hi - For years I've been using Proteus to simulate PIC firmware and hardware by using the MPLAB/MPLABX Proteus plugin. It's been a useful tool in my development workflow. Proteus simulation isn't perfect, but it's saved me a lot of time and solder...

I recently started doing the same with the Arduino IDE and the AVR processors in Proteus. Since there is no plugin to tie the Arduino IDE (or any other Arduino IDEs, like VSCode, PlatformIO, etc.) to Proteus, I generate .elf files from the GCC-AVR compiler and load them directly into the AVR processor on Proteus.

I encountered a number of frustrating issues doing this, but eventually worked through them. I'd like to share my workflow to assist others who may want to do the same, perhaps save someone time or trouble.

Proteus has the ability to set up a firmware project itself. However, I encountered a number of issues when using this. You can set up Proteus to directly use the Arduino IDE compiIer toolchain but I found sometimes sketches would compile in the Arduino IDE but not the Proteus IDE, and I was not able to figure out why (sometimes Proteus couldn't find libraries that were right there). The Proteus system compiles to a hard-to-locate temp directory unless the project settings "Embed Files" box is unchecked, which dumps all the compiler output into the project folder.  I also found the Proteus editor and IDE user interface to be awkward. I prefer to develop code in the Arduino IDE, VSCode, or more sophisticated editor suites, and let Proteus do the simulation, not the code building.

Because of these issues, I decided to avoid using the Proteus firmware development environment, and to use the Arduino IDE toolchain directly. Here is the way I've set up my system:

1) Create the hardware schematic in Proteus, using one of the AVR processors.

2) Create the firmware project in the IDE of choice. I prefer to write code using VSCode as my editor and to use the VSCode Arduino Extension to compile the code using the Arduino IDE toolchain. That way I can easily switch from the Arduino IDE to VSCode as desired for different purposes. Some prefer to use the PlatformIO extension in VSCode or Eclipse, that's fine, but I prefer to avoid creating a separate toolchain from the default Arduino IDE toolchain.

3) Edit the Arduino preferences.txt file. This text file is referenced in the Arduino IDE preferences window. Add the line "build.path=(path)", setting the path to wherever you prefer the Arduino build output to be placed (* if anyone knows how to make this path dynamic rather than static so you could place the output in the project folder, I'd appreciate a how-to...*)

4) If you are using VSCode to edit and build the Arduino firmware, edit the arduino.json project file to include the line, "output": "../VSCode_output", to place the Arduino build output into the specified VSCode_output folder.

5) When building for Proteus simulation, instruct the compiler to turn off optimization. If this isn't done, the resulting .elf file will display incomplete code addresses in Proteus, and sometimes even fail to provide a .ino file for debugging purposes.

To do this, preface the Arduino sketch with:

Code:
#pragma GCC optimize ("-O0")
#pragma GCC push_options
...and terminate the Arduino sketch with:

Code:
#pragma GCC pop_options

This will tell the compiler not to perform any optimization. This will result in larger firmware files, so these #pragma lines can be commented out when building and uploading the firmware to the actual hardware.

6) Build the file in the Arduino IDE, VSCode or (your choice).  The .elf file will be written to the output folder specifed in item #3 or #4 above.

7) In Proteus, add the .elf file to the processor properties (control-i, "Properties"). Simulate using the Proteus system debugger, as described in the Proteus documentation.

Works well for me. Hope it's helpful for someone else too.

Now if only there were a similar firmware/hardware simulation environment for the ESP8266/ESP32... Wink

« Last Edit: August 08, 2020, 11:16:16 23:16 by chicowood » Logged
chicowood
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 101
-Receive: 29


« Reply #1 on: August 15, 2020, 08:14:14 20:14 »

Addendum: If you encounter the issue of Proteus simulation not displaying local variable values, despite having compiler optimization turned off:

The compiler will sometimes use registers to handle local variables. If you can't find a particular local variable in the "AVR Variables" list, press control-D in the AVR Source Code window to view the compiler-generated assembly code. Next open "Debug -> AVR -> CPU Registers". Search for the desired local variable in the Source Code window, and step through the disassembled code below the C++ code line that contains the variable.

You should see the processor load a variable into the register indicated in the source code, and you will see the value of the local register in the CPU Registers window.

For example, if the C++ source code line is "x = 0", you will see assembly code that looks something like "ST Y+5, R1" below it, and as you step through, you will see R1 change to reflect the value of x.

If the C++ source code line is "if (x == false)", you will see assembly code that looks something like "LD R25, Y+1" below it, and as you step through, you will see R25 change to reflect the value of x before the comparision occurs.

I haven't done assembly coding since the original days of the Z80 and 8031/8048 chips, but even if you've never played with assembly, it's pretty self-explanatory for simple usage cases like this.

EDIT: Someone just pointed out to me that as an alternative, you can just declare the local variable as "volatile" to get it to appear as a listed variable in Proteus, since in that case the compiler won't store it solely in a register instead of ram. I tested this, it works. I'm not sure why turning off optimization doesn't do this as well, but it doesn't, so...
« Last Edit: August 15, 2020, 10:24:25 22:24 by chicowood » Logged
mitsos
Hero Member
*****
Offline Offline

Posts: 860

Thank You
-Given: 3086
-Receive: 4596


« Reply #2 on: August 25, 2024, 10:35:38 10:35 »

hi

in IDE 1.8.19, the only way to change optimization level to -O0 or -Og for best debugging in Proteus, is to edit the platform.txt (you can find this here C:\Users\user_name\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.4\platform.txt)
and change the three options -Os in the following lines
compiler.c.flags=-c -g -Os {compiler.warning_flags} -std=gnu11.......
compiler.c.elf.flags={compiler.warning_flags} -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections
compiler.cpp.flags=-c -g -Os {compiler.warning_flags} -std=gnu++11.....

is there a way to do this in the source file by adding the correct instructions?
the #pragma ..... is not working at me

regards
mitsos
Logged
chicowood
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 101
-Receive: 29


« Reply #3 on: August 26, 2024, 02:09:46 02:09 »

Hi mitsos

Quote
is there a way to do this in the source file by adding the correct instructions?
the #pragma ..... is not working at me

This goes back 4 years so I apologize, my memory isn't the best...I'm still using the Arduino UNO-based EV J1850 charge controller I built with this project, but can barely remember the details of how I put it together Wink

Pulling up the old files, I see I was using both the Windows and MacOS versions of the Arduino IDE during development (I usually run Proteus under Windows on Parallels on a Mac). My most recent sketch that includes the lines "#pragma GCC optimize ("-O0")" and "#pragma GCC push_options" still compiles ok. Kind of rare to have something survive 4 years of tool chain changes!

The compiler running on the Mac appears to be the one I used in the final stages of the project. It is the GCC AVR compiler. Here's a snippet of the compiler output from the Arduino IDE to show the compiler version:

Code:
Compiling core...
/Users/myUserName/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/Users/myUserName/Library/Arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino -I/Users/myUserName/Library/Arduino15/packages/arduino/hardware/avr/1.8.6/variants/standard /Users/myUserName/Library/Arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/HardwareSerial1.cpp -o /private/var/folders/dz/6mp0vphs7s7brkdmvyqtwz280000gn/T/arduino/sketches/CE64994574F853DE4713102783194896/core/HardwareSerial1.cpp.o
....(etc)

As I recall I found the #pragma commands in the compiler documentation and they worked as expected.

It's possible that the compiler on your Windows installation is different than the one on my Mac installation? I'm sure you know the following but I post it for anyone else who may be interested:

(From Wikipedia) In C, the #pragma directive is a special purpose directive that is used to turn on or off some features. #pragma also allows us to provide some additional information or instructions to the compiler. It is compiler-specific i.e., the behavior of pragma directive varies from compiler to compiler.

I hope that's helpful. Let me know if you would like any other info from this project...

chico
Logged
Pages: [1]
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright © 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC