Searching \ for '[PIC] accurate delay routines - Standard embedded' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/time.htm?key=delay
Search entire site for: 'accurate delay routines - Standard embedded'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] accurate delay routines - Standard embedded '
2006\02\27@100744 by Walter Banks

picon face
Almost any time function is a problem to define in any general sense.
The mandate of ISO is to define and document standard practice and
that opens the door for embedded additions like standard delays. In
our own compilers we have defined delays as either time functions
that need to know the execution speed of the processor or cycle
delays that reference some form the of the system clock.

In the discussions on C standards for embedded systems delays
only came up briefly and was seen as a library rather than
language issue.

What should be in a standardized embedded library?

Ignoring exact syntax for a moment.

DELAYS

void Delay_Ms_(delay);
void Delay_Us_(delay);
void Delay_10xUs(delay);

PORTS

void initPORTwrite(port,output);
void writePORT(port,data);
char readPORT(port);


SERIAL I/0

void _initSerialPort(portnumber,syncronous/asyncronous,baudrate,databits,parity,stopbits)
void _putc(port,ch);
char _getc(port);

MICROWARE  I2C  SPI

 void initSPI(port,config);
 char readSPI(port);
 void writeSPI(port,data);

 void initI2C(port,config);
 char readI2C(port);
 void writeI2C(port,data);

Analog to Digital

void initAtoD(void);
int readAtoD(channel);

Digital  to Analog

voidDtoA(void);
writeDtoA(analogvalue);

Pulse Width Modulation

void  initPWM(port);
void PWM(port,frequency,dutycycle);


Wachdog Timers / COP

void initWD(timoutdelay);
void clearWDT0(void);
void clearWDT1(void);
void clearWDT(void);





Walter



Wouter van Ooijen wrote:

{Quote hidden}

2006\02\27@104204 by Wouter van Ooijen

face picon face
> What should be in a standardized embedded library?
> Ignoring exact syntax for a moment.

Walter, if you ask what I was talking about: I want to be able to
control execution down to the timing of individual instructions, without
the burden of assembly language. A simple example:

- make pin X high
- 5 us later: make pin X low

I am not interested in how long it takes to make a pin high or low, but
I do want that to be taken into account by the compiler. Obviously, to
do this the compiler must know the clock frequency, and this clock
frequency must be fixed. And I want the compiler to give an error
message when the 5 us can not be met.

The above is the realy simple case, things get more interesting with for
instance code between the set-high and set-low, including if's and
limited loops, and with the set-low and set-high in a loop (in that
order!).

I am not saying this should be in the next version of C. I don't want to
donate a kidney yet :)

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\02\27@113736 by William Chops Westfield

face picon face
On Feb 27, 2006, at 7:39 AM, Wouter van Ooijen wrote:

> - make pin X high
> - 5 us later: make pin X low
>
The mythical "pulseout" instruction that is parallelized and
"multiply executed" (to take some high-end microprocessor terms
and misuse them) at the same time as other instructions, only
implemented in the compiler (if necessary) rather than the
processor itself.  Ie, you want the second instruction 'scheduled'
for the right spot in the future instruction scheme...

BillW

2006\02\27@120336 by Wouter van Ooijen

face picon face
>> - make pin X high
>> - 5 us later: make pin X low
>
> The mythical "pulseout" instruction that is parallelized and
> "multiply executed" (to take some high-end microprocessor terms
> and misuse them) at the same time as other instructions, only
> implemented in the compiler (if necessary) rather than the
> processor itself.  Ie, you want the second instruction 'scheduled'
> for the right spot in the future instruction scheme...

