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 support@ccsinfo.com

CCS C: how to limit function defined inputs

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



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

CCS C: how to limit function defined inputs
PostPosted: Fri Nov 25, 2011 10:31 am     Reply with quote

I would like to limit possibilities of inputs for functions. is it possible?

e.g.

Code:
enum RF24_STATUS {   //Status Register
   IRQ_RX_dataready  =0b01000000,   //(0)Data Ready RX FIFO interrupt. Write 1 to clear bit.
   IRQ_TX_datasent   =0b00100000,   //(0)Data Sent TX FIFO interrupt. Write 1 to clear bit.
   IRQ_MAX_retransmit=0b00010000,   //If asserted it must be cleared to enable further communication.
   IRQ_ALL           =0b01110000,   //Allows clearing all IRQs
   };

/************************************************************************************
* IRQs must be cleared through this command. Usage:
* RF24_STATUS_clr_IRQs(IRQ_RX_dataready|IRQ_TX_datasent|IRQ_MAX_retransmit);  //select IRQs to clear, or
* RF24_STATUS_clr_IRQs(IRQ_ALL);       //clear all possible IRQs
*/   
void RF24_STATUS_clr_IRQs(RF24_STATUS xstat) {
   spi_xfer(RF24_SPI, W_REGISTER|STATUS);
   spi_xfer(RF24_SPI, xstat);     //clear selected IRQs(bits 6,5 or 4 from xstat)
}
/************************************************************************************/   

ps: I want that the compiller could only accept the constants from RF24_STATUS. Not variables, not anything at all!

e.g.
Code:
//I don´t want this:
int i;
RF24_STATUS_clr_IRQs(i);
//and not this
RF24_STATUS_clr_IRQs(2);


//But this MUST be accepted:
RF24_STATUS_clr_IRQs(IRQ_RX_dataready|IRQ_TX_datasent);
//Or this:
RF24_STATUS_clr_IRQs(IRQ_ALL);       //clear all possible IRQs


Is there someway to do that? maybe with macros?
_________________
Eduardo Guilherme Brandt
Eduardo__



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

PostPosted: Fri Nov 25, 2011 10:36 am     Reply with quote

To be more clear,
Yes, I know, i could do:

Code:

void RF24_STATUS_clr_IRQs(RF24_STATUS xstat) {
   xstat&=IRQ_ALL;   //limit xstat input to bits 6,5 and 4
   spi_xfer(RF24_SPI, W_REGISTER|STATUS);
   spi_xfer(RF24_SPI, xstat);     //clear selected IRQs(bits 6,5 or 4 from xstat)
}



But I would like to limit input to RF24_STATUS constants as described above.

Thanks for ideas! Very Happy
_________________
Eduardo Guilherme Brandt


Last edited by Eduardo__ on Fri Nov 25, 2011 4:36 pm; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 25, 2011 2:31 pm     Reply with quote

Possibly you may want to look at the 'assert' macro. It's in the manual
and in assert.h
Quote:
c:\program files\picc\drivers\assert.h
Eduardo__



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

PostPosted: Fri Nov 25, 2011 4:39 pm     Reply with quote

But it is not about assert and RS232.

It´s about how to create functions that accept only some limited types of constant defined parameters.

I do not know if it is possible.
Someone knows some trick to do this?
_________________
Eduardo Guilherme Brandt
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sat Nov 26, 2011 2:41 am     Reply with quote

For a parameter check at compile time, use a construct like
#if
#error
#endif
Ttelmah



Joined: 11 Mar 2010
Posts: 19346

View user's profile Send private message

PostPosted: Sat Nov 26, 2011 5:02 am     Reply with quote

Seriously, no.
The 'constants from RF24_STATUS', are turned into simple int8 numbers when they are used. Just like in a #define, wherever the word exist, the corresponding number is substituted. Even if you perform a parameter check for the values, it'll accept any equivalent numeric value. C, is also a 'weakly typed' language, and _any_ value fed to the function, will automatically be cast to a number, before being used. If you fed the function, a pointer to a value, and the function was testing for the enum values, it'd still accept this, if the low byte of the pointer happened to match one of the values.
It is a great strength of C, allowing you to do some useful things, but it comes at the cost of not being able to do the sort of parameter checking being asked for.
The only way you could do this, would be to use some form of script, which scans the program for every call to the function, and verifies that the parameter is one of the text strings in the enum, before the code is compiled....

