misadventures with char type

Go To Last Post
21 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Yesterday was filled with confusion and doubt. Today brings a shaft of light, but little in the way of enlightenment.

 

I appear to have my Raspberry Pi Zero toolchain working. Trivial programs compile and upload to my fleet of ATTiny85s and LEDs blink.

 

Then I got over enthusiastic and refactored my giant ugly .ino file for my game console project into a set of nice neat .c and .h files. After much hacking with various things not being declared in the right order (My primary programming experience is web/python!) I got it to compile! Shuffled it over to the chip and plugged it into my little development board.

 

Blank Screen.

 

Hours of Hack, Hack, Hackity Hacking and still no joy so I broke and installed AVR Studio 7 on my work laptop. Watched the pretty lights of the simulator and everything seemed to be working correctly so I built it, fired the AS7 .hex at the chip and BINGO, worky!

 

With no changes made by me at all.

 

After MUCH more hacking, I finally tracked down the culprit:

 

</p>
<p>void clear_display()<br />
{<br />
    PORTB &= ~(1 << DC);        // LOW<br />
    send_command(0x21);         //  COLUMNADDR<br />
    send_command(0);            // Column start address (0 = reset)<br />
    send_command(WIDTH - 1);    // Column end address (127 = reset)</p>
<p>    send_command(0x22);         //  PAGEADDR<br />
    send_command(0);            // Page start address (0 = reset)<br />
    send_command(7);            // Page end address // 64 lines<br />
    <br />
    PORTB |= 1 << DC;           // HIGH<br />
    <br />
    for (char i=0 ; i<128 ; i++)<br />
    {<br />
        shift_out_block(SPACE[0]);<br />
    }<br />
}</p>
<p>

 

When AS7 compiles that, the for loop is perfectly happy, char is unsigned. When avr-gcc compiles it on my RPi, it is signed. i can never be 128, the loop goes on forever and ever and ever and ever. Dutifully pushing out blank spaces into the SSD1306 controller.

 

These are the sorts of pitfalls I am not equipped to climb out of without a LOT of effort!

 

my utils.h file gained a new line:

 

</p>
<p>typedef unsigned char byte;</p>
<p>

 

There be Dragons.

 

-Mike

This topic has a solution.
Last Edited: Fri. May 11, 2018 - 10:27 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

time to lookup and start using <stdint.h>

 

instead of using char, use uint8_t

    ..             ..      int,  use int16_t  signed, or uint16_t unsigned.

 

Don't make up non-standard size types.....

 

 

 

Jim

 

Mission: Improving the readiness of hams world wide : flinthillsradioinc.com

Interests: Ham Radio, Solar power, futures & currency trading - whats yours?

 

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

I have seen those types, I just don't like the way they look - the names slide off my eyes.

I'm not sure 'byte' is particularly non-standard (and it exists in the Arduino environment), but I certainly take the point that I'm adding stuff that'll likely break later.

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

Also, unrelated - why do I always end up with html tags in my code blocks here?

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

line 83 in stdint.h 

http://svn.savannah.gnu.org/viewvc/avr-libc/trunk/avr-libc/include/stdint.h?revision=2503&view=markup

...

typedef unsigned char uint8_t;

...

 

With thanks to Jim in post #2 as am simply elaborating his post (ie wouldn't if not for his post)

 

Edit: thanks

 

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

Last Edited: Fri. May 11, 2018 - 12:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MalphasWats wrote:
(My primary programming experience is web/python!)
You're doing well to learn C then you'll be well equipped to go end-to-end for MCU to web browsers.

Some MCU have the computational power and memory to run a WebSocket server; else, the WebSocket server on an application processor that connects multiple MCUs to web browsers.

https://www.websocket.org/about.html

 

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

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

It sounds like you did your RPi Toolchain install wrong (or incomplete) and are getting some include files from the wrong place (native ARM stdlib.h, or something.)