Hmmm, it seems you do not take me seriously :(

No. I want the compiler to make sure that a specified amount of time
elapses between two points in the code. This not exactly the same as an
exact pulse length on an output pin, but close enough to be usefull and
technically possible for a compiler to do - nothing mythical.

In code a simple case could be like this:

  time anchor x
  set( porta, 0, 1 )
  time since x is 5 us
  set( porta, 0, 0 )

The effect of the "time since x is 5 us" is a delay untill 5 us after
the x anchor. This 5 us must include the time spend in the call "set(
porta, 0, 1 )". This puts some limitations on that code.

The difference between this form of delay and a delay library is that it
(this form of delay) must take the other (inbetween) code into account.
And no, no timers please!

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\02\27@122554 by David VanHorn
picon face
>
>
> The effect of the "time since x is 5 us" is a delay untill 5 us after
> the x anchor. This 5 us must include the time spend in the call "set(
> porta, 0, 1 )". This puts some limitations on that code.


And what about interrupts?  Since code like that could have multiple
execution paths, you'd have to somehow adjust the pulse output according to
which path was taken, then we can try to deal with the case where the int
happens late enough that you can't finish the int before the required event.

This sounds like something that needs to be solved in hardware.
IIRC one of the motorola chips has something like 32 hardware timers.

2006\02\27@123253 by Walter Banks

picon face
Delay and do some action later rather than just delay by waiting and doing
nothing.


x = high;
delay_us(5);
x = low;

This is how most of our customers using delays.

I think what you are talking about is

x = high;
Later(5us,x=low);
. . .  Unrelated code that executes and the compiler interleaves the (x = low)


There is a second accounting that is needed as well, it is read and write
access often occurs on different execution cycles in an instruction. Instruction
selection is and issue, on many processors writes occur at different times
in the execution sequence if it is a simple write or a read modify write sequence..

w..


Wouter van Ooijen wrote:

{Quote hidden}

2006\02\27@125339 by Walter Banks

picon face
There are processors that have this type of instruction. The simplest implementation
output is pre scheduled on some combination of logical events. The events
can be complex or simple. Something like when the interrupt fires at the end of a
timer set or clear the bit.

The second approach I have seen is with a thread engine. Here we have multiple
parallel executing threads and some number of execution engines. Threads in the
one case I am familiar with are very much like interrupts with complex events
that triggers a start of execution. Most automotive engine controllers use this
approach for engine timing operations.

In PIC type execution current compilers probably can solve the straight line
code and multiple path (straight line with conditional branches) implementations.
As others have pointed out asynchronous interrupts are an issue. What is
solvable is the use of multiple processors for I/O operations. This can still be
a low cost solution with 8 bit devices each servicing 1 to 4 I/O pins.

w..


David VanHorn wrote:

{Quote hidden}

2006\02\27@133601 by Wouter van Ooijen

face picon face
> > The effect of the "time since x is 5 us" is a delay untill
> 5 us after
> > the x anchor. This 5 us must include the time spend in the
> call "set(
> > porta, 0, 1 )". This puts some limitations on that code.
>
> And what about interrupts?

This would probably be usefull only without interrupts. Think 12-bit
core PICs.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\02\27@150101 by Gerhard Fiedler

picon face
David VanHorn wrote:

>> The effect of the "time since x is 5 us" is a delay untill 5 us after
>> the x anchor. This 5 us must include the time spend in the call "set(
>> porta, 0, 1 )". This puts some limitations on that code.
>
> And what about interrupts?  

If you relax Wouter's requirement to a "at least 5 us" instead of "exactly
5 us", it becomes a bit less useful but still with some use. But possibly
not with enough use to justify the implementation...

I don't think an "exactly 5 us" makes a lot of sense, because it puts a lot
of constraints on the whole environment. No interrupts is probably the
strongest restriction. No function calls to linked-in functions (or you
have to have a linker that does this for you, or source code access to all
libraries) is another one.

Gerhard

2006\02\27@160116 by David VanHorn

picon face
On a larger scale, I've dealt with this problem in thermal printers and
systems that drive R/C servos.  The printer problem was the most
interesting.

