chipKIT® Development Platform

Inspired by Arduino™

No strings.h ? Other missing string functions?

Created Mon, 08 Aug 2011 10:25:02 +0000 by WestfW


WestfW

Mon, 08 Aug 2011 10:25:02 +0000

So I'm taking a shot at "avr/pgmspace.h", which is theoretically unneeded on PIC32, but having a fully compatible version that does nothing but dereference pointers (for pgm_read_byte()) seems like it would be a pretty significant portability win.

pgmspace.h also defines a bunch of functions (implemented in avr-libc, I guess) that mimic a bunch of C string function from string.h (memcmp_P, memcpy_P, etc) and strings.h (strcasecmp_P, strncasecmp_P, etc). I had intended to make them just call the ordinary functions, but it seems that there is no strings.h for pic32 at all, and string.h is missing several functions (strcasestr() should be there and apparently isn't.)

What's up with that?


marcmccomb

Mon, 08 Aug 2011 16:59:49 +0000

Hi West:

Sorry you're having troubles with this. For some reason the strings.h was omitted from the last build. As I understand it, there should be a new build coming out in the next day or so that fixes some know issues and this one has definitely been identified. My apologies for the inconvenience. If you need right away, it should be available in an older build.

As always, you can track any issues on our github repository.


WestfW

Mon, 08 Aug 2011 22:15:25 +0000

Huh. I can't find strings.h in the oldest distribution (6/10) either. Not in the microchip mplabc32 1.11a or 2.0 installs, either! (note: string.h and strings.h are different files.)


marcmccomb

Wed, 10 Aug 2011 02:43:38 +0000

Hi Westfw:

chalk it up to a Monday. Sorry to mislead. Thought you were talking about something else. I'll get your question over to one of our Software guys first thing in the morning.


jasonk

Wed, 10 Aug 2011 17:49:58 +0000

The toolchain provided with the chipKIT currently only attempts to provide ISO C standard functions. If there's an open implementation that you suggest that we could snag and put into the chipKIT build for compatibility with avr-libc, I think the team would be open to that.


WestfW

Thu, 11 Aug 2011 06:55:01 +0000

Sigh. I did this badly.

As I said, pgmspace.h on AVR defines a bunch of _P functions for dealing with strings in flash rather than ram, which is a Big Deal on AVR. I ran into difficulties trying to port these definitions to PIC32, but it's more complicated than I initially reported...

It looks like memmem(), memrchr(), and strnlen() are holdovers from BSD and were never standardized.

strcasecmp(), strcasestr(), and strncasecmp() are from strings.h, which is apparently POSIX rather that ISO C.

but strlcat(), strlcpy(), and strsep() look like ISO C function from string.h that are not present in the PIC32 include...

(I don't think that it's particularly important to include these, and I don't know where one would find open source versions of them. I think I'll reconsider my implementation.)


jasonk

Thu, 11 Aug 2011 07:20:13 +0000

Well, we should look into adding them if it will help other Arduino users to port their code to chipKIT. Also, I'll check on strlcat(), strlcpy(), and strsep().


mongo

Wed, 17 Aug 2011 08:31:35 +0000

Some way to convert an int to a char or string would be nice for times when you cannot use Serial.print e.g. when trying to use IOShieldOled.putString/Char with the basic IO shield to write a value from analogRead()

I wrote some look up tables but that will be beyond most basic io shield type users.

The ability to cast from an into to a char would be enough for this IMHO

I guess making the IOShieldOled library support int's and longs would work also.


GeneApperson

Wed, 17 Aug 2011 16:41:19 +0000

The C runtime function itoa converts an int to a string in any radix.

int i; char str[16];

itoa(i, str, 10);

This converts the value of i into a character string in the array str, with 10 as the radix of the output string.

I think that the standard C language runtime is available for use in the MPIDE.

You have to make sure that the output character array is large enough to contain the resulting string or you will get a buffer overrun and a hard to track down bug. There is a more secure version of the function itoa_s that allows you to specify the buffer size, but I'm not sure if these versions are available.

Gene Apperson Digilent


mongo

Wed, 17 Aug 2011 16:57:54 +0000

technicaly itoa is not standard but I did try it, I will have to look at what the issue was tonight but I think it was a link error.

sprintf was broken but I am in the Windows IDE, which is not my normal platform.

I have a git clone going and will try to make it in native 64 bit Linux and see if I can get better debug information for you.

BTW,

I wrote itoa as an in program function to fix the issue last night.

thanks.


GeneApperson

Wed, 17 Aug 2011 18:13:15 +0000

I did a quick sketch using itoa and then used the verify button. I didn't get any errors, but I didn't try to run it.

Sorry if I was 'talking down' to you. It's hard to know how much expertise the other person has when answering a question.

Gene


mongo

Wed, 17 Aug 2011 22:41:45 +0000

NO worries,

I too no offense, and I am very rusty in C, the last time someone paid me to work on it was in 1997.

I think part of the issue may be 64 vs 32bit-ness and the fact that Arduino has been moving strings into their core. (although it looks like they have the full Wstrings in 1.0b1)

It is interesting that Serial which Calls Print which does the same type of conversion is not having issues.

I do not want to make this thread drift too much but I will try and find what is causing my issue and provide a fix.

I do have several versions of the IDE on my windows machine, it may just be a path issue on my part.


unexpectedly

Mon, 02 Sep 2013 02:49:33 +0000

OK, I'm unearthing a properly dead thread.

But this is my 2nd go at porting Arduino code to chipKIT land and Googling memcpy_P chipKIT got me 3 hits.

If you could make some replacement for #include <avr/pgmspace.h> that would be awesomesauce! I know that with one of them, I've always cheated with great success:

uint8_t type = pgm_read_byte(&amp;(p_item-&gt;type));

... just take out the pgm_read_byte(& ) stuff...

uint8_t type = p_item-&gt;type;

... and then go find when p_item was cast and change that to a byte, char, or uint8_t.

However if the code is being slick and is wanting a pointer out of it all...

OMMenuItem* item = reinterpret_cast&lt;OMMenuItem*&gt;(pgm_read_word(&amp;(items[p_target + i])));

I then leave the (& ) around the variable.

And the line below the above:

memcpy_P(m_dispBuf, &amp;( item-&gt;label ), sizeof(char) * sizeof(m_dispBuf) );

I changed memcpy_P to memcpy ... and it at least compiled.


majenko

Mon, 02 Sep 2013 08:31:06 +0000

The _P versions of functions only make sense on a Harvard architecture chip - that is one where the flash and RAM have separate memory spaces (flash memory address 0 is not the same as RAM memory address 0). The PIC32 is a Princeton architecture - the flash and RAM share the same address space. So you don't need any cheesy hacks to copy from one to the other - you just access it as it is. Just like programming in C or C++ on a normal PC.


unexpectedly

Mon, 02 Sep 2013 22:31:22 +0000

That's not quite working for me. They are invested too heavily in structs and typedefs and defines to get their menu system setup pre-compile. Just changing all these instances to their own variables wasn't enough. They've got text labels at the front of each struct but it's not getting passed to the display callback.

I have nerded out on pointers before ... even legitimately deploying a *** for a linked list of items where each type had structs built for them and all could work interchangeably. It was particularly annoyed because I had earlier whined to my supervisor about someone else's *** saying "why the F would you even need that for!?" :lol:


majenko

Mon, 02 Sep 2013 22:44:51 +0000

All these images and talk of TFT screens is getting me impatient for mine to arrive so I can play with it.

I normally write my own menu systems as and when I need them - usually based around arrays of structs including pointers to functions to execute for each entry, then a simple "displayMenu()" function to display and interact with a specific menu array. They're usually for simple mono LCD or OLED displays though - 16x2, 20x4, and sometimes 128x64 GLCD. Maybe something with icons and pretty colours would be nice...

Of course, all I really want it for is to display pictures of cats...