Or it could be a gratuitous change introduced by gcc folk in a newer version of the compiler: "the standard SAYS that it is undefined whether "char" is signed or not, so we decided to change something it to make sure everyone stays on their toes!"  (although, I'm pretty sure that "char" has always been signed on AVR, by default.)

 

linux package manager installs of embedded toolchains are "not to be trusted."

There's also apparently a compiler switch that Studio might set by default.  "-funsigned-char"

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

hah, -funsigned, how appropriate.

 

Anyhoo, lesson learnt.

 

I almost certainly installed it wrong - $ sudo apt install make-thingy-go-please, but I was aiming for "simple-out-of-the-box-ish" as much as possible!

 

Not looking forward to trying to make my new ATTiny1614s work - looks like a whole different ball game, but I'll save all those questions for a few weeks to give you all a chance to recover from me!

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

MalphasWats wrote:
I have seen those types, I just don't like the way they look - the names slide off my eyes.
time to get over it. stdint.h has been an important part of C since 1999. It makes code much safer.
.
You probably also need to know that char has THREE types. Only use "char" (neither signed nor unsigned) when what you are actually dealing with are characters.

Last Edited: Fri. May 11, 2018 - 10:06 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is a "byte" signed or unsigned?

How would I know?

I don't even want to know.

 

Using "byte" for numbers is just as sloppy as using char for numbers.

Use stdint.h if you have any interest into writing portable code or want to show your code to others.

Paul van der Hoeven.
Bunch of old projects with AVR's:
http://www.hoevendesign.com

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

MalphasWats wrote:
... and still no joy so I broke and installed AVR Studio 7 on my work laptop.
For ones with MacBooks, Microchip AVR GCC 3.6.1 has made a web page (IIRC was 3.5.4)

Microchip Technology Inc

Microchip Technology

SAM(ARM) and AVR Toolchains (C Compiler)

http://www.microchip.com/avr-support/avr-and-arm-toolchains-(c-compilers)

...

AVR Toolchain for Darwin

4/18/2018

...

 

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

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

Paulvdh wrote:

Is a "byte" signed or unsigned?

How would I know?

I don't even want to know.

 

Using "byte" for numbers is just as sloppy as using char for numbers.

Use stdint.h if you have any interest into writing portable code or want to show your code to others.

 

The primary use for my byte type is representing 'image' data to be displayed on the OLED screen and a single 'byte' of pixels isn't a number at all. Whilst I accept that using the type in a for loop as a 'number' is a touch lazy, I'm not completely sure the intention/sign-ed-ness isn't obvious bearing in mind I'm using it in a simple for loop.

 

The only reason it ever became a char was because when I switched from 'Arduino' to core-less avr-gcc the byte type no longer existed. I was trying to fix a number of other errors in order to get it to compile and picked char as I didn't want to waste a byte of SRAM on an int that was never going to go above 255.

 

as always, I shall endeavour to do better ;)

 

-Mike

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

westfw wrote:
Or it could be a gratuitous change introduced by gcc folk in a newer version of the compiler: "the standard SAYS that it is undefined whether "char" is signed or not,
Implementation-defined.

Undefined is the realm of nasal demons.

Implementation-defined things are documented.

If the documentation is hard to find or not trusted, they can often be tested.

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?

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

Get into the habit of also ramping up the default warning level using the options -Wall -Wextra. You would have found the bug instantly.

nigel@E6420:$ avr-gcc -std=gnu99 -Wall -Wextra -Os -mmcu=atmega328  -c MalphasWats.c
MalphasWats.c: In function 'clear_display':
MalphasWats.c:24:19: warning: comparison is always true due to limited range of data type [-Wtype-limits]
  for (char i=0; i<128; i++) {
                  ^

 

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

Oh, that's interesting, thank you. I've just got done making a makefile, so I can put this in there now!

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

MalphasWats wrote:

(My primary programming experience is web/python!)

Home

Design News

The Soon-to-Be-Extinct Embedded Software Engineer

by Jacob Beningo

May 14, 2018

https://www.designnews.com/design-hardware-software/soon-be-extinct-embedded-software-engineer/39152617858743

...

Instead of training new [embedded software] engineers, they are starting to rely on application developers, who have experience with Windows applications or mobile devices, to develop their real-time embedded software. 

...

via

The Ganssle Group logo

The Ganssle Group

The Embedded Muse 350

by Jack Ganssle

May 21, 2018

http://www.ganssle.com/tem/tem350.html

...

 

The Vanishing Embedded Engineer?

http://www.ganssle.com/tem/tem350.html#article4

 

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

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

If the documentation is hard to find or not trusted, they can often be tested.

Ah yes, the "poke at it and see" method ;-)

"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."

"Read a lot.  Write a lot."

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

 

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

joeymorin wrote:

If the documentation is hard to find or not trusted, they can often be tested.

Ah yes, the "poke at it and see" method ;-)

At least in the case of implementation-defined behavior,

one knows that there is an answer.

In the case at hand, an answer is #define char_is_signed (CHAR_MIN< 0)

Some implementation-defined behaviors also have corresponding #defined constants.

For some things, poke at it and see can be reliable.

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?

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

I was only poking fun because I know you've railed against the "poke at it and see" approach in the past.  FWIW, and despite how much I poke at things to see, I agree with you, insofar as the method should not be a replacement for good documentation.  It can, however, be a useful tool to aid in understanding behaviour or confirming one's understanding of documented behaviour.

"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."

"Read a lot.  Write a lot."

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

 

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