Picture 13 outputs that all have to have slightly different turn-off points.
You start out with a maximum number of pixels that can be activated, and as
you add active outputs, you total up the number of active pixels till you
hit the limit, so you may have anywhere from 3 to 13 outputs.

Now, you compensate for wiring differences and other factors, and you end up
with 3-13 different burn pulse widths that need to be output.

Making this more fun, the voltage at the printhead needs to be measured
AFTER you start the burn pulse..

What I ended up with is a 100uS fixed burn, while the ADC is measuring the
voltage, and then while this is running, calculating the times needed for
the other burn pulses.  This ends up with an array of times to load into the
timer once it ints on the 100uS timeout, and an array of outputs to turn off
when those timer ints hit.

2006\02\27@164204 by Wouter van Ooijen

face picon face
> If you relax Wouter's requirement to a "at least 5 us"
> instead of "exactly 5 us", it becomes a bit less useful
> but still with some use.

But in that case a procedure call would be sufficient.

> I don't think an "exactly 5 us" makes a lot of sense, because
> it puts a lot of constraints on the whole environment.

But how else would you write a bit-banged UART in a HLL without using
timers?

> No function calls to linked-in
> functions (or you
> have to have a linker that does this for you, or source code
> access to all libraries) is another one.

I think separate compilation (in the C way, with only a stupid linker
after the compilations) is a bad thing. It makes too many nice
optimizations impossible, and clouds peoples minds as to what a compiler
could/should do for them.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\02\27@165832 by Timothy Weber

face picon face
Gerhard Fiedler wrote:
> I don't think an "exactly 5 us" makes a lot of sense, because it puts a lot
> of constraints on the whole environment. No interrupts is probably the
> strongest restriction.

That doesn't seem like an unreasonable constraint to me.  I was just
writing a 1-Wire interface in C recently, and the timing requirements
are tight.  So of course I had to disable interrupts while banging the
bits, but I also had to drop to inline assembly and/or look carefully at
what the compiler was producing in order to count microseconds.  With a
language feature like what Wouter's describing, it would have been simple.

Wouter, it doesn't sound like anyone's seen such a feature, but I think
your description of it seems pretty sensible to me.

In its most simple incarnation, I think you could implement it in C
preprocessor macros if you could just add a couple of custom #pragmas
like this:

----
// Raise RA2 for exactly 500 us.
intcon.GIE = 0;

porta.2 = 1;
#pragma time_critical_start

// Do some math or whatever in the meantime.
// The compiler takes care of ensuring each branch is constant time?
if (portc.3)
  foo++;
else {
  bar = 0;
  foo = 0;
}

#pragma time_critical_stop DELTA
  // sets DELTA macro to the offset between the current output
  // and when the time-critical section was started

delay_us((500 - DELTA) / INSTRUCTION_PERIOD);

porta.2 = 0;
intcon.GIE = 1;
----

This would only work with straight-line code, with interrupts disabled,
no function calls, etc.  But it would be very handy for doing this kind
of time-sensitive bit twiddling.  And, adding these two #pragmas seems
like it would be simple for the compiler author.

