Static Array

86 views
Skip to first unread message

Mike Jones

unread,
Oct 5, 2015, 9:14:56 PM10/5/15
to ats-lang-users
I need a hint...

I need a 256 byte lookup table for a CRC routine. The table, probably and array, needs to be static and in .text, of an Arduino elf file, thus read only, and not copied to .data.

The look up needs to be based on an index (pointer) so that it is very fast, as in I am measuring the algorithm in us. The preferred programming context is simply to pass an index to a function and get a byte back.

Is there an array in the libraries I can do this with? Preferably the answer is not, use C, unless there is no simple alternative.

Also, is there some documentation on the list/arrays in the library beyond html that just points to code? Like a tutorial beyond the examples that walks through each version of these explaining how to use them from an application writer point of view?

gmhwxi

unread,
Oct 5, 2015, 10:24:43 PM10/5/15
to ats-lang-users
In the past, I implemented some data structures that are statically allocated:

https://github.com/githwxi/ATS-Postiats-contrib/tree/master/contrib/libats-/hwxi/globals/HATS

For instance, gdeqarray is a statically allocated double-ended queue (deque). The code is a bit
difficult to access due to lack of documentation. I would say that going back to C is quite a sensible
approach here. Essentially you just need a function of the following interface:

fun lookup(index: natLt(256)): uint8

While you can indeed implement such a function safely in ATS, it may not be worth your time :)

Mike Jones

unread,
Oct 5, 2015, 10:43:22 PM10/5/15
to ats-lang-users
Hm, this points out that for embedded work, the community may need to develop a library of statically allocated things.

However, an alternative might be to to allocate static structures in main, and pass them around in a state object, for programs that are small. So this might work in my case.

So if I want a fixed array I pass around with my state, what do you suggest?

When I poked around, there were pointer lists, reference lists... but it was not clear if any of these would allocate on the stack rather than the heap.

gmhwxi

unread,
Oct 5, 2015, 11:18:26 PM10/5/15
to ats-lang-users

Following is a simple way to get a statically allocated array for use in ATS:

//
%{^
#define N 10
int theArray[N] =
{
 
0,1,2,3,4,5,6,7,8,9
} ;
%} // end of [%{^]
#define N 10
macdef theArray
=
  $extval
(arrayref(int,N),"theArray")
//

You can find some related code in:

https://github.com/githwxi/ATS-Postiats-contrib/blob/master/contrib/arduino/TEST/QueenPuzzle


>>When I poked around, there were pointer lists, reference lists... but it was not clear if any of these would allocate on the stack rather than the heap.

Library code for ATS2 often allows the user to choose how memory is allocated. While this sounds good, I have to say that doing so requires that the
user have gained very good understanding of the library code in actual use.

Mike Jones

unread,
Oct 6, 2015, 11:37:30 PM10/6/15
to ats-lang-users
I tried to compile Blink before compiling this example, and ran into a problem and have to ask a newbie question.

In Blink.dats is:

#include
"{$ARDUINO}/staloadall.hats"

Compiling fails to find the file. So I did an export ARDUINO=path to parent dir, and still no luck.

I'm not sure if the variable is supposed to be defined in the make system, env, or if it is some macro like stadef macros.

I'm on Ubuntu. 

Any hints on what defines this variable?

Mike Jones

unread,
Oct 7, 2015, 12:42:38 AM10/7/15
to ats-lang-users
It never occurred to me that a boxed type could simply be assigned to external data. I guess it makes sense, as a boxed type is just a pointer. Given that, I think I agree that it is just find to make statics in C. What I did is:

%{^
const uint8_t crcLookupTable[256] PROGMEM  = { 0, 7, 14, 9, 28, 27, 18, 21,
                                       56, 63, 54, 49, 36, 35, 42, 45,
                                       112, 119, 126, 121, 108, 107, 98, 101,
                                       72, 79, 70, 65, 84, 83, 90, 93,
                                       224, 231, 238, 233, 252, 251, 242, 245,
                                       216, 223, 214, 209, 196, 195, 202, 205,
                                       144, 151, 158, 153, 140, 139, 130, 133,
                                       168, 175, 166, 161, 180, 179, 186, 189,
                                       199, 192, 201, 206, 219, 220, 213, 210,
                                       255, 248, 241, 246, 227, 228, 237, 234,
                                       183, 176, 185, 190, 171, 172, 165, 162,
                                       143, 136, 129, 134, 147, 148, 157, 154,
                                       39, 32, 41, 46, 59, 60, 53, 50,
                                       31, 24, 17, 22, 3, 4, 13, 10,
                                       87, 80, 89, 94, 75, 76, 69, 66,
                                       111, 104, 97, 102, 115, 116, 125, 122,
                                       137, 142, 135, 128, 149, 146, 155, 156,
                                       177, 182, 191, 184, 173, 170, 163, 164,
                                       249, 254, 247, 240, 229, 226, 235, 236,
                                       193, 198, 207, 200, 221, 218, 211, 212,
                                       105, 110, 103, 96, 117, 114, 123, 124,
                                       81, 86, 95, 88, 77, 74, 67, 68,
                                       25, 30, 23, 16, 5, 2, 11, 12,
                                       33, 38, 47, 40, 61, 58, 51, 52,
                                       78, 73, 64, 71, 82, 85, 92, 91,
                                       118, 113, 120, 127, 106, 109, 100, 99,
                                       62, 57, 48, 55, 34, 37, 44, 43,
                                       6, 1, 8, 15, 26, 29, 20, 19,
                                       174, 169, 160, 167, 178, 181, 188, 187,
                                       150, 145, 152, 159, 138, 141, 132, 131,
                                       222, 217, 208, 215, 194, 197, 204, 203,
                                       230, 225, 232, 239, 250, 253, 244, 243
                                     };

%}
macdef crcLookupTable =
  $extval(arrayref(uint8,256),"crcLookupTable")

var-size -C -x main.elf 

confirms that the array is in .text where it belongs, due to using PROGMEM.

It is typical in Arduino programming to use the F macro for strings like Serial.print(F("Foo")); And this ends up in PROGMEM.

Can an ATS macro bury c code in it? Something like:

macdef F(s,nm) = %{^ const char* ,(nm) PROGMEM = ,(s) %} macdef ,(s) $extval(char*,",(s)")


But, have nm, the name, be taken care of so you can simple use F("Bar") and have it generate the c code and ats macro.

The F macro is a big help keeping RAM usage down on an Arduino.


On Monday, October 5, 2015 at 9:18:26 PM UTC-6, gmhwxi wrote:

gmhwxi

unread,
Oct 7, 2015, 7:46:32 AM10/7/15
to ats-lang-users

You need:

1. ATS2-contrib: see the installation page.
2. You need the following line:

#include "share/atspre_define.hats"

$ARDUINO is defined in the above file; it is not an environment variable.

gmhwxi

unread,
Oct 7, 2015, 8:38:06 AM10/7/15
to ats-lang-users
For now, ATS does not parse C code. So ATS macros cannot make
direct use of C code. For F macro, you could do something like:
                                                                                                                                               
extern
fun
FLASH{n:int}(string(n)): string(n) = "mac#F"

val () = println! (FLASH("Hello, world!")) // it should work!

Mike Jones

unread,
Oct 7, 2015, 10:57:39 AM10/7/15
to ats-lang-users
I'm having trouble getting this to compile. I guessed from the compiler message that in (uint8,256) the 256 defines a type g0uint, and that it needs a kind, so I tried to use int_kind. I noticed your examples use pos, which I think is a sort.

I'm confused about the kind vs. sort thing in general,

Can you explain how to pass in a uint8 and transform it such that it can be used by the arrayref, and perhaps clarify the kind/sort thing so I can self help later?


macdef crcLookupTable =
  $extval(arrayref(uint8,256),"crcLookupTable")

fun pec_add (old: uint8, new: uint8): uint8 = 
  let
    val a = uint8_bit_xor(old, new)
    val b = cast{g0uint(int_kind)}(a)
  in
    crcLookupTable[b]
  end

