CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

rom * in sub-structure can cause function to not be resolved

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
allenhuffman



Joined: 17 Jun 2019
Posts: 552
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

rom * in sub-structure can cause function to not be resolved
PostPosted: Wed Feb 05, 2020 11:33 am     Reply with quote

I already submitted this to CCS, but I wanted to post it here in case anyone else has stumbled on this.

PIC24 CCS compiler, multi-unit compile:

We ran into another issue with structures today, where a function reported:

Code:
*** Error 112 "main.c" Line 21(1,1): Function used but not defined:  ... MakeButton 1087  SCR=4431


We narrowed it down to a "rom int8 *ptr;" in a sub-structure that was being returned by the function. Here is a sample.

button.h
Code:
#ifndef BUTTON_H
#define BUTTON_H

#include <main.h>
#include <stdint.h>

typedef struct
{
   rom int8 *Icon_Ptr; // Comment this out, and it works.
   int dummy;
} Basic_Button_Type;

typedef struct
{
   uint16_t          Button_Number;
   Basic_Button_Type Basic_Button;
} Screen_Button_Type;


// PROTOTYPE
Screen_Button_Type MakeButton(unsigned int index);

#endif


button.c
Code:
#include <main.h>

#include "button.h"

Screen_Button_Type MakeButton(unsigned int index)
{
   Screen_Button_Type tempButton;

   tempButton.Button_Number   = index;
 
   //tempButton.Basic_Button.Icon_Ptr = 0x1234;

   return tempButton;
}


main.c
Code:
#include <main.h>

#include <stdint.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "button.h"

#define NUM_BUTTONS 100

//Button_Type Buttons[NUM_BUTTONS];

void main()
{
   Screen_Button_Type Buttons[NUM_BUTTONS];
   
   for (int idx=0; idx<NUM_BUTTONS; idx++)
   {
     Buttons[idx] = MakeButton (idx);
   }
   
   for (int idx=0; idx<NUM_BUTTONS; idx++)
   {
      printf ("Button %u - Number:%u\r\n",
         idx,
         Buttons[idx].Button_Number);
   }

   while(TRUE);
}


When we build this, it reports MakeButton() isn't there. If we comment out the "rom int8 *Icon_Ptr;" line in the buttons.h header file, the function is magically available.

Our real project was actually using a function in other files, just fine, but in main.c or another .c file that function would not resolve.

We just moved the "rom" thing into the top structure and everything is fine, though we hope to have a fix so we can put it back where we wanted it.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Feb 05, 2020 12:34 pm     Reply with quote

I've never heard of 'perfect programs' when using "multi-unit compile: ".
Historically the compiler has been a 'one pass - one program' type environment.

Every once in awhile, we see postings of 'odd' or 'strange' behaviour and someone usually figures it relates to attemping MCU.

I've never given it much thought since PCM v2.540 and PIC16C84s.
allenhuffman



Joined: 17 Jun 2019
Posts: 552
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Wed Feb 05, 2020 12:52 pm     Reply with quote

The list of problems is growing daily Smile
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Thu Feb 06, 2020 4:17 am     Reply with quote

I think this again ties into function overloading.

ROM pointers are actually a very complex construction. I'm not at all
surprised that these can't be exported between compilation units. Perhaps
this should be a documented restriction. Problem is that these rely on
a table built as part of the compile for resolution. Since this won't be
passed with import/export, result, problem....
What's happening is that the structure declaration is being 'simplified'
to remove this when exported. This results in the function no longer actually
'matching' it's declaration, so the imported version does not give the
physical definition for the function. So the message.

I think it really is worth saying that CCS is fundamentally a single pass
compiler. The support for MCU's, has always been limited, and it is far
better not to use it. A very large percentage of the problems are when
people insist on using CCS with MCU's.
allenhuffman



Joined: 17 Jun 2019
Posts: 552
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Thu Feb 06, 2020 8:41 am     Reply with quote

There's a related issue we found, and I went and created overload functions for a half dozen types (structure, int, char *, float, double, etc.) and ran some tests on that. I found another issue where, since you can't overload a (void) function, as soon as you have one, it won't be resolved if you have a prototype for it. Removing the prototype allowed it to work.

As we may migrate to another architecture down the line, I am trying to make all new code modular and portable. Which is often not possible here Smile
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
jeremiah



Joined: 20 Jul 2010
Posts: 1346

View user's profile Send private message

PostPosted: Thu Feb 06, 2020 7:36 pm     Reply with quote

allenhuffman wrote:

As we may migrate to another architecture down the line, I am trying to make all new code modular and portable. Which is often not possible here Smile