(Managing branches in between would be more challenging, and of course
so would allowing more complicated constructs, but some of that work
could be shifted to the compiler user with a few more options on the
#pragmas.)
--
Timothy J. Weber
http://timothyweber.org

2006\02\27@172229 by olin piclist

face picon face
Wouter van Ooijen wrote:
> But how else would you write a bit-banged UART in a HLL without using
> timers?

You don't.  That is clearly something that should be done in assembler.
I've done that and used assembly time looping and calculations to
automatically insert the right number of NOPs into the code at the right
places.  The macros and other logic did subtraction on address labels to get
the number of instructions and compensated to the desired delay with
additional NOPs.  This was on a 16C66 running at 160KHz, and output at 9600
baud worked very well.


******************************************************************
Embed Inc, Littleton Massachusetts, (978) 742-9014.  #1 PIC
consultant in 2004 program year.  http://www.embedinc.com/products

2006\02\27@192106 by Chen Xiao Fan

face
flavicon
face
> From: spam_OUTpiclist-bouncesTakeThisOuTspammit.edu
> [.....piclist-bouncesKILLspamspam@spam@mit.edu] On Behalf Of Walter Banks
>
> In the discussions on C standards for embedded systems delays
> only came up briefly and was seen as a library rather than
> language issue.
>
> What should be in a standardized embedded library?
>
> Ignoring exact syntax for a moment.
>

Perhaps none. Just look at HiTech PICC. HiTech PICC does not
provide most of the library you described. It does provide
those standard C libraries which are not very useful in many
PIC applications.

For example, the following three ports related libraries
will not be very useful in many cases due to the overhead.
Often it is better to write one's own libraries.

void initPORTwrite(port,output);
void writePORT(port,data);
char readPORT(port);

C18 is quite different. It provides many functions. However
often people need to write their own functions. The good
thing is that C18 provides the libraries sources even for the
free student versions.

Regards,
Xiaofan

2006\02\27@204554 by Gerhard Fiedler

picon face
Timothy Weber wrote:

{Quote hidden}

The problem here is that DELTA depends on the value read from portc.3,
unless you require the compiler to write code that has the same number of
cycles independently of the branch. (That's a problem with every such
implementation.)

Otherwise I like this pragma idea. It looks pretty straightforward. But the
code would look ugly for something like Wouter's original example :)

I tend to agree with Olin: if you want to bit-bang at the level of a few
instructions, go do it in assembler. If it's only a matter of a few
instructions, that should be possible even for a HLL junkie (like me). And
if it's more than a few instructions, it's a whole different ball game.

Gerhard

2006\02\27@210800 by Timothy Weber

face picon face
Gerhard Fiedler wrote:
> The problem here is that DELTA depends on the value read from portc.3,
> unless you require the compiler to write code that has the same number of
> cycles independently of the branch.

Right, that's what I think Wouter's suggesting, and I think it would be
a neat idea.

It just has to insert NOPs in the shorter branch.

> Otherwise I like this pragma idea. It looks pretty straightforward. But the
> code would look ugly for something like Wouter's original example :)

Yes, it would be simple for a basic block, and much more complicated for
branches, loops and all that stuff.

> I tend to agree with Olin: if you want to bit-bang at the level of a few
> instructions, go do it in assembler. If it's only a matter of a few
> instructions, that should be possible even for a HLL junkie (like me). And
> if it's more than a few instructions, it's a whole different ball game.

I agree - with the tools that are available now.

But, counting instructions - especially in the complicated cases - is
something that computers are very good at and that human beings are
notoriously bad at.  If this feature were available in your favorite HLL
compiler (and you were confident it had been fully tested, etc. - a big
if!), why wouldn't you use it?
--
Timothy J. Weber
http://timothyweber.org

2006\02\27@214445 by Chen Xiao Fan

face
flavicon
face


> -----Original Message-----
> From: piclist-bouncesspamKILLspammit.edu
> [.....piclist-bouncesKILLspamspam.....mit.edu] On Behalf Of Timothy Weber
>
> Gerhard Fiedler wrote:
> > The problem here is that DELTA depends on the value read
> from portc.3, unless you require the compiler to write code
> that has the  same number of cycles independently of the branch.
>
> It just has to insert NOPs in the shorter branch.
>
> But, counting instructions - especially in the complicated cases - is
> something that computers are very good at and that human beings are
> notoriously bad at.  If this feature were available in your
> favorite HLL compiler (and you were confident it had been fully
> tested,  etc. - a big if!), why wouldn't you use it?

That would be wonderful if it is at all possible.

I needed to count instructions for an asynchronous detection
firmware (to detect pulse for through-beam sensor: the emitter
and the receiver are in separate unit) so that all loops would
have the same number of cycles with all branching connections.

I used an Excel sheet for doing this. It was very troublesome
and error-prone. Luckily it was not very long and the branches
are not that many. I also tried to use simulator to help. This
was with PIC assembly so it was doable. With HLLs, it will
become much trickier.

Regards,
Xiaofan

2006\02\27@235610 by William Chops Westfield

face picon face

On Feb 27, 2006, at 9:01 AM, Wouter van Ooijen wrote:

>> The mythical "pulseout" instruction

> Hmmm, it seems you do not take me seriously :(
>

No, I meant "mythical" as in duplicating the pulseout "instruction"
of the Basic Stamp "language", where of course it's a function that
takes the full time specified to execute.  But if it could run in
parallel with the following code, it would be close to what you
want to do.  Except you probably want arbitrary actions at the
end of the time rather than just turning off a pin.

BillW

2006\02\28@011007 by Robert Ammerman

picon face
> The mythical "pulseout" instruction that is parallelized and
> "multiply executed" (to take some high-end microprocessor terms
> and misuse them) at the same time as other instructions, only
> implemented in the compiler (if necessary) rather than the
> processor itself.  Ie, you want the second instruction 'scheduled'
> for the right spot in the future instruction scheme...
>
> BillW

Sounds like an application for the Ubicom (SX) concept of virtual
peripherals to me.

Bob Ammerman
RAm Systems

2006\02\28@020225 by Wouter van Ooijen

face picon face
> No, I meant "mythical" as in duplicating the pulseout "instruction"
> of the Basic Stamp "language", where of course it's a function that
> takes the full time specified to execute.  But if it could run in
> parallel with the following code, it would be close to what you
> want to do.  Except you probably want arbitrary actions at the
> end of the time rather than just turning off a pin.

And I don't want to specify them in advance, I just want (in effect) to
specify a compiler-caculated delay (or in complicated cases: lots of
such delays to keep parts of the code isosynchronous).

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\02\28@020226 by Wouter van Ooijen

face picon face
> I used an Excel sheet for doing this. It was very troublesome
> and error-prone.

That words (troublesome and especially error-prone) are for me clear
indications of a good candicate HLL feature! (compare for instance to
bank setting elimination and static-statck allocation).

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\02\28@020227 by Wouter van Ooijen

face picon face
> Wouter, it doesn't sound like anyone's seen such a feature,
> but I think your description of it seems pretty sensible to me.

Glad you use that is can be usefull. But the description as I stated is
totally incomplete.

> In its most simple incarnation, I think you could implement it in C
> preprocessor macros if you could just add a couple of custom #pragmas

That is just the syntax. The devil is in defining the semantics.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\02\28@020227 by Wouter van Ooijen

face picon face
> > But how else would you write a bit-banged UART in a HLL
> without using
> > timers?
>
> You don't.  That is clearly something that should be done in
> assembler.

With the current compiler features, yes. So what you are in fact stating
is that it would be a good idea to add something like this to compilers,
to eliminate one more reason to drop down to assembler.

Note that doing this in assembler (without timers) has the same
restriction as in a HLL: no interrupts.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\02\28@080234 by Gerhard Fiedler

picon face
Wouter van Ooijen wrote:

>> In its most simple incarnation, I think you could implement it in C
>> preprocessor macros if you could just add a couple of custom #pragmas
>
> That is just the syntax. The devil is in defining the semantics.

Assuming a C/Pascal/Jal type language...

- We have start markers (only with an identifier) and interval markers
(with an identifier and a time). Markers with the same identifier are
associated with each other. If there is an execution path between two
markers with the same identifier (of which the second marker must be an
interval marker), the execution time between them gets adjusted to the time
specified with the later marker.

- The allowed scope is restricted to one function. All the markers
associated with each other have to be within one function. (That is, the
marker identifier has block scope.)

- The loop limits of loop constructs between markers must be known at
compile time. (For example, bit-banging routines that send out bits,
counting from 0 to 7 with 0 and 7 being defined as constants or literals,
would be allowed; loops with limits that come from function arguments would
not be allowed.)

- Possibly there may be function calls allowed in between the markers, but
in that case the compiler has to see the source and have control over the
execution times of the function calls. Every such function call would be
made isochronous. This means among others that no loops are allowed in such
functions with loop limits that are not known at compile time. This also
means that such functions would not run at their fastest possible execution
time in some of their branches, even when called from other places without
markers around them.

- If there are remaining ambiguities (not sure about this -- are there?),
this one may help. It may result in an ugly syntax, but maybe can be
simplified in steps until ambiguities appear. Markers are only allowed in
start/end pairs. Every pair has a unique identifier (to associate the end
marker with the start marker). The time associated with the pair is the
execution time between the start and end markers.


Does this (with or without the last rule) leave something undefined? Or is
it too restricted to make it useful?

Gerhard

2006\02\28@100728 by Walter Banks

picon face
I am not sure that I follow how writing your own libraries
would be better. Libraries supplied by the compiler from
are often implemented as macro's or inline code.

w..



Chen Xiao Fan wrote:

> For example, the following three ports related libraries
> will not be very useful in many cases due to the overhead.
> Often it is better to write one's own libraries.
>
>  void initPORTwrite(port,output);
>  void writePORT(port,data);
>  char readPORT(port);


2006\02\28@104411 by Timothy Weber

face picon face
Gerhard Fiedler wrote:
> - Possibly there may be function calls allowed in between the markers, but
> in that case the compiler has to see the source and have control over the
> execution times of the function calls. Every such function call would be
> made isochronous. This means among others that no loops are allowed in such
> functions with loop limits that are not known at compile time. This also
> means that such functions would not run at their fastest possible execution
> time in some of their branches, even when called from other places without
> markers around them.

One alternative (perhaps selectable for the project, or for the
function, or as part of an overall speed/space optimization switch)
might be to generate alternate versions of the function if it's called
both from an isochronous block and from a non-isochronous block, so the
latter will run full-speed.

> - If there are remaining ambiguities (not sure about this -- are there?),
> this one may help. It may result in an ugly syntax, but maybe can be
> simplified in steps until ambiguities appear. Markers are only allowed in
> start/end pairs. Every pair has a unique identifier (to associate the end
> marker with the start marker). The time associated with the pair is the
> execution time between the start and end markers.

And this rule should maybe also specify that marker pairs may not overlap.

> Does this (with or without the last rule) leave something undefined? Or is
> it too restricted to make it useful?

My feeling is that it's useful even with the last rule, and even leaving
out support for function calls (as a first pass) - just branches and
constant-iteration loops.

And I can't say it's completely defined, but I don't immediately see
gaping holes.
--
Timothy J. Weber
http://timothyweber.org

2006\02\28@180444 by Peter

picon face


> But how else would you write a bit-banged UART in a HLL without using
> timers?

Inline assembly ... C can do it.

Peter

2006\02\28@184105 by Walter Banks

picon face

Wouter van Ooijen wrote

> But how else would you write a bit-banged UART in a HLL without using
> timers?

Most of the C compilers can create very specific delays that account for
processor speed. If the delays are short usually by generating
NOP's and longer delays by some more complex function.

Compilers regularly make rational choices between inline and
called functions. Our delay routines account for the procedure
calls just as you would in asm.

In creating HLL tools including very low-level code the compiler
developer has the same restrictions that asm programmers
have but

the HLL tools can do some things better than asm tools. Chief
among these is accounting and data base knowledge about
what the program is doing. Changing processor speed may very
well be no more complex than changing a single define.

> I think separate compilation (in the C way, with only a stupid linker
> after the compilations) is a bad thing. It makes too many nice
> optimizations impossible, and clouds peoples minds as to what a compiler
> could/should do for them.

Very good point. Link editing is not C specific. There are linkers that
approach linking so the code generation only happens after the whole
application is available. Byte Craft's compilers including MPC
all call the code generation part of the compiler from the linker so
control and data flow information for the whole application can be
used in code generation.

This make a big difference.

Walter




'[PIC] accurate delay routines - Standard embedded '
2006\03\01@015644 by Wouter van Ooijen
face picon face
> Most of the C compilers can create very specific delays that
> account for processor speed.

But I don't know of any compiler that takes in-between instructions into
account.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\03\01@015645 by Wouter van Ooijen

face picon face
> > But how else would you write a bit-banged UART in a HLL
> without using
> > timers?
>
> Inline assembly ... C can do it.

In-line assembly is a way to combine HLL and assembly that is often more
convenient than using separate C and asm files. But it is not HLL. If
you disagree I'll rephrase: how do you do it in a portable way (one
source for PIC and an as-yet-undifined chip, but one that is supported
by the HLL)?

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\03\01@180540 by Peter

picon face

On Wed, 1 Mar 2006, Wouter van Ooijen wrote:

>>> But how else would you write a bit-banged UART in a HLL without
>>> using timers?
>>
>> Inline assembly ... C can do it.
>
> In-line assembly is a way to combine HLL and assembly that is often more
> convenient than using separate C and asm files. But it is not HLL. If
> you disagree I'll rephrase: how do you do it in a portable way (one
> source for PIC and an as-yet-undifined chip, but one that is supported
> by the HLL)?