/home/mike/linti/linti-avr/DATS/main.dats: 3773(line=82, offs=5) -- 3790(line=82, offs=22): error(3): the symbol [[]] cannot be resolved as no match is found.
/home/mike/linti/linti-avr/DATS/main.dats: 3773(line=82, offs=5) -- 3790(line=82, offs=22): error(3): the dynamic expression cannot be assigned the type [S2Eapp(S2Ecst(g0uint_t0ype); S2Eextkind(atstype_uint8))].
/home/mike/linti/linti-avr/DATS/main.dats: 3773(line=82, offs=5) -- 3790(line=82, offs=22): error(3): mismatch of static terms (tyleq):
The actual term is: S2Eerr()
The needed term is: S2Eapp(S2Ecst(g0uint_t0ype); S2Eextkind(atstype_uint8))

gmhwxi

unread,
Oct 7, 2015, 11:53:49 AM10/7/15
to ats-lang-users

This is the kind of code you would need:

staload
UN
= "prelude/SATS/unsafe.sats"


macdef crcLookupTable
=
  $extval
(arrayref(uint8,256),"crcLookupTable")

fun
pec_add
(
  old
: uint8, new: uint8
) : uint8 = let
  val a
= old lxor new
  val b
= $UN.cast{natLt(256)}(a)
in
  crcLookupTable
[b]
end

gmhwxi

unread,
Oct 7, 2015, 1:10:18 PM10/7/15
to ats-lang-users

Turning pec_add into a template is the right way to go:

extern

fun
{}
pec_add
(
  old
: uint8, new: uint8
) :
uint8

implement
{}
pec_add
 
(old, new) = let
  val a
= old lxor new

  val b
= $UN.cast{natLt(256)}(a)
in
  crcLookupTable
[b]
end

Mike Jones

unread,
Oct 7, 2015, 3:41:27 PM10/7/15
to ats-lang-users
What is the value of a template if there are no parameters?
I can see the value of splitting interface from the implementation if I move the code to a sats/dats, but not sure what the template adds.

gmhwxi

unread,
Oct 7, 2015, 4:00:30 PM10/7/15
to ats-lang-users

After ATS compilation, the code for each instance of a template is contained
in the same file where the instance is called. So inlining can be readily performed
during a subsequent C compilation.

Mike Jones

unread,
Oct 7, 2015, 11:46:12 PM10/7/15
to ats-lang-users
Is there any reason this can't be a macro? I get all kinds of errors. If I stop off $extval, uint8, etc, eventually it will compile. I'v tried spaces in various places, etc.

macdef theArray (x) =
  $extval(arrayref(uint8, ,(x)),"theArray")


/home/mike/linti/linti-avr/DATS/main.dats: 3588(line=73, offs=27) -- 3590(line=73, offs=29): error(parsing): the syntactic entity [s0exp] is needed.
/home/mike/linti/linti-avr/DATS/main.dats: 3586(line=73, offs=25) -- 3587(line=73, offs=26): error(parsing): the keyword ')' is needed.
/home/mike/linti/linti-avr/DATS/main.dats: 3580(line=73, offs=19) -- 3581(line=73, offs=20): error(parsing): the keyword [,] is needed.
/home/mike/linti/linti-avr/DATS/main.dats: 3564(line=73, offs=3) -- 3571(line=73, offs=10): error(parsing): the syntactic entity [d0exp] is needed.
/home/mike/linti/linti-avr/DATS/main.dats: 3534(line=72, offs=1) -- 3540(line=72, offs=7): error(parsing): the token is discarded.
exit(ATS): uncaught exception: _2home_2hwxi_2Research_2ATS_2dPostiats_2src_2pats_error_2esats__FatalErrorExn(1025)

Hongwei Xi

unread,
Oct 7, 2015, 11:56:17 PM10/7/15
to ats-lan...@googlegroups.com


macdef currently does not support substitution inside a type. In your example, 'x' is part of a type.

--
You received this message because you are subscribed to the Google Groups "ats-lang-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-user...@googlegroups.com.
To post to this group, send email to ats-lan...@googlegroups.com.
Visit this group at http://groups.google.com/group/ats-lang-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/ats-lang-users/9d384d48-6fd0-4fc3-865c-8464422ab61e%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages