Atmel Toolchain For Linux supporting ATtiny104

Go To Last Post
71 posts / 0 new

Pages

Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was all revved up to port a project to the t104 when I ran up against a wall.  The lastest Atmel toolchain for Linux (or Windows, for that matter) is 3.5.4 (with AVR GCC 4.9.2) which, of course, has no support for the ATtiny104.

 

I found the atpack which includes support for the t104, but I'm not sure how, or even if, I can integrate that into the 3.5.4 toolchain.  I've identified a few files which are a good start:  iotn104.h, specs-attiny104, crtattiny104.o, libattiny104.a.  I've dropped those into the appropriate directories in the 3.5.4 toolchain directory hierarchy, but obviously that's not enough.

 

The build proceeds until the assembly phase, when there are errors with respect to supported instructions.  The atpack defines the 'core' for the t104 to be AVR8L_0, which appears to be unknown to 3.5.4.  I'm uncertain if this can be resolved easily.

 

In addition, of course, the AVR Libc libraries have no knowledge of the t104, so things like avr/power.h and avr/wdt.h aren't much help.

 

I presume that AS7 ships with a much more recent version of the toolchain, but that seems to be unavailable as a separate download for Windows, and not at all for Linux.

 

Is there a one-stop-shopping experience for the t104 under Linux?  Or have I missed something else simple that will get 3.5.4 up and running with the t104?  Or maybe I've missed an existing thread on the subject?

 

Many thanks.

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:

Or have I missed something else simple that will get 3.5.4 up and running with the t104?  Or maybe I've missed an existing thread on the subject?

 

AS7 on Windows, so yes you have missed many an existing thread on the subject! cheeky

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AS7 on Windows, so yes you have missed many an existing thread on the subject!

I haven't missed them, they just haven't been helpful, since I'm using Linux (thought the thread title gave it away ;-)

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:

I haven't missed them, they just haven't been helpful, since I'm using Linux (thought the thread title gave it away ;-)

 

You did ask for a simple solution!  How could you miss the sarcastic humor implied.  I am trying to find a solution for you though, more eyes, Bing Fu, and the fact that I also have to use Linux for some projects.  In the end the joint effort supports the needs of the many. 

 

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

Last Edited: Sun. Dec 10, 2017 - 05:11 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How could you miss the sarcastic humor implied.

I didn't.  Hence my own smilie.  Here's another :)

 

I am trying to find a solution for you though, more eyes, Bing Fu, and the fact that I also have to use Linux for some projects.  In the end the joint effort supports the needs of the many. 

Gratitude.

 

I will resume my own search when I again become conscious.

 

 

 

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are on Linux, so just build that tools :-)

 

The specs stuff is supported since v5

 

http://gcc.gnu.org/gcc-5/changes...

 

so you'll have to build it anyway if you want that feature.  Same vor -mmcu=avrtiny, which was added in v5. The tiny support had some inconveniences, so you may want to use a recent version like v7.

 

Since the introduction of the specs hack Atmel stopped adding device support to mainline, so you will need that specs hack even with the most recent version of the tools.

 

Moreover, newer versions have -mabsdata and attribute absdata, and new binutils have .rodata in flash.

 

avrfreaks does not support Opera. Profile inactive.

Last Edited: Sun. Dec 10, 2017 - 11:18 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Joey!

 

If you take the route of building yourself, then will you summarize what you've learned and share? Please?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
I found the atpack which includes support for the t104, but I'm not sure how, or even if, I can integrate that into the 3.5.4 toolchain.
Could build 3.6.1

http://distribute.atmel.no/tools/opensource/Atmel-AVR-GNU-Toolchain/3.6.1/avr8-gnu-toolchain-readme.pdf (DFPs are mentioned on page 8)

http://distribute.atmel.no/tools/opensource/Atmel-AVR-GNU-Toolchain/3.6.1/

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The specs stuff is supported since v5

The 'specs stuff' appears to be supported in 4.9.2 as well:

$ apt-show-versions | grep gcc-avr
gcc-avr:amd64/xenial 1:4.9.2+Atmel3.5.0-1 uptodate
gcc-avr:i386 not installed
$ /usr/bin/avr-gcc --version
avr-gcc (GCC) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ locate specs | grep -i tiny
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny10
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny11
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny12
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny13
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny13a
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny15
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny1634
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny167
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny20
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny22
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny2313
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny2313a
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny24
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny24a
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny25
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny26
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny261
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny261a
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny28
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny4
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny40
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny4313
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny43u
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny44
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny441
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny44a
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny45
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny461
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny461a
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny48
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny5
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny828
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny84
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny841
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny84a
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny85
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny861
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny861a
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny87
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny88
/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny9
/usr/lib/gcc/avr/4.9.2/device-specs/specs-avrtiny

... which is why I was able to proceed as far as I did.  Note that it appears to be supported in 4.9.2 in the Ubuntu repositories for 16.04LTS, not just in the 4.9.2 from the Atmel toolchain 3.5.4.

 

Same vor -mmcu=avrtiny, which was added in v5.

And yet there it is above (last in the list), and below:

$ /usr/bin/avr-gcc -mmcu=attiny104
avr-gcc: error: cannot access device-specs for ‘attiny104’ expected at
‘/usr/lib/gcc/avr/4.9.2/device-specs/specs-attiny104’
avr-gcc: note: devices natively supported: ata5272 ata5505 ata5702m322 ata5782
ata5790 ata5790n ata5791 ata5795 ata5831 ata6285 ata6286 ata6289 ata6612c
ata6613c ata6614q ata6616c ata6617c ata664251 ata8210 ata 8510 atmega103
atmega128 atmega128a atmega128rfa1 atmega128rfr2 atmega1280 atmega1281
atmega1284 atmega1284p atmega1284rfr2 atmega16 atmega16a atmega16hva
atmega16hva2 atmega16hvb atmega16hvbrevb atmega16m1 atm ega16u2 atmega16u4
atmega161 atmega162 atmega163 atmega164a atmega164p atmega164pa atmega165
atmega165a atmega165p atmega165pa atmega168 atmega168a atmega168p atmega168pa
atmega168pb atmega169 atmega169a atmega 169p atmega169pa atmega256rfr2
atmega2560 atmega2561 atmega2564rfr2 atmega32 atmega32a atmega32c1 atmega32hvb
atmega32hvbrevb atmega32m1 atmega32u2 atmega32u4 atmega32u6 atmega323
atmega324a atmega324p atmega32 4pa atmega325 atmega325a atmega325p atmega325pa
atmega3250 atmega3250a atmega3250p atmega3250pa atmega328 atmega328p atmega329
atmega329a atmega329p atmega329pa atmega3290 atmega3290a atmega3290p
atmega3290pa a tmega406 atmega48 atmega48a atmega48p atmega48pa atmega48pb
atmega64 atmega64a atmega64c1 atmega64hve atmega64hve2 atmega64m1 atmega64rfr2
atmega640 atmega644 atmega644a atmega644p atmega644pa atmega644rfr2 atm ega645
atmega645a atmega645p atmega6450 atmega6450a atmega6450p atmega649 atmega649a
atmega649p atmega6490 atmega6490a atmega6490p atmega8 atmega8a atmega8hva
atmega8u2 atmega8515 atmega8535 atmega88 atmega88a atmega88p atmega88pa
atmega88pb attiny10 attiny11 attiny12 attiny13 attiny13a attiny15 attiny1634
attiny167 attiny20 attiny22 attiny2313 attiny2313a attiny24 attiny24a attiny25
attiny26 attiny261 attiny261a att iny28 attiny4 attiny40 attiny43u attiny4313
attiny44 attiny44a attiny441 attiny45 attiny461 attiny461a attiny48 attiny5
attiny828 attiny84 attiny84a attiny841 attiny85 attiny861 attiny861a attiny87
attiny88 att iny9 atxmega128a1 atxmega128a1u atxmega128a3 atxmega128a3u
atxmega128a4u atxmega128b1 atxmega128b3 atxmega128c3 atxmega128d3 atxmega128d4
atxmega16a4 atxmega16a4u atxmega16c4 atxmega16d4 atxmega16e5 atxmega192a
3 atxmega192a3u atxmega192c3 atxmega192d3 atxmega256a3 atxmega256a3b
atxmega256a3bu atxmega256a3u atxmega256c3 atxmega256d3 atxmega32a4 atxmega32a4u
atxmega32c3 atxmega32c4 atxmega32d3 atxmega32d4 atxmega32e5 a txmega384c3
atxmega384d3 atxmega64a1 atxmega64a1u atxmega64a3 atxmega64a3u atxmega64a4u
atxmega64b1 atxmega64b3 atxmega64c3 atxmega64d3 atxmega64d4 atxmega8e5
at43usb320 at43usb355 at76c711 at86rf401 at90can128 at90can32 at90can64
at90c8534 at90pwm1 at90pwm161 at90pwm2 at90pwm2b at90pwm216 at90pwm3 at90pwm3b
at90pwm316 at90pwm81 at90scr100 at90s1200 at90s2313 at90s2323 at90s2333
at90s2343 at90s4414 at90s4433 at90s443 4 at90s8515 at90s8535 at90usb1286
at90usb1287 at90usb162 at90usb646 at90usb647 at90usb82 at94k m3000
avr-gcc: note: supported core architectures: avr2 avr25 avr3 avr31 avr35 avr4
avr5 avr51 avr6 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny avr1
avr-gcc: note: you can provide your own specs files, see
<http://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html> for details
avr-gcc: fatal error: no input files
compilation terminated.

 

Since the introduction of the specs hack Atmel stopped adding device support to mainline, so you will need that specs hack even with the most recent version of the tools.

I'm not sure I understand.  Are you saying that Atmel are no longer publishing their own builds?  Isn't that contrary to the licence?

 

EDIT:  Fixed horrible formatting in code blocks.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sun. Dec 10, 2017 - 03:54 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wrote:

Since the introduction of the specs hack Atmel stopped adding device support to mainline, so you will need that specs hack even with the most recent version of the tools.

I'm not sure I understand.  Are you saying that Atmel are no longer publishing their own builds?  Isn't that contrary to the licence?

 

I see:

Could build 3.6.1

 

http://distribute.atmel.no/tools/opensource/Atmel-AVR-GNU-Toolchain/3.6.1/avr8-gnu-toolchain-readme.pdf (DFPs are mentioned on page 8)

http://distribute.atmel.no/tools/opensource/Atmel-AVR-GNU-Toolchain/3.6.1/

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:

 

The specs stuff is supported since v5

 

The 'specs stuff' appears to be supported in 4.9.2 as well:

 

I referred to FSF mainline, and the release notes I linked are the official GCC release notes.  Sorry for the confusion.

 

For the Atmochip branch-fork-distribution you'll have to study the respective release notes; I don't know anything about it and don't use it.

 

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I referred to FSF mainline, and the release notes I linked are the official GCC release notes.  Sorry for the confusion.

I presume that the Ubuntu repo draws from the FSF mainline, not the Atmel toolchain, but I may be incorrect.  Nevertheless, it appears that the repo version supports it, as does the 3.5.4 toolchain, but I don't know how to fully integrate the DFP into it.

 

The Ubuntu 17.10 repo appears to have the 3.6.1 toolchain, but so far I've been unable to get it to even find its own avr/io.h, with or without the DFP! :(

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you take the route of building yourself, then will you summarize what you've learned and share? Please?

Will do.  I'm hoping I'll have luck with a pre-built package from a repo, though.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Joey (sorry my bad english)

 

It is run in Mint 18.1 (same as Ubuntu), gcc-compiler run, but i have not testet with the mcu.

 

Download the Attiny DFP http://packs.download.atmel.com/

 

copie (package to hdd)

 

from gcc/dev/attiny104/device-specs/specs-attiny104     >>>    /usr/lib/gcc/avr/4.9.2/device-specs/

from gcc/dev/attiny104/avrtiny/crtattiny104.o        >>>          /usr/lib/avr/lib/avrtiny

from gcc/dev/attiny104/avrtiny/libattiny104.a         >>>        /usr/lib/avr/lib/avrtiny

from include/avr/iotn104.h  >>>    /usr/lib/avr/include/avr/ 

 

same can you du with the attiny102....

 

have you other folder in ubuntu, search the file as attiny10.xxx

 

good luck ;)

 

EDIT:

 

I have another idea for Assembly with wine, it is running good :) 

(avra make the "PRAGMA-problem" is dont know what this is)

 

Copy in a folder:

 

avrasm2.exe   (download from google)

tn104def.inc   (from the package)

demo.asm      (your code)

 

open a terminal in this folder and type:     wine avrasm2.exe -fI demo.asm

 

EDIT2:

https://lists.nongnu.org/archive...

ATTINY102/104 in Avrdude (modified the avrdude.conf )

 

 

 

 

 

Last Edited: Sun. Dec 10, 2017 - 07:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Holle_L wrote:
I have another idea for Assembly with wine, it is running good :)
or

Gerd's AVR Assembler

http://www.avr-asm-tutorial.net/gavrasm/index_en.html

...

 

Features

View the ReadMe.Txt for more informations on features. ...

 

...

http://www.avr-asm-tutorial.net/gavrasm/v37/ReadMe.Txt

...

 

g) Supported AVR-types:

...

* ATtiny: ..., 102, 104, ...

...

 

Januar 2017: Version 3.6
- Added: Support for ATtiny80 und 840 (datasheet not yet available),
  ATtiny102, 104, 417, 814, 816 und 817, def.inc as of Studio version
  7.0-1188

...

 

P.S.

Don't wait for tiny214 wink

http://new.microchipdirect.com/product/search/all/attiny214

http://new.microchipdirect.com/product/search/all/attiny104

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks @Holle_L, but I'm aware of all of that.  I already have the DFP, and the same repo-fetched version of avr which you're using.  I'd tried to use them in the recommended way:

How to use Atmel DFPs with Stanadalone toolchain?

# Download DFP from here (e.g. Atmel.ATmega_DFP.1.0.86.atpack)

# Unzip .atpack to packs directory (/home/packs/)

# Invoke avr-gcc with additional option -B to tell gcc where to look for device specific information

e.g. avr-gcc -mmcu=atmega328pb -B /home/packs/Atmel.ATmega_DFP.1.0.86/gcc/dev/atmega328pb/

... which is of course better than copying them to /usr/lib by hand.  That will likely break as soon as the repo offers an update to the package.

 

Neither am I interested in having to use wine, and as I'm porting AVR GCC code, avra/avrasm2 won't be necessary or helpful.

 

Turns out the issue was a layer 8 problem.  I was trying all of this on Ubuntu Mate 17.10 in a VM, and I'd only installed gcc-avr.  I'd forgotten to the rest of the toolchain (avr-libc, binutils-avr, etc).  I'm so used to getting it all in one tarball from Atmel, I guess.  Silly me.  Took me a little while to absorb the implication of "<avr/io.h> not found".

 

In addition to using -B to point the compiler to the directory containing the crt*.o, lib*.a, and specs* device-specific files, -I must be used to point to the include directory in the DFP, or attiny104.h won't be found by io.h.

 

With those installed, all seems to be well.

 

Thanks for everyone's help.

 

I'd still love to see an up-to-date, prebuilt, Micromel-provided toolchain that can be deployed on any Linux system, like they used to do right up to 3.5.4.  The current toolchain seems to be 3.6.1 (thank you @gchapman), but I cannot find an official build of it (as a tarball) anywhere (Anyone from Microchip reading this?)

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, that was short-lived.  Same issue I had when trying to integrate the DFP into 3.5.4:

foo.elf.ltrans0.s: Assembler messages:
foo.elf.ltrans0.s:259: Error: illegal opcode elpm for mcu avrtiny
foo.elf.ltrans0.s:260: Error: register name or number from 16 to 31 required
foo.elf.ltrans0.s:261: Error: illegal opcode sbiw for mcu avrtiny
foo.elf.ltrans0.s:262: Error: illegal opcode elpm for mcu avrtiny
foo.elf.ltrans0.s:263: Error: register name or number from 16 to 31 required
foo.elf.ltrans0.s:424: Error: illegal opcode elpm for mcu avrtiny
foo.elf.ltrans0.s:425: Error: register name or number from 16 to 31 required
foo.elf.ltrans0.s:525: Error: illegal opcode elpm for mcu avrtiny
foo.elf.ltrans0.s:526: Error: register name or number from 16 to 31 required

Lines 260 and 261 from foo.s:

        .ascii  "\337\3457;\202.\361\305\237'\263|\361\272\016\303\3669\356\256"
        .ascii  "\316yo*\377\254\347N]iI]9r\320\227\216v}\206\314\222\243\223"