// setup (can include setup file)

// define ONE
#define PIC_IMPLEMENTATION_A
// #define PIC_IMPLEMENTATION_B

// ****** Implementation start

// Function foo() does something
void foo(void) {
       unsigned char a, b = 2, c = 3;

// ****** PIC IMPLEMENTATION
#ifdef __PIC

#  ifdef PIC_IMPLEMENTATION_A
#  define _SECTION_FOO_SEEN
       --c; // C

       _asm

       movf        _b
       addwf        _c,w
       movwf        a

       _endasm;
#  endif

#  ifdef PIC_IMPLEMENTATION_B
#  define _SECTION_FOO_SEEN

       _asm

       movf        _c
       addwf        _b,w
       movwf        a

       _endasm;
#  endif

#endif

// ****** MCS51 implementation
#ifdef _MCS51
#define _SECTION_FOO_SEEN

       ++b; // C
       _asm

       mov        A, _c
       add        _b
       mov        _a, A

       _endasm;

#endif

// ****** PORTABLE C IMPLEMENTATION
#ifdef _POSIX
#define _SECTION_FOO_SEEN

       a = b * c; // pure C

#endif

} // foo()

...

#ifndef _SECTION_FOO_SEEN
#  error "Could not compile foo (_SECTION_FOO_SEEN undefined)"
#endif