Modular is doable. We have tons of modular code here. Portable is a bit open ended. CCS C is a K&R version 1 variant, so if you want it portable to an ANSI compiler, then you probably won't get there easily. They are effectively very different languages. ANSI C has a lot more semantics defined than K&R, which is very open ended.

CCS C is very portable among different PIC chips, which is the target they are aiming for. Note that using multiple compilation units is not a requirement for modularity or portability, so I agree with Ttelmah that one should stick to single file compilation for a single pass compiler. At least until they work out all the kinks in multiple file compilation.

If you want portability, I would recommend using a top down method rather than bottom up. Doing this I have been easily able to move code I made in CCS to an 8051 microcontroller, a cortex M0+ arm, a cortex M4, and a Jetson TX2 without hardly any changes, just the low level peripheral functionality at the bottom of my design. In addition, I have been able to simply replace C files in order to completely change drivers to external interfaces (like switch to a SPI interface chip from an I2C chip for example) with no change to my business logic.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Feb 07, 2020 3:15 am     Reply with quote

Totally.

I use the same libraries on projects here on Raspberry Pi, Arduino, and
PIC. However it is vital to actually understand the differences in meanings
that some things have. ROM * in the first two, does not actually result
in things stored in ROM. In ANSI C, ROM * is just a signal to say that the
RAM values cannot be changed. In CCS C it instead means a value actually
'held' in ROM. Given the different memory architectures, this is a very
important difference. It is historical. CCS actually started to use 'ROM' as a
keyword before it was introduced in ANSI C. The equivalent to ROM in
the Arduino, is PROGMEM.
Write using original K&R syntax. Don't try to use later constructs. Then
when using anything like ROM *, only use this when you actually want to
produce the real effect of storage in ROM, and change this to match the
processor you are using. 'Portability' requires you to understand the
different processor architectures and code for them. Code for a Harvard
architecture is always going to be different to that for Von-Neumann
architecture and you need to understand the abilities and limitations
as you write.
allenhuffman



Joined: 17 Jun 2019
Posts: 552
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Fri Feb 07, 2020 10:22 am     Reply with quote

For anyone interested, CCS has an official document about their ANSI compliance, and notes areas where they aren't.

http://www.ccsinfo.com/downloads/ansi_compliance.pdf

The Microware Ultra-C compiler for OS-9 was similar. While it was a fairly-strict ANSI-C compiler, there were some things that could not be done due to OS-9 using position-independent re-entrant code (I forget what, but I know something about "const" there was handled differently).
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
jeremiah



Joined: 20 Jul 2010
Posts: 1346

View user's profile Send private message

PostPosted: Fri Feb 07, 2020 11:31 am     Reply with quote

allenhuffman wrote:
For anyone interested, CCS has an official document about their ANSI compliance, and notes areas where they aren't.

http://www.ccsinfo.com/downloads/ansi_compliance.pdf


Keep in mind that they update the checklist. It isn't fully vetted by the ISO standards committee. It's often times wrong as well. I've sent multiple reports about non compliance. They fixed some but still haven't fixed all (though they are working on it).

The ANSI C standard defines a lot of "abstract machine" semantics that aren't on that checklist and that they don't support.

For example, Duff's Device was vetted by the ANSI committee as standard based on the semantics as defined in the ANSI standard. However, CCS supports K&R semantics (which are largely open and not defined), so it cannot compile the ANSI version of Duff's Device:

Code:

void main()
{
   short *to, *from;
   int count;
   int n = (count + 7) / 8;

   switch (count % 8) {
      case 0: do { *to = *from++;
      case 7:      *to = *from++;
      case 6:      *to = *from++;
      case 5:      *to = *from++;
      case 4:      *to = *from++;
      case 3:      *to = *from++;
      case 2:      *to = *from++;
      case 1:      *to = *from++;
               } while (--n > 0);
   }
}


which happily compiles in GCC but CCS doesn't understand because it doesn't implement ANSI control structure semantics as defined in the standard.

NOTE: if you are wondering the use of the example, it's useful in various types of optimizations on specific processors and is the foundation to protothreads (I implemented them in CCS C, but had to use a different method with compiler extensions).

NOTE: Sorry if this sounds like I am disagreeing with you. Not my intention. My hope is that you just keep it in mind when you are designing for portability. And I hope you keep submitting the bugs you find to CCS via their support email. The more that can get fixed, the better.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Feb 07, 2020 1:41 pm     Reply with quote

I actually asked if they could change their syntax support to allow
this to work some time ago. Perhaps I need to remind them of this!... Very Happy
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group