What the...  What the heck kind of encoding is that for a .s file?  And how do I get a human-readable ASCII .s?

 

In any event, the error messages appear to be identical to those I saw when I shoehorned the DFP into 3.5.4.  These are the relevant lines from the .s when building with 3.5.4:

	lpm
	mov r20,r0
	lpm
	mov r22,r0
	adiw r30,1
	lpm
	mov r23,r0
	lpm
	mov r22,r0

 

So

  • r0 is used, despite the fact that the t104 only has r16-r31.
  • Curiously, the 'elpm' errors are for lpm instructions
  • it doesn't like sbiw either

 

The t104 does support lpm and sbiw, but the toolchain doesn't think so.

 

What am I missing?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sun. Dec 10, 2017 - 10:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
What the heck kind of encoding is that for a .s file?
.s is a "private conversation" between the compiler and the assembler - no one said it had to be "human readable"! Another example in this post:

 

https://www.avrfreaks.net/comment...

 

uint8_t data[] __attribute__ ((section (".progmem"))) = { 13, 23, 56, 91, 104, 156, 202 };

becomes:

data:
        .byte   13
        .byte   23
        .byte   56
        .byte   91
        .byte   104
        .byte   -100
        .byte   -54

which always invokes a bit of a "WTF" from me! We all know what's going on here but if it had use hex (or even octal) constants here it might be more consistent/easier to read. But then again the compiler and the assembler both know what's trying to be achieved here.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:

foo.elf.ltrans0.s: Assembler messages:

foo.elf.ltrans0.s:259: Error: illegal opcode elpm for mcu avrtiny
foo.elf.ltrans0.s:260: Error: register name or number from 16 to 31 required
...

Dump all __flash and PROGMEM stuff and use open-coded C / C++.  The old toolchains won't complain properly, and I'd recomment you use gcc v7.2  + binutils 2.29+.

As a test, when you compile code like the following

__attribute((externally_visible))
const int a = 1;
const int * volatile p;

int main()
{
    p = &a;
    return *p;
}

The map file should look something like this:

.rodata         0x000000000000404a        0x2 load address 0x000000000000004a
 *(.rodata)
 .rodata        0x000000000000404a        0x2 memc.elf.ltrans0.ltrans.o
                0x000000000000404a                a

i.e. "a" is located after 0x4000.  This means .rodata lives in flash and you can drop progmem and similar hacks without any overhead.  And the disassembly should read like

0000004c <main>:
  4c:   42 e6           ldi     r20, 0x62       ; 98
  4e:   50 e4           ldi     r21, 0x40       ; 64
  50:   51 a9           sts     0x41, r21       ; 0x800041 <__data_end+0x1>
  52:   40 a9           sts     0x40, r20       ; 0x800040 <__data_end>
  54:   e0 a1           lds     r30, 0x40       ; 0x800040 <__data_end>
  56:   f1 a1           lds     r31, 0x41       ; 0x800041 <__data_end+0x1>
  58:   81 91           ld      r24, Z+
  5a:   90 81           ld      r25, Z
  5c:   08 95           ret

i.e. "a" lives after 0x4000 and "p" is accessed by LDS / STS.

Quote:

        .ascii  "\337\3457;\202.\361\305\237'\263|\361\272\016\303\3669\356\256"
        .ascii  "\316yo*\377\254\347N]iI]9r\320\227\216v}\206\314\222\243\223"

What the...  What the heck kind of encoding is that for a .s file?  And how do I get a human-readable ASCII .s?

Looks like byte code (lto).

avrfreaks does not support Opera. Profile inactive.

Last Edited: Mon. Dec 11, 2017 - 10:56 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
With those installed, all seems to be well.

I know that I'll be roundly lambasted for the below; go for it if you must.

 

Sometimes engineers and similar curious people go to great lengths exploring stuff that "can't be done".  For example, some might spend many many hours setting up some kind of practical joke.  Or making a mold of one's head in a microwave oven.  I often like to use automobile analogies to try to demonstrate my point.  In this case,  "I have Chevy cars and won't change.  The Chevy wheels are functional and readily available, but I "need" to use Ford wheels because [insert reason here].  All sorts of problems are being encountered, from physical fit to interface with onboard systems.  Please help."

 

In this case, a Tiny104 family member has

Non-volatile Program and Data Memories
1024 Bytes of In-system Programmable Flash Program Memory
 

500 instructions max.  One could have put the code into a hex editor in machine language in the time it took to just pose this question.  Obviously extreme, but on the list?

 

-- Write machine code with hex editor

-- Use just about any AVR assembler on any platform.  If there are a couple new op codes, then "patch" with hex sequences.

-- Use any toochain with support for the model on your platform of choice.

-- Use any toochain with support for the model on the platform that it works on.

-- Bite the bullet and use the supported platform, or have someone else do the build for you.

 

I realize that the last few might upset your sensibilities.  It depends on your aim.  If your aim is to get the app working on the new target -- there are several ways.  If your aim is to get your chosen dev platform and toolchain and version to build an app for that target mode, regardless of how much time and effort is used for the possible 500 instructions:  You are well on your way, reviewing the above.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Apart from the max of 500 instructions, there is the limit of 32 bytes of RAM.  Hence, one of the first questione we can expect, is <<How do I get rid of "rcall main"?>>

 

And the next one probably: <<.vectors is consuming sooo much space, how can I start code /immediately/ after the last used vect entry?>>

 

Some like <<ISRs are pushing so much regs not actually needed to be pushed, how can I avoid this?>> are solved by gcc v8, but you may be better off with asm for that app.

 

IMO, such an app is basically a prove-of-concept for <<avrtiny+avr-gcc work in principle>>, I finally managed the project without the tools exploding my silicon...

 

But maybe avr-gcc just works out better then we are expecting.  Who knows..? avrtiny+avr-gcc has quite little coverage.

 

avrfreaks does not support Opera. Profile inactive.

Last Edited: Mon. Dec 11, 2017 - 03:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looks like byte code (lto).

Yeah, it went away when I dropped LTO.

 

Dump all __flash and PROGMEM stuff and use open-coded C / C++.

I'd had a hunch about that, too.

 

I dropped down to a simple blinky test, and it builds fine:

$ cat blink104.c
#include <avr/io.h>
#include <util/delay.h>

#define FLASH_RATE 0.5

int __attribute__ ((__OS_main__)) main(void) {

  DDRA = 0;
  DDRA = 0xFF;

  while(1) {
    PORTA = 0xFF;
    _delay_ms(500.0 / FLASH_RATE);
  }   

}
$ avr-gcc -DF_CPU=1000000UL -Os -mmcu=attiny104 -g -Wall -save-temps blink104.c -o blink104.elf
$ avr-objdump -S blink104.elf

blink104.elf:     file format elf32-avr

Disassembly of section .text:

00000000 <__vectors>:
   0:	0f c0       	rjmp	.+30     	; 0x20 <__ctors_end>
   2:	16 c0       	rjmp	.+44     	; 0x30 <__bad_interrupt>
   4:	15 c0       	rjmp	.+42     	; 0x30 <__bad_interrupt>
   6:	14 c0       	rjmp	.+40     	; 0x30 <__bad_interrupt>
   8:	13 c0       	rjmp	.+38     	; 0x30 <__bad_interrupt>
   a:	12 c0       	rjmp	.+36     	; 0x30 <__bad_interrupt>
   c:	11 c0       	rjmp	.+34     	; 0x30 <__bad_interrupt>
   e:	10 c0       	rjmp	.+32     	; 0x30 <__bad_interrupt>
  10:	0f c0       	rjmp	.+30     	; 0x30 <__bad_interrupt>
  12:	0e c0       	rjmp	.+28     	; 0x30 <__bad_interrupt>
  14:	0d c0       	rjmp	.+26     	; 0x30 <__bad_interrupt>
  16:	0c c0       	rjmp	.+24     	; 0x30 <__bad_interrupt>
  18:	0b c0       	rjmp	.+22     	; 0x30 <__bad_interrupt>
  1a:	0a c0       	rjmp	.+20     	; 0x30 <__bad_interrupt>
  1c:	09 c0       	rjmp	.+18     	; 0x30 <__bad_interrupt>
  1e:	08 c0       	rjmp	.+16     	; 0x30 <__bad_interrupt>