Peter

2006\03\02@015012 by Wouter van Ooijen

face picon face
> > If
> > you disagree I'll rephrase: how do you do it in a portable way (one
> > source for PIC and an as-yet-undifined chip, but one that
> > is supported
> > by the HLL)?

> // setup (can include setup file)
> (snip the rest)

I don't see how your code handles an as-yet-undifined chip, it does only
PIC and 8051. It can of course be extended for another specific chip,
but it can't handle a new chip without additions/changes.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\03\02@024336 by William Chops Westfield

face picon face

On Mar 1, 2006, at 10:49 PM, Wouter van Ooijen wrote:

> I don't see how your code handles an as-yet-undifined chip

TI has some interesting timer-based schemes for implementing
uarts an the like on the low-end MSP430 micros, which are pretty
C-oriented.  Seems like it's pretty easy if you can handle
clock interrupts at a frequency significantly faster than your
even rate.  That wasn't common in the past, but it's becoming
so.  You end up arriving at "my RTOS features can do that with 100us
resolution, do you really want a whole new language primitive
to handle the few cases when you need faster than that?"

Are there any good HLLs for supporting virtual peripheral development
on the scenix CPUs?  That would have been a natural place for this
sort of thing to have been refined...

BillW

2006\03\02@033224 by Wouter van Ooijen