Best Wishes
Eduardo__



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

PostPosted: Mon Nov 28, 2011 5:56 am     Reply with quote

Thank you Ttelmah,

I apreciate your answer!
_________________
Eduardo Guilherme Brandt
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

Re: CCS C: how to limit function defined inputs
PostPosted: Mon Nov 28, 2011 8:21 am     Reply with quote

Code:
enum RF24_STATUS {   //Status Register
   IRQ_RX_dataready  =0b01000000,   //(0)Data Ready RX FIFO interrupt. Write 1 to clear bit.
   IRQ_TX_datasent   =0b00100000,   //(0)Data Sent TX FIFO interrupt. Write 1 to clear bit.
   IRQ_MAX_retransmit=0b00010000,   //If asserted it must be cleared to enable further communication.
   IRQ_ALL           =0b01110000,   //Allows clearing all IRQs
   };


//But this MUST be accepted:
RF24_STATUS_clr_IRQs(IRQ_RX_dataready|IRQ_TX_datasent);
//Or this:
RF24_STATUS_clr_IRQs(IRQ_ALL);       //clear all possible IRQs


You've rightly been told this is a matter of weak typing of C compared to the stronger typing of C++, which would allow assignments of compatible integer values, and the even stronger typing of C#, which would only accept the members of the enum. C is NOT C++, nor is it C#. They are all different languages with similar but different syntax and in many ways very different semantics. C comes from an earlier time in computing, when memories were small and processor speed limited. That makes it very suitable for embedded processing such as with PICs.

C doesn't "suffer" from the processor and memory overheads inherent in C++. In CCS C an int is a byte,nothing more. I shudder to think what a byte really takes up in C# with all the typing information and reference counts and the other stuff that has to go along with it. However on PCs, where C# is common, there's tons of memory: it measured in gigabytes, on PICs its still measured in kilobytes. A mere difference of six orders of magnitude.

Is C# "better" than C? That depends on what you are trying to do. There'd be no point trying to program a PIC using C#. The overheads would be crippling. Sure, you don't get a lot of the type protection in C that you do in C# and even C++, but that lovely "safety" costs. Also C was designed from the outset to give near direct access to the hardware. It was created as a language in which to write an operating system: Unix. It was specific to a processor, the PDP-11/20, but allowed porting to other processors: other PDP-11s, which while being largely compatible, all had quirks and differences. That was nearly 40 years ago. (Note Unix came about in 1969 the year orf the first moon landing, but was first written in assembler on a PDP-7, an 18 bitter. C came along later...)

I say all this to point out that its totally unfair to assume C should have language features that we expect modern languages to have. C simply isn't a modern language. It does, however can, when well compiled, give compact efficient code that uses little memory and gives almost direct access to hardware: oerfect for PICs and other embedded programming. C doesn't hold your hand, and it doesn't protect you from doing crazy stuff. If you want all that go use C#. C isn't perfect, no language is, but it when programmed well, and all serious embedded programmers should, then it is capable of getting great things from limited resources. Just don't expect run time type checking and array bounds tests.

In any case, just think about the meaning of
Code:

RF24_STATUS_clr_IRQs(IRQ_RX_dataready|IRQ_TX_datasent);

Is the result part of the set of values you want to constrain the set to? Is the or operator defined within the enum? Does IRQ_RX_dataready|IRQ_TX_datasent actually mean anything in the context of your enum? No, it doesn't. The resulting value isn't even one of the enumerated values, it lies outside the set. As yet I don't know of any general purpose computer language that allow definition of rings and fields as well as enumerations. There must be some special purpose mathematical language that does, but a general purpose one... that runs on tiny processors in a few k of memory?

RF Developer
Eduardo__



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

PostPosted: Mon Nov 28, 2011 11:45 am     Reply with quote

I´m very grateful for your complette answer Mr. RF_Developer! It´s good to know about the past, just for understanding what´s going on.

Concerning to the answer, I understand about the lot of overhead of C++ and I understand perfectly that it´s not proper for uC. I really would like to obtain a copy of that old Unix source codes, just for learning how to make clever and clever code Smile

I´m only was wondering if there were a macro or something like that, just for look some function input possibilities(I mean during compiling, not run time, of course).

For example, I develop some peripheral driver. If someone(not me) use that driver in their program, the driver file would not be able to block some input different possibilities of that defined at the device driver. Understand?