00000020 <__ctors_end>:
  20:	11 27       	eor	r17, r17
  22:	1f bf       	out	0x3f, r17	; 63
  24:	cf e5       	ldi	r28, 0x5F	; 95
  26:	d0 e0       	ldi	r29, 0x00	; 0
  28:	de bf       	out	0x3e, r29	; 62
  2a:	cd bf       	out	0x3d, r28	; 61
  2c:	02 d0       	rcall	.+4      	; 0x32 <main>
  2e:	0f c0       	rjmp	.+30     	; 0x4e <_exit>

00000030 <__bad_interrupt>:
  30:	e7 cf       	rjmp	.-50     	; 0x0 <__vectors>

00000032 <main>:

#define FLASH_RATE 0.5

int __attribute__ ((__OS_main__)) main(void) {

  DDRA = 0;
  32:	11 b9       	out	0x01, r17	; 1
  DDRA = 0xFF;
  34:	4f ef       	ldi	r20, 0xFF	; 255
  36:	41 b9       	out	0x01, r20	; 1

  while(1) {
    PORTA = 0xFF;
  38:	42 b9       	out	0x02, r20	; 2
	#else
		//round up by default
		__ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
	#endif

	__builtin_avr_delay_cycles(__ticks_dc);
  3a:	5f e3       	ldi	r21, 0x3F	; 63
  3c:	6d e0       	ldi	r22, 0x0D	; 13
  3e:	73 e0       	ldi	r23, 0x03	; 3
  40:	51 50       	subi	r21, 0x01	; 1
  42:	60 40       	sbci	r22, 0x00	; 0
  44:	70 40       	sbci	r23, 0x00	; 0
  46:	e1 f7       	brne	.-8      	; 0x40 <__SREG__+0x1>
  48:	00 c0       	rjmp	.+0      	; 0x4a <__SREG__+0xb>
  4a:	00 00       	nop
  4c:	f5 cf       	rjmp	.-22     	; 0x38 <main+0x6>

0000004e <_exit>:
  4e:	f8 94       	cli

00000050 <__stop_program>:
  50:	ff cf       	rjmp	.-2      	; 0x50 <__stop_program>

Note that I included the line DDRA = 0 to show that the compiler correctly uses r17 for __zero_reg__.

 

Now if I try to use __flash:

$ cat blink104.c
#include <avr/io.h>
#include <util/delay.h>

#define FLASH_RATE 0.5

int __attribute__ ((__OS_main__)) main(void) {

  static const __flash uint8_t foo[] = {
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
  };

  uint8_t bar;

  DDRA = 0;
  DDRA = 0xFF;

  while(1) {
    for (bar=0; bar<sizeof(foo); bar++) {
      PORTA = foo[bar];
      _delay_ms(500.0 / FLASH_RATE);
    }
  }   

}
$ avr-gcc -DF_CPU=1000000UL -Os -mmcu=attiny104 -g -Wall -save-temps blink104.c -o blink104.elf
blink104.s: Assembler messages:
blink104.s:39: Error: illegal opcode elpm for mcu avrtiny
blink104.s:40: Error: register name or number from 16 to 31 required
blink104.s:41: Error: illegal opcode sbiw for mcu avrtiny

And looking at the .s:

$ head -n 46 blink104.s
	.file	"blink104.c"
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__SREG__ = 0x3f
__CCP__ = 0x3c
__tmp_reg__ = 16
__zero_reg__ = 17
	.text
.Ltext0:
	.cfi_sections	.debug_frame
	.section	.text.startup,"ax",@progbits
.global	main
	.type	main, @function
main:
.LFB6:
	.file 1 "blink104.c"
	.loc 1 6 0
	.cfi_startproc
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0
	.loc 1 14 0
	out 0x1,__zero_reg__
	.loc 1 15 0
	ldi r20,lo8(-1)
	out 0x1,r20
	ldi r20,lo8(foo.1641)
	ldi r21,hi8(foo.1641)
	subi r20,lo8(-(8))
.L3:
.LVL0:
	.loc 1 6 0
	ldi r30,lo8(foo.1641)
	ldi r31,hi8(foo.1641)
.LVL1:
.L2:
	.loc 1 19 0 discriminator 3
	lpm
	mov r21,r0
	adiw r30,1
.LVL2:
	out 0x2,r21
.LVL3:
.LBB4:
.LBB5:

So something about using __flash assumes a full complement of GP registers.  I suppose that whichever part of avr-gcc generates the code for __flash ignores core restrictions like the number of GP registers...?

 

However, the curious thing is that lpm and sbiw trigger errors.

 

Huh?  When I look at the instruction set summary in the ATtiny102/104 datasheet, SBIW is there:

LPM is there too.

 

Hang on... >>everything<< is there.  There are 128 instructions in the instruction set summary.  That certainly doesn't jibe with:

... even if we account for folding some instructions together.  For example, the t25/45/85 datasheet claims 120 instrucitons, and shows 123 instructions in the summary.

 

Then I stumbled across this:

https://www.avrfreaks.net/comment/2210746#comment-2210746

... where Lee posted a screenshot of the datasheet:

 

No SBIW (or ADIW) in sight.

 

Lee:  what version of the datasheet was that, and where did you get it?

 

Some other inconsistencies:

  • the break instruction shows up in the datasheet, but the t104 doesn't support debugging.
  • the Microchip product page for the t104 has links to appnotes for EEPROM, but the t104 has no EEPROM

 

I'm forced to wonder if the t104 actually has lpm.  Since it apparently can self-program flash, surely it can also read flash for verification purposes?

 

However, I also see that all NVM memories are mapped to data address space, with flash at 0x4000, so perhaps there is no lpm after all, and this is the only way to access flash?:

 

(NOTE: This would also appear to be one of the new tinies which does not map GP registers into the the data address space.)

 

This map is consistent with what @SprintSB has said:

The old toolchains won't complain properly, and I'd recomment you use gcc v7.2  + binutils 2.29+.

As a test, when you compile code like the following

__attribute((externally_visible))
const int a = 1;
const int * volatile p;

int main()
{
    p = &a;
    return *p;
}

The map file should look something like this:

.rodata         0x000000000000404a        0x2 load address 0x000000000000004a
 *(.rodata)
 .rodata        0x000000000000404a        0x2 memc.elf.ltrans0.ltrans.o
                0x000000000000404a                a

i.e. "a" is located after 0x4000.  This means .rodata lives in flash and you can drop progmem and similar hacks without any overhead.

Am I to conclude that the use of const is enough to place data into flash?  Or is:

__attribute((externally_visible))

... also required?

 

It would appear that neither of these is sufficient, at least prior to gcc v7.2.  Note that the code examples I used above were built with 3.5.4 (4.9.2).  I tried moving the declaration of foo[] out of main():

__attribute((externally_visible))
const uint8_t foo[] = {
  0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
};

... but building shows that it stays in SRAM:

0000002c <__do_copy_data>:
  2c:	20 e0       	ldi	r18, 0x00	; 0
  2e:	a0 e4       	ldi	r26, 0x40	; 64
  30:	b0 e0       	ldi	r27, 0x00	; 0
  32:	e6 e7       	ldi	r30, 0x76	; 118
  34:	f0 e4       	ldi	r31, 0x40	; 64
  36:	02 c0       	rjmp	.+4      	; 0x3c <__CCP__>
  38:	31 91       	ld	r19, Z+
  3a:	3d 93       	st	X+, r19
  3c:	a8 34       	cpi	r26, 0x48	; 72
  3e:	b2 07       	cpc	r27, r18
  40:	d9 f7       	brne	.-10     	; 0x38 <__do_copy_data+0xc>
  42:	02 d0       	rcall	.+4      	; 0x48 <main>
  44:	16 c0       	rjmp	.+44     	; 0x72 <_exit>
    for (bar=0; bar<sizeof(foo); bar++) {
      PORTA = foo[bar];
  52:	41 91       	ld	r20, Z+
  54:	42 b9       	out	0x02, r20	; 2

I get the same result with 3.6.1 (5.4.0).

 

I'd recomment you use gcc v7.2  + binutils 2.29+.

What version of the toolchain (and each component) ships with AS7?  Has that version been built for Linux by Atmel/Microchip?  I suppose not, but maybe the source is available somewhere?  Or I guess I'll likely have to 'round and gather all the pieces myself and muddle through a build.

 

Can anyone who has AS7 try out some of the code in this post and report back here?

 

EDIT:  corrected incorrect screenshot from Lee's post

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Mon. Dec 11, 2017 - 03:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SprinterSB wrote:
But maybe avr-gcc just works out better then we are expecting.  Who knows..? avrtiny+avr-gcc has quite little coverage.

Microchip Technology Inc

Microchip

ATtiny104

http://www.microchip.com/wwwproducts/en/ATtiny104

(expand Documentation)

AT12489: Getting Started with Atmel ATtiny102 and ATtiny104

(open PDF, go to 2. Creating an Example Application in Atmel Studio, C code for a button and LED blinky)

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Joey,

 

I think you can revert to the old PROGMEM/pgm_read_byte() instead of using __flash, as a work around.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
I'm forced to wonder if the t104 actually has lpm.
Yes for all unified memory AVR.

http://ww1.microchip.com/downloads/en/AppNotes/Atmel-42789-Writing-to-Flash-on-the-New-tinyAVR-Platform-Using-Assembly_ApplicationNote_AVR42789.pdf

joeymorin wrote:
Since it apparently can self-program flash, surely it can also read flash for verification purposes?
Yes though the tiny104 bootloader does not verify.

http://ww1.microchip.com/downloads/en/AppNotes/Atmel-42736-ATtiny104-Low-Footprint-Bootloader_AT12498_ApplicationNote.pdf

 


http://www.microchip.com/wwwproducts/en/ATtiny104

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In general I have to say the quality of the datasheet for the t104 is quite low.  I've found a growing list of errors, including a reference to MCUCR, which doesn't exist in that device, for the PUD bit, which doesn't exist in that device.  There are other lies, like "If PORTxn is written to '1' when the pin is configured as an input pin, the pull-up resistor is activated."

 

In reality, pull-ups are handled via a new set of registers, PUEx.

 

Even the code example reference by @gchapman above gets this wrong:

int main(void) {
  /* enable the pull-up function */
  PUEB |= 1<<PORTB1;

  /* enable pull-up for button */
  PORTB |= 1<<PORTB1;

  /* configure LED pin as output */
  DDRA |= 1<<DDRA5;
  while(1) {
    /* check the button status (press - 0 , release - 1 ) */
    if(!(PINB & (1<<PINB1))) {
      /*switch on the LED until button is pressed */
      PORTA &= ~(1<<PORTA5);
    }
    else {
      /* switch off the LED if button is released*/
      PORTA |= 1<<PORTA5;
    }
  }
}

... even though they got it right in the previous line!

 

The explanation following the code example in the PDF is also full of errors:

7. Code explanation:
– The application uses the mechanical button and yellow LED of ATtiny104 Xplained Nano kit. They are connected to Port Pin PB1 and PA5, respectively.
– Each PORT has three registers; DDRx, PORTx, and PINx.
– The DDRx register is used to configure the port pin direction.
  • 1 - Output
  • 0 - Input
– The kit does not have pull-up resisters onboard and hence internal pull-up has to be enabled for the button.
– Configure the PUEx register to enable internal pull-up of the corresponding port pin.
When a pin is configured as input and the respective bit in PORTx is written logic one, the respective pin is internally pulled up.
– The PINx register is used to return the logic level available on the port pin.
– The button connected to pin PB1 is configured as input with pull-up enabled. LED connected to Pin PA5 is configured as output.
– The LED is controlled based on the button status. When the button is not pressed the LED will not glow. When pressing the button the LED will glow.

 

 

Micromel have got to get their act together and hire some real technical writers, instead of copy-paste-happy college interns who have done the work in the past.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
However, I also see that all NVM memories are mapped to data address space, with flash at 0x4000, so perhaps there is no lpm after all, and this is the only way to access flash?:
Via the NVM controller (NVMCTRL) for access to flash for all unified memory AVR.

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

snigelen wrote:

Hi Joey,

 

I think you can revert to the old PROGMEM/pgm_read_byte() instead of using __flash, as a work around.

 

No, please.  Don't recommend such stuff!

 

It even depends on the toolchain version on how it works an on the linker script.

 

Just drop progmem!

 

If not, read the gcc documentation on it. It differs and is not the same as with classic avrs!

 

avrfreaks does not support Opera. Profile inactive.

Last Edited: Mon. Dec 11, 2017 - 04:29 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you can revert to the old PROGMEM/pgm_read_byte() instead of using __flash, as a work around.

@sniglen!  You 'ol pole cat, you. .. You 'ol so-n-so...  Why didn't I think of that?  Actually, I did, and rejected it out of hand.  Thanks for putting me back on track.

 

$ cat blink104.c
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>

#define FLASH_RATE 0.5

int __attribute__ ((__OS_main__)) main(void) {

  static const uint8_t foo[] PROGMEM = {
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
  };
  
  uint8_t bar;
  
  DDRA = 0;
  DDRA = 0xFF;

  while(1) {
    for (bar=0; bar<sizeof(foo); bar++) {
      PORTA = pgm_read_byte(&foo[bar]);
      _delay_ms(500.0 / FLASH_RATE);
    }
  }   

}
$ avr-gcc -DF_CPU=1000000UL -Os -mmcu=attiny104 -g -Wall -save-temps blink104.c -o blink104.elf
$ avr-objdump -S blink104.elf

blink104.elf:     file format elf32-avr


Disassembly of section .text:

00000000 <__vectors>:
   0:	13 c0       	rjmp	.+38     	; 0x28 <__ctors_end>
   2:	1a c0       	rjmp	.+52     	; 0x38 <__bad_interrupt>
   4:	19 c0       	rjmp	.+50     	; 0x38 <__bad_interrupt>
   6:	18 c0       	rjmp	.+48     	; 0x38 <__bad_interrupt>
   8:	17 c0       	rjmp	.+46     	; 0x38 <__bad_interrupt>
   a:	16 c0       	rjmp	.+44     	; 0x38 <__bad_interrupt>
   c:	15 c0       	rjmp	.+42     	; 0x38 <__bad_interrupt>
   e:	14 c0       	rjmp	.+40     	; 0x38 <__bad_interrupt>
  10:	13 c0       	rjmp	.+38     	; 0x38 <__bad_interrupt>
  12:	12 c0       	rjmp	.+36     	; 0x38 <__bad_interrupt>
  14:	11 c0       	rjmp	.+34     	; 0x38 <__bad_interrupt>
  16:	10 c0       	rjmp	.+32     	; 0x38 <__bad_interrupt>
  18:	0f c0       	rjmp	.+30     	; 0x38 <__bad_interrupt>
  1a:	0e c0       	rjmp	.+28     	; 0x38 <__bad_interrupt>
  1c:	0d c0       	rjmp	.+26     	; 0x38 <__bad_interrupt>
  1e:	0c c0       	rjmp	.+24     	; 0x38 <__bad_interrupt>

00000020 <__trampolines_end>:
  20:	01 02       	muls	r16, r17
  22:	04 08       	sbc	r0, r4
  24:	10 20       	and	r1, r0
  26:	40 80       	ld	r4, Z

00000028 <__ctors_end>:
  28:	11 27       	eor	r17, r17
  2a:	1f bf       	out	0x3f, r17	; 63
  2c:	cf e5       	ldi	r28, 0x5F	; 95
  2e:	d0 e0       	ldi	r29, 0x00	; 0
  30:	de bf       	out	0x3e, r29	; 62
  32:	cd bf       	out	0x3d, r28	; 61
  34:	02 d0       	rcall	.+4      	; 0x3a <main>
  36:	1b c0       	rjmp	.+54     	; 0x6e <_exit>

00000038 <__bad_interrupt>:
  38:	e3 cf       	rjmp	.-58     	; 0x0 <__vectors>

0000003a <main>:
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
  };
  
  uint8_t bar;
  
  DDRA = 0;
  3a:	11 b9       	out	0x01, r17	; 1
  DDRA = 0xFF;
  3c:	4f ef       	ldi	r20, 0xFF	; 255
  3e:	41 b9       	out	0x01, r20	; 1
#include <avr/pgmspace.h>
#include <util/delay.h>

#define FLASH_RATE 0.5

int __attribute__ ((__OS_main__)) main(void) {
  40:	40 e0       	ldi	r20, 0x00	; 0
  42:	50 e0       	ldi	r21, 0x00	; 0
  44:	e4 2f       	mov	r30, r20
  46:	f5 2f       	mov	r31, r21
  48:	e0 5e       	subi	r30, 0xE0	; 224
  4a:	ff 4b       	sbci	r31, 0xBF	; 191
  DDRA = 0;
  DDRA = 0xFF;

  while(1) {
    for (bar=0; bar<sizeof(foo); bar++) {
      PORTA = pgm_read_byte(&foo[bar]);
  4c:	e0 81       	ld	r30, Z
  4e:	e2 b9       	out	0x02, r30	; 2
	#else
		//round up by default
		__ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
	#endif

	__builtin_avr_delay_cycles(__ticks_dc);
  50:	6f e3       	ldi	r22, 0x3F	; 63
  52:	7d e0       	ldi	r23, 0x0D	; 13
  54:	83 e0       	ldi	r24, 0x03	; 3
  56:	61 50       	subi	r22, 0x01	; 1
  58:	70 40       	sbci	r23, 0x00	; 0
  5a:	80 40       	sbci	r24, 0x00	; 0
  5c:	e1 f7       	brne	.-8      	; 0x56 <__SREG__+0x17>
  5e:	00 c0       	rjmp	.+0      	; 0x60 <__stack+0x1>
  60:	00 00       	nop
  62:	4f 5f       	subi	r20, 0xFF	; 255
  64:	5f 4f       	sbci	r21, 0xFF	; 255
  
  DDRA = 0;
  DDRA = 0xFF;

  while(1) {
    for (bar=0; bar<sizeof(foo); bar++) {
  66:	48 30       	cpi	r20, 0x08	; 8
  68:	51 07       	cpc	r21, r17
  6a:	61 f7       	brne	.-40     	; 0x44 <__SREG__+0x5>
  6c:	e9 cf       	rjmp	.-46     	; 0x40 <__SREG__+0x1>

0000006e <_exit>:
  6e:	f8 94       	cli

00000070 <__stop_program>:
  70:	ff cf       	rjmp	.-2      	; 0x70 <__stop_program>

Hardly optimal, but does the trick it seems.  Mind you, that was with 3.5.4 (4.9.2), but with 3.6.1 (5.4.0) I get exactly the same thing.  Maybe 7.x does a better job?

 

I'm forced to wonder if the t104 actually has lpm.

Yes for all unified memory AVR.

GCC doesn't seem to know this, based on the errors I've seen.  I haven't tried newer than 5.4.0, though, but I'd expect the issue is more to do with the DFP.

 

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you really want progmem, READ THE DOCS (again!)

avrfreaks does not support Opera. Profile inactive.

Last Edited: Mon. Dec 11, 2017 - 07:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, please.  Don't recommend such stuff!

 

It even depends on the toolchain version on how it works an on the linker script.

 

Just drop progmem!

Except, it works.  I'm not a fan per se, but the other option right now seems to be building a bleeding-edge toolchain from source.  Unless Atmel provide a easier option, I'm likely to stick with the simplest solution, at least for now.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
Lee: what version of the datasheet was that, and where did you get it?

Well, I don't know if there are exactly 54 powerful instructions.  The list in my datasheet is much longer than that--but there are e.g. many flavours of LD and others.

 

Dunno where I got it -- I have a lot of AVR datasheets downloaded; this is the only one/only version for this family.  Screenshot:

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SprinterSB wrote:
... and I'd recomment you use gcc v7.2  + binutils 2.29+.
Arch Linux appears to meet that requirement; Ubuntu does not.

Did not search RHEL and Fedora (remainder of the Linux distributions that Microchip tests on)

 

https://www.archlinux.org/packages/?sort=&q=avr&maintainer=&flagged=

https://packages.ubuntu.com/search?suite=all&section=all&arch=any&keywords=avr&searchon=names

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Having got the blinky to build, I moved on to the original app I had intended to port.  It builds fine with PROGMEM, and the disassembly looks to be correct.  HOWEVER, the code generation is exceedingly inefficient:

 

#define ADC_HIST_SZ 64
.
.
.
static uint8_t moving_avg(uint16_t sample) {

  static uint16_t hst[ADC_HIST_SZ];
  static uint16_t tot;
  static uint8_t  idx;

  tot      = tot + sample - hst[idx];
  hst[idx] = sample;
  idx      = (idx + 1) % ADC_HIST_SZ;

  return tot / (ADC_HIST_SZ * 4);

}

EDIT: Let's put aside for the moment the fact that the t104 has only 32 bytes of SRAM, and that the above #define would call for 128 bytes ;-)

00000150 <moving_avg>:
}

// Compute moving average based on new sample
uint8_t moving_avg(uint16_t sample) {
 150:	3f 93       	push	r19
 152:	cf 93       	push	r28
 154:	df 93       	push	r29

  static uint16_t hst[ADC_HIST_SZ];
  static uint16_t tot;
  static uint8_t  idx;

  tot      = tot + sample - hst[idx];
 156:	c1 e8       	ldi	r28, 0x81	; 129
 158:	d0 e0       	ldi	r29, 0x00	; 0
 15a:	38 81       	ld	r19, Y
 15c:	e3 2f       	mov	r30, r19
 15e:	f0 e0       	ldi	r31, 0x00	; 0
 160:	ee 0f       	add	r30, r30
 162:	ff 1f       	adc	r31, r31
 164:	ef 5b       	subi	r30, 0xBF	; 191
 166:	ff 4f       	sbci	r31, 0xFF	; 255
 168:	40 81       	ld	r20, Z
 16a:	ef 5f       	subi	r30, 0xFF	; 255
 16c:	ff 4f       	sbci	r31, 0xFF	; 255
 16e:	50 81       	ld	r21, Z
 170:	e1 50       	subi	r30, 0x01	; 1
 172:	f0 40       	sbci	r31, 0x00	; 0
 174:	68 2f       	mov	r22, r24
 176:	79 2f       	mov	r23, r25
 178:	64 1b       	sub	r22, r20
 17a:	75 0b       	sbc	r23, r21
 17c:	a2 e8       	ldi	r26, 0x82	; 130
 17e:	b0 e0       	ldi	r27, 0x00	; 0
 180:	4c 91       	ld	r20, X
 182:	af 5f       	subi	r26, 0xFF	; 255
 184:	bf 4f       	sbci	r27, 0xFF	; 255
 186:	5c 91       	ld	r21, X
 188:	a1 50       	subi	r26, 0x01	; 1
 18a:	b0 40       	sbci	r27, 0x00	; 0
 18c:	46 0f       	add	r20, r22
 18e:	57 1f       	adc	r21, r23
 190:	4d 93       	st	X+, r20
 192:	5c 93       	st	X, r21
  hst[idx] = sample;
 194:	81 93       	st	Z+, r24
 196:	90 83       	st	Z, r25
  idx      = (idx + 1) % ADC_HIST_SZ;
 198:	3f 5f       	subi	r19, 0xFF	; 255
 19a:	3f 71       	andi	r19, 0x1F	; 31
 19c:	38 83       	st	Y, r19

  return tot / (ADC_HIST_SZ * 4);
 19e:	84 2f       	mov	r24, r20
 1a0:	95 2f       	mov	r25, r21
 1a2:	88 0f       	add	r24, r24
 1a4:	89 2f       	mov	r24, r25
 1a6:	88 1f       	adc	r24, r24
 1a8:	99 0b       	sbc	r25, r25
 1aa:	91 95       	neg	r25

}
 1ac:	df 91       	pop	r29
 1ae:	cf 91       	pop	r28
 1b0:	3f 91       	pop	r19
 1b2:	08 95       	ret

It gets worse when the function is made static and therefore inlined.

 

I know that the AVR backend has been getting shafted as a result of changes made to benefit ARM and x86, but this is terrible.  It's bad for other AVR as well, but it just hurts so much more on a 1K device.

 

I may have to go with asm, but this is for a 3rd party who will own the source code, and the preference/requirement is that it be in C.  I may have to do some convincing... either of the client, or of the compiler ;-)

 

Some attempts at convincing the compiler by using local copies of static variables helps, but there seems to be an insistence on using indexed addressing for what could be done with lds or sts.  Does the t104 really lack these instructions?  Or is the compiler just that stupid?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Mon. Dec 11, 2017 - 06:29 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dunno where I got it -- I have a lot of AVR datasheets downloaded; this is the only one/only version for this family.  Screenshot:

Ah, that's revision C.  The currently available one is revision D, Atmel-42505D-ATtiny102-ATtiny104_Datasheet_Complete-10/2016.

 

I wonder which instruction summary is correct.  I expect the one in C, since it seems SBIW is not supported.

 

Arch Linux appears to meet that requirement; Ubuntu does not.

Thanks, I'll look into it.

 

 

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did not search RHEL and Fedora (remainder of the Linux distributions that Microchip tests on)

Where did you see that?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
What version of the toolchain (and each component) ships with AS7?
3.6.1

Relative to this thread, corrected in 3.6.1 was

Issue #AVRTC-857:
Improve const data handling for devices that see flash memory in data address space (memory mapped flash)
e.g, tiny40, tiny416 Backport of gcc's PR 78093, 81072 and respective binutils patches

joeymorin wrote:
Has that version been built for Linux by Atmel/Microchip?
Yes on an assumption that each is tested on several Linux distributions per its release notes.

Apparently making a copy of that build visible on Microchip's web site is another effort.

joeymorin wrote:
I suppose not, but maybe the source is available somewhere?
Yes though 3.6.0 is in Debian and Ubuntu.

joeymorin wrote:
Can anyone who has AS7 try out some of the code in this post and report back here?

P.S.

An aid if one wants to join in the fun ... or to commiserate  wink

https://www.avrfreaks.net/forum/microchip-dev-tools-end-year-2017-sale

...

ATtiny104 Xplained Nano

 


http://studio.download.atmel.com/7.0.1645/as-installer-7.0.1645-readme.pdf

(page 3)

Atmel Studio 7.0.1645

...

AVR 8-bit GCC Toolchain 3.6.1

....

 

...

 

Atmel Studio 7.0.1416

...

AVR 8-bit GCC Toolchain 3.6.0 with upstream versions:
– gcc 5.4.0
– Binutils 2.26.20160125
– avr-libc 2.0.0
– gdb 7.8

...

via http://www.microchip.com/avr-support/atmel-studio-7

http://distribute.atmel.no/tools/opensource/Atmel-AVR-GNU-Toolchain/3.6.1/avr8-gnu-toolchain-readme.pdf

(page 5)

2.1 Component Versions
GCC: 5.4.0
binutils: 2.26.20160125
avr-libc: "2.0.0"
gdb

http://distribute.atmel.no/tools/opensource/Atmel-AVR-GNU-Toolchain/3.6.1/

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

http://distribute.atmel.no/tools/opensource/Atmel-AVR-GNU-Toolchain/3.6.1/avr8-gnu-toolchain-readme.pdf

(page 3)

1.1.2 Software Requirements

...

The toolchain should work on the Linux distributions Fedora, RedHat Enterprise, Arch Linux and Ubuntu for both 32-bits and 64-bits architecture. AVR 8-bit GNU Toolchain may very well work on other distributions. However those are untested and unsupported.

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
It's bad for other AVR as well, but it just hurts so much more on a 1K device.
The (only?) alternatives are IAR EWAVR Kickstart and CodeVisionAVR evaluation though these are only on Windows.

joeymorin wrote:
I may have to do some convincing... either of the client, or of the compiler ;-)
laugh

P.S.

joeymorin wrote:
I know that the AVR backend has been getting shafted as a result of changes made to benefit ARM and x86, but this is terrible.
There's an alternate AVR code generator in LLVM.

http://releases.llvm.org/5.0.0/docs/ReleaseNotes.html#changes-to-the-avr-target

 


https://www.iar.com/iar-embedded-workbench/?focus=wbselector#!?device=ATtiny104&architecture=AVR (near page's bottom, expand "Download a free trial!")

CodeVisionAVR Download Current Version

http://hpinfotech.ro/cvavr_download.html

 

Edit: LLVM

 

"Dare to be naïve." - Buckminster Fuller

Last Edited: Mon. Dec 11, 2017 - 06:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

for the following input

#include <stdint.h>

#define ADC_HIST_SZ 16u

uint8_t moving_avg (uint16_t sample)
{

  static uint16_t hst[ADC_HIST_SZ];
  static uint16_t tot;
  static uint8_t  idx;

  tot      = tot + sample - hst[idx];
  hst[idx] = sample;
  idx      = (idx + 1u) % ADC_HIST_SZ;

  return tot / (ADC_HIST_SZ * 4);
}

v7 and v8 give output as below (-mmcu=attiny4 -Os) ATtiny104 would be same.  For v6 and older, I am basically getting code as shown by you.

moving_avg:
	lds r22,idx.1517
	mov r30,r22
	ldi r31,0
	lds r20,tot.1516
	lds r21,tot.1516+1
	add r20,r24
	adc r21,r25
	lsl r30
	rol r31
	subi r30,lo8(-(hst.1515))
	sbci r31,hi8(-(hst.1515))
	ld r26,Z+
	ld r27,Z
	subi r30,lo8((1))
	sbci r31,hi8((1))
	sub r20,r26
	sbc r21,r27
	sts tot.1516+1,r21
	sts tot.1516,r20
	st Z+,r24
	st Z,r25
	subi r22,lo8(-(1))
	andi r22,lo8(15)
	sts idx.1517,r22
	mov r25,r21
	mov r24,r20
	ldi r30,6
1:
	lsr r25
	ror r24
	dec r30
	brne 1b
	ret

There are at least 2 superfluous instructions, and that function consumes already 66% of RAM.  Some unrelated notes:

 

* ad progmem: After 20 years of progmem, it appears it is impossible for avr-gcc people to not think in that term, and instead just do "vanilla C/C++".  The convenience of the newer tools is that Binutils comes with a linker descripton that caters for .rodata in flash and adds the needed extra 0x4000.  That's all.  You can have a custom ld script without having to build / install complete toolchains.  If you deploy the sources, then it's much cleaner without pgm_read sprincled all over the place (it's even simpler when you just do GNU asm). Moreover, by avoiding progmem you might get less register pressure as you can access flash also via X and Y.

 

* custom specs:  If Atmochip backported the mentioned PRs, then the compiler should support -mabsdata.  Make sure specs-attiny104 sets it.  Compiled with -v, all calls to cc1 should show -mabsdata.

 

* addressing: tiny does not support REG+Offset addressing, the only luxury in indirect addressing is REG, REG+ and -REG, i.e. indirect, post-increment and pre-decrement.

 

* avr-gcc -mmcu=avrtiny: gcc is not good in using pre- and post-modify addressing (is was good until v3.4, released around 2006). Due to the poor addressing capabilities, few address registers and few GPRs, you may expect additional overhead.  It's hard to push gcc into using direct addressing (LDS / STS) and not indirect addressing when there are several accesses to the same static datum.  And if your code is so complex that it triggers a frame, you lost :-)

 

All this refers to FSF mainline, and I cannot tell in how far (or not) it applies to Atmochip's.

 

As I already wrote, such project is kinda proof-of-concept, and avr-gcc + tiny has hardly any coverage. Improvement of addressing might be achieved by a new post-reload, target-specific pass, but to implement it will be up to the one that deems it important enough.

 

Maybe combining C and Asm is an option. You can start with C and implement stuff in Asm if C hurts too much.  Remember that avrtiny follows its own ABI, cf. gcc wiki for details.  However, following an ABI and a specific calling convention might introduce overhead by itself, so you'll need some experience which stuff is appropriate in C and which is too painful, or if you dump C and resort to Asm.

 

 

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I appreciate all of your remarks, Georg-Johann.  Thank you so much for your detailed responses, for your insight, and for you amazing work over the years.  I have personally benefited immensely from it, as I know everyone else here has.

 

A combined C/asm approach may be what I end up using, if not pure asm.  Much will depend on the 3rd party.  As it is, the My preference (and probably theirs) would be for the build environment to be easy to get, and easy to use.  At the moment, the best available which fits that description seems to be 3.6.1 (5.4.0).  I expect building from source (even if it's only binutils) will not be in the cards for that 3rd party this time around.  I suspect that it may be enough for them to opt for a different device, perhaps even an m48 as they already have some familiarity with it.  At the moment it's unclear to me how many units will be built, so the added cost ($0.33 v.s. $0.714) may be completely acceptable to them.

 

I hope this whole exercise hasn't been for naught.  Even so, I have learned a great deal.  I may yet get the target app ported with pure asm.  Only I need know that the generated code is heinous, as long as it works.  I don't anticipate the need to upgrade the app's requirements, as it is part of a retro-fit to a legacy product, so even if I come in at 100% flash and SRAM, so be it.

 

Thank you all.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
I may have to go with asm, but this is for a 3rd party who will own the source code, and the preference/requirement is that it be in C.

After 40 posts, >>now<< we are learning of this requirement?

 

I thought the primary criterion was Linux toolchain?

 

-- First, how much credence do you want to put into a trial example that can't be built anyway?

-- If C is the primary criterion, then put a representative test program into CodeVision, and see what it comes up with.  In some respects the CV code generation model lends itself a bit better to brain-dead models.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After 40 posts, >>now<< we are learning of this requirement?

It's not really relevant to the original question, which is how to get >>any<< toolchain for Linux working with the t104.  The underlying problem which got me here was that __flash doesn't seem to play well with targets which map NVM to data space.  The PROGMEM workaround (kludgey though it may be) was pointed out in #25.

 

I thought the primary criterion was Linux toolchain?

It is.

 

-- First, how much credence do you want to put into a trial example that can't be built anyway?

You've lost me (again).  It can be built.  Did you miss #30 (and #32)?

 

If C is the primary criterion, then put a representative test program into CodeVision, and see what it comes up with.  In some respects the CV code generation model lends itself a bit better to brain-dead models.

Who said it was the primary?  Or even >>a<< primary?:

I may have to go with asm, but this is for a 3rd party who will own the source code, and the preference/requirement is that it be in C.

I may have to do some convincing... either of the client, or of the compiler ;-)

 

 

In some respects the CV code generation model lends itself a bit better to brain-dead models.

Now >>you're<< ignoring the primary criterion:

Atmel Toolchain For Linux supporting ATtiny104

 

Seriously, I think we're done here.  Unless someone can make any other non-Window suggestions, and/or can point out ways in which GCC can be convinced to generate less heinous code (as @SprinterSB has shown, even v7 and v8 seem to be lacking in this respect), I'm satisfied that this thread is wrapped up.  I won't mark it 'solved', because it isn't really.  Just exhausted ;-)

 

I may one day fiddle with LLVM myself, but unless it's (nearly) a single-click experience for the 3rd party to deploy, I'll stick with 3.6.1.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
I thought the primary criterion was Linux toolchain? It is.
theusch wrote:
the preference/requirement is that it be in C.

I don't see a Linux in that customer requirement.

 

joeymorin wrote:
You've lost me (again). It can be built. Did you miss #30 (and #32)?

Ummm--

joeymorin wrote:
EDIT: Let's put aside for the moment the fact that the t104 has only 32 bytes of SRAM, and that the above #define would call for 128 bytes ;-)

From #35.  No, I guess I can't put it aside--how can one complain about code generation for a fatuous example?

 

So you want to hold up #30 code as the example?

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

...continued...

Just for fun I built #30 with CV, using a bit of editorial discretion.

#include <io.h>
#include <stdint.h>
#include <delay.h>

#define FLASH_RATE 0.5

flash uint8_t foo[]  = {
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
  };

void main(void) {

  
  uint8_t bar;
  
  DDRA = 0;
  DDRA = 0xFF;

  while(1) {
    for (bar=0; bar<sizeof(foo); bar++) {
      PORTA = foo[bar];
      delay_ms((unsigned int)(500.0 / FLASH_RATE));
    }
  }   

}

...and no joy (i.e., no magic pills with jumping to that toolchain):  ~150 bytes versus ~112.  Let me peek...

 

-- Flash reads are a subroutine.  I guess if only one invocation one could put it inline.

                 __GETB1PF:
00003e 5cf0          SUBI R31,-0x40
00003f 81e0          LD   R30,Z
000040 9508          RET

 

-- Delay primitive is a 12-word subroutine.  _delay_ms() resolves into 11 words, inline.

 

--  Full vector table in both versions.  That can of course be adjusted.

 

-- CV prologue disables watchdog, and sets both stack pointers as is its wont.  Certainly one could adjust the prologue.  I leave the belt-and-suspenders code intact.  If I was down to needing the next one or a few words, then...

 

So good luck.  If it were me, I'd build the real ported app and see how close it is to fitting.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:

EDIT: Let's put aside for the moment the fact that the t104 has only 32 bytes of SRAM, and that the above #define would call for 128 bytes ;-)

From #35.  No, I guess I can't put it aside--how can one complain about code generation for a fatuous example?

The app I'm porting had it #defined as 64 (for 128 bytes), but I can live with 8 (for 16 bytes).  The code I posted is unaffected, since it doesn't change with a lower define.  Only the divisor does.  Generated code is nearly identical.

 

If it were me, I'd build the real ported app and see how close it is to fitting.

I did.  It fits.  Not tested yet, nor validated for maximum stack usage.  I'm done for now, as I must wait for answers from the 3rd party before spending any more time on this.  Thanks.

 

EDIT:  typo.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Mon. Dec 11, 2017 - 10:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> Now if I try to use __flash:
> $ cat blink104.c

 

v7 complains

</p>
<p>In function 'main':<br />
blink104.c:10:16: error: address spaces are not supported for reduced Tiny devices<br />
static const __flash uint8_t foo[] = {<br />
            ^~~~~~~</p>
<p>

Dropping __flash, "foo" will end up in .rodata.  The linker script then doesn't put .rodata in RAM but in flash, adding an offset of 0x4000 as outlined after "Please notice that on these devices, there is no need for progmem at all..." in

http://gcc.gnu.org/onlinedocs/gc...

The inconvenience with older versions of Binutils is that you need a custom ld script with the indicated adjustments (newer versions come with the the indicated adjustment per default).

 

> Am I to conclude that the use of const is enough to place data into flash?

 

With appropriate ld script: Yes. (You'll even get vtables in flash if you are a C++ boy).

 

> Or is: __attribute((externally_visible)) also required?

 

No, that was just paranoia because I didn't know whether you optimize with -lfto (lto may make it non-global otherwise, and you don't see the symbol in the map file any more).

 

> It would appear that neither of these is sufficient, at least prior to gcc v7.2.

 

The trick is not the compiler version but Binutils version / linker script.  The only addition in the new compiler is that it won't trigger __do_copy_data for stuff in .rodata. Hence, with the script additon from above, you may still see superfluous __do_copy_data.

 

> I'm forced to wonder if the t104 actually has lpm.

 

If the dadasheet is correct and not a pasto, then the devices support

 

* LPM

 

* ADIW, SBIW but *no* MOVW

 

* LDD and STD (reg+offset addressing)

 

There is no such combination in gcc. Same with gas for avrtiny: it will complain when it sees respective codes. The best fit is -mmcu=avrtiny which supports none of the instructions above; the worst lost being LDD and STD addressing being no more available.

 

If the datasheed is correct, then ATtiny102/4 is more similar to AT90S2313 or ATtiny26 from avr2 family, but with only 16 GPRs and 16-bit LDS/STS.  To my knowledge, neither gcc, binutils nor avr-libc support such a device family.  So much for coverage :-P

 

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The best fit is -mmcu=avrtiny which supports none of the instructions above

Got it.

 

the worst lost being LDD and STD addressing being no more available.

 

If the datasheed is correct, then ATtiny102/4 is more similar to AT90S2313 or ATtiny26 from avr2 family, but with only 16 GPRs and 16-bit LDS/STS.  To my knowledge, neither gcc, binutils nor avr-libc support such a device family.  So much for coverage :-P

Indeed!

 

Again, many thanks.

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
I may one day fiddle with LLVM myself, but unless it's (nearly) a single-click experience for the 3rd party to deploy, I'll stick with 3.6.1.
clang with AVR can be built but it's not yet turnkey.

http://clang-developers.42468.n3.nabble.com/How-do-I-call-clang-for-AVR-targets-td4058258.html

How do I call clang for AVR targets?

(last post on Oct 03, 2017)

or http://lists.llvm.org/pipermail/cfe-dev/2017-October/055649.html

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gchapman wrote:

There's an alternate AVR code generator in LLVM.

http://releases.llvm.org/5.0.0/docs/ReleaseNotes.html#changes-to-the-avr-target

As you are recommending LLVM, you can certainly help with building it (the official blob does not support avr).

Downloading llvm-5.0.0 source bundle and following build instructions, I am running into the following build error:

-- Constructing LLVMBuild project information
CMake Error at CMakeLists.txt:688 (message):
  The target `AVR' does not exist.

      It should be one of
  
  AArch64;AMDGPU;ARM;BPF;Hexagon;Lanai;Mips;MSP430;NVPTX;PowerPC;Sparc;SystemZ;X86;XCore

-- Configuring incomplete, errors occurred!
See also ".../build/llvm-5-avr/CMakeFiles/CMakeOutput.log".
See also ".../build/llvm-5-avr/CMakeFiles/CMakeError.log".

 

avrfreaks does not support Opera. Profile inactive.

Pages