face picon face
> TI has some interesting timer-based schemes for implementing
> uarts an the like on the low-end MSP430 micros, which are pretty
> C-oriented.  Seems like it's pretty easy if you can handle
> clock interrupts at a frequency significantly faster than your
> even rate.  That wasn't common in the past, but it's becoming
> so.

yes, for the pripheral requirements of the past.

> You end up arriving at "my RTOS features can do that with 100us
> resolution, do you really want a whole new language primitive
> to handle the few cases when you need faster than that?"

yes

> Are there any good HLLs for supporting virtual peripheral development
> on the scenix CPUs?  That would have been a natural place for this
> sort of thing to have been refined...

no, because Scenix peripherals tend to be interrupt-based

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\03\02@074956 by Walter Banks

picon face
Byte Craft implemented a embedded library that has delay routines in it
(arguments in us ms ) This library has identical calling sequences for
several compilers. Because the delay is a compiler supported library
code written using the calling conventions is portable over diverse
architectures.

These are strictly delay libraries rather than interleaved delay and
executable code next event. the bigger issue in this thread is how to
generate delays automatically and still be able to use the cycles
for other work by the processor. There are two solutions turn off
interrupts or use timers (with or without interrupts) . Compilers could
track the instruction time, easy with straight line code and more
complex with when branches or loops are involved. It would
probably be trade-off between optimization and exact timing.