Ttelmah said that it´s not possible in C, due of inherent language capabilities.
Well, I just asked. Now I know that it´s not possible.

Thanks for all Razz .
_________________
Eduardo Guilherme Brandt
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue Nov 29, 2011 3:16 am     Reply with quote

Eduardo__ wrote:
I really would like to obtain a copy of that old Unix source codes, just for learning how to make clever and clever code Smile


Unix wasn't clever code, it was just code that worked, and a lot of it would make us, now, knowing what we do, shudder. As it was handcoded by very few people they built it from small code modules that were managable on a human scale. They built these, whether from the ground up or the top down I don't know, into the operating system and all its utilities, and its in the utilities that Unix really scored, that and its heirarchical filesystem which while not being unique (the idea came from the behemoth MULTICS) in the end turned out to be revolutionary. Also, the language, C (that's K & R C, not ANSI C - the early versions of Unix may well be uncompilable with any of todays C compilers), was written to do what the operating system needed it to do and no more, so the fit was perfect. If its OS code you're after, take a look at Linux, or any other open source OS code. I suspect you'll find it uses pointers, and layers of indirection everywhere, which makes it difficult to read and understand but its not really "clever". The overall design; the way its all put together; *is* clever however.

Quote:

For example, I develop some peripheral driver. If someone(not me) use that driver in their program, the driver file would not be able to block some input different possibilities of that defined at the device driver. Understand?


Yes, I understand. But its important for the device driver code to check input parameters are valid: that the driver is being asked to do something sensible, and for it to raise suitable error messages when it isn't. Even so, often errors can only be detected when the driver attempts to perform the requested operation: 'Jeez, you want to write to which port?? You ain't even opened any yet!' Syntax is one thing, semantics are quite another. Its *code* that has to do all that at run time, no compiler can do it all for you.

Very few drivers ever get called with parameters fixed at compile time as your original question assumed. If you think about it, drivers are there to abtract IO and other functionality: they are inherently required to deal with variable data derived from the tsk at hand at run time. Read this disk block, send that message. Write this data to eeprom, send that packet over the network. Close this, open that, CRC the other....

RF Developer
Eduardo__



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

PostPosted: Tue Nov 29, 2011 6:18 am     Reply with quote

Thank you again Mr. RF_Developer for sharing with us. Idea

It´s seems that you lived all that old time of computers. When do you began programming? 80´s? Question
_________________
Eduardo Guilherme Brandt
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue Nov 29, 2011 6:36 am     Reply with quote

Eduardo__ wrote:

It´s seems that you lived all that old time of computers. When do you began programming? 80´s? Question


1976 or '77. Algol 60 and SIR (an assembler) on Elliott 901 18 bit machine, Just 8K words of core store. We had to built our own serial interface, mostly out of discrete components.

I first used C in 1980 on Unix V5? on PDP-11/34s. Programmed a nifty version of the classic text/alphanumeric "graphics", with plenty of ASCII art, Star Trek game. Did some compilation work too, producing parse trees from a compiler for a subset of Pascal.

Processor power wise, the 11/34 was roughly equal to the upper end PIC18Fs.

Yet, I'm sure others here go back further... anyone worked on a 360?

RF Developer
dyeatman



Joined: 06 Sep 2003
Posts: 1924
Location: Norman, OK

View user's profile Send private message

PostPosted: Tue Nov 29, 2011 6:56 am     Reply with quote

I started out programming assembly on 8008, 8080 and Motorola 6800
(anyone remember the Mikbug?) in the late 60's. A number of computers
later, Altair etc, I "did some time" on the IBM360/30 programming in Cobol,
WATFOR, WATFIV and later in JCL. In the mid 70's, I designed PDP
based systems (PDP-8 and PDP-11 mostly) and attended the DECUS
conventions every year.
_________________
Google and Forum Search are some of your best tools!!!!
Eduardo__



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

PostPosted: Tue Nov 29, 2011 10:35 am     Reply with quote

And I was born in 81! Shocked

All of you are really an important part of the history.

Computer programmers should be very rich also!!! Very Happy

but really, the world of electronics is fascinating.
_________________
Eduardo Guilherme Brandt
Eduardo__



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

PostPosted: Tue Nov 29, 2011 10:43 am     Reply with quote

But, I would like to know:
Anyone of you have had problems with your bones(articulations) and wrist?

I fell pen. I´m only 30!
_________________
Eduardo Guilherme Brandt
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