I agree with Wouter that as far as I know no C compilers have done
this for embedded systems.

w..
.



Wouter van Ooijen wrote:

> I don't see how your code handles an as-yet-undefined chip, it does only
> PIC and 8051. It can of course be extended for another specific chip,
> but it can't handle a new chip without additions/changes.


2006\03\02@090552 by Wouter van Ooijen

face picon face
> > I don't see how your code handles an as-yet-undefined chip,
> it does only
> > PIC and 8051. It can of course be extended for another
> specific chip,
> > but it can't handle a new chip without additions/changes.
>
> Byte Craft implemented a embedded library that has delay
> routines in it (arguments in us ms ) This library has
> identical calling sequences for
> several compilers.

That's nice when the delay is large wrt. the time taken by 'inbetween'
operations and/or by the I/O operations itself.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\03\02@144701 by Peter

picon face

On Thu, 2 Mar 2006, Wouter van Ooijen wrote:

>>> If you disagree I'll rephrase: how do you do it in a portable way
>>> (one source for PIC and an as-yet-undifined chip, but one that is
>>> supported by the HLL)?
>
>> // setup (can include setup file)
>> (snip the rest)
>
> I don't see how your code handles an as-yet-undifined chip, it does only
> PIC and 8051. It can of course be extended for another specific chip,
> but it can't handle a new chip without additions/changes.

It does PIC 8051 and *POSIX*. That is plain C. Not only that but if the
#ifdef setup is done right (as I try to) then the program can be
compiled and run even on a mainframe (using only the C implementations).

When you get an 'unsupported' chip then the POSIX implementation will
necessarily run (subject to the compiler being compatible). After that,
the implementation can be adapted and a more optimal code generated for
that CPU. That will appear as another #ifdef section with assembly (or
whatever) for that CPU.

Peter

2006\03\02@161311 by Wouter van Ooijen

face picon face
> It does PIC 8051 and *POSIX*. That is plain C.

yeah, but that doesn't give you a way to do timing in the order of 1's
to 10's of instructions. Fine for 1000's of instructions, maybe for
100's.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


More... (looser matching)
- Last day of these posts
- In 2006 , 2007 only
- Today
- New search...