RetroBSD

2.11BSD operating system for microcontrollers
It is currently Thu Dec 14, 2017 5:12 pm

All times are UTC




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Thu Sep 29, 2016 4:35 pm 
Contributor
User avatar

Joined: Thu Nov 08, 2012 7:04 am
Posts: 2400
Location: Rapa Nui
Because of a significant "brain trust" [British: a group of experts who give impromptu answers to questions in front of an audience or on the radio; US: a group of experts appointed to advise a government or politician; Urban Dict: a group of smart advisors. Used sarcastically to refer to a bunch of decision makers who are not wise] existing behind the retro scene (currently resting, waiting on pic32mzda), I dare myself to ask for a help of any kind (except pointing me to K&R book :lol: ).

I have about 2kB free space :) and looking for an "femto readline parser" called from my C source (not from an OS), which will:

1. read a line with a command and up to say 4 params
2. command - up to 3 chars like: ou, in, pr, lop; number of commands will be small
3. params - up to 4 numbers
4. numbers - hex32bit ie xDEADBEAF or shorter, decimal signed 32bit (cannot use scanf)
5. I will then, based on the command, make some actions with params
6. All I have is a function readchar(*buf, numberofchars) which reads numberofchars from uart into a char buf[], which does not help me much here, fortunately I can read 1 char too :)
7. cannot use heavy lib functions as they do not fit.

Example:
ou 3 x347f
in 2 8
tm 4 50000
lop 1 100 x4e3fddaa -1234567890

Is that doable in such small footprint in pure C?
P.

_________________
Pukao Hats Cleaning Services Ltd.


Top
 Profile  
 
PostPosted: Thu Sep 29, 2016 8:51 pm 
Contributor
User avatar

Joined: Thu Nov 08, 2012 7:04 am
Posts: 2400
Location: Rapa Nui
For example a splitter from stackoverflow:
Code:
// A splitter with delimiters
// http://stackoverflow.com/questions/9210528/split-string-with-delimiters-in-c
int dtmsplit(char *str, const char *delim, char ***array, int *length ) {
  int i=0;
  char *token;
  char **res = (char **) malloc(0 * sizeof(char *));

  /* get the first token */
   token = strtok(str, delim);
   while( token != NULL )
   {
        res = (char **) realloc(res, (i + 1) * sizeof(char *));
        res[i] = token;
        i++;
      token = strtok(NULL, delim);
   }
   *array = res;
   *length = i;
  return 1;
}

// my simple dirty readline
u32 readline (void) {
   u32 i = 0;
   u32 numc;
   u8 data[1];
   while(1) {
      while ((numc = XIOModule_Recv(&iomodule, data, 1)) == 0);
      line[i] = data[0];
      if ((line[i] == '\n') || (i == 79)) break;
      i++;
   }
   line[i] = 0;
   return i;
}


It works but dtmsplit() takes 10kB (without actual conversion to commands and params/numbers):
Code:
    int i;
    int c = 0;
    char **arr = NULL;
    int count =0;
    c = dtmsplit(line, " ,;./", &arr, &count);
    xil_printf("Found %d tokens.\n\r", count);
    for (i = 0; i < count; i++)
    xil_printf("string #%d: %s\n\r", i, arr[i]);

Code:
Keybo = Yee , 44555 34343 54545 5656 -1211 x3434 , 333/444/555.666 777.888
Found 13 tokens.
string #0: Yee
string #1: 44555
string #2: 34343
string #3: 54545
string #4: 5656
string #5: -1211
string #6: x3434
string #7: 333
string #8: 444
string #9: 555
string #10: 666
string #11: 777
string #12: 888

Also using malloc and realloc with an mcu .. :?
I'll make a fixed arg strings - ie. 5x 10bytes - for command and 4 numbers, so no need for malloc/realloc then..

_________________
Pukao Hats Cleaning Services Ltd.


Top
 Profile  
 
PostPosted: Fri Sep 30, 2016 8:44 am 
Contributor
User avatar

Joined: Thu Nov 08, 2012 7:04 am
Posts: 2400
Location: Rapa Nui
Removing malloc and realloc shaved off 3kB only :(
strtok() is large..
Code:
// Pito has removed malloc and realloc
int dtmsplit(char *str, int *length) {
  int i=0;
  char *token;

  /* get the first token */
   token = strtok(str, " ");
   while( (token != NULL) && ( i <= maxntokens) )
   {
      param[i]   = token;
      i++;
      token = strtok(NULL, " ");
   }
   *length = i;
  return 1;
}

_________________
Pukao Hats Cleaning Services Ltd.


Top
 Profile  
 
PostPosted: Fri Sep 30, 2016 9:28 am 
Contributor
User avatar

Joined: Thu Nov 08, 2012 7:04 am
Posts: 2400
Location: Rapa Nui
My new toy :)
16bits signed Q2.13 Phase in and Q1.14 Sin and Cos out, 2clocks per result they say :)
Code:
Start CORDIC ?? [Yes From To Nsteps (in microrads)]
Yes -2000000 2000000 20
Keybo = Yes -2000000 2000000 20
Found 4 tokens.
string #0: Yes
string #1: -2000000
string #2: 2000000
string #3: 20
-2000000 , -909362 , -416137
-1800000 , -973876 , -227172
-1600000 , -999572 , -29174
-1400000 , -985473 , 170104
-1200000 , -932067 , 362365
-1000000 , -841491 , 540344
-800000 , -717346 , 696716
-600000 , -564697 , 825317
-400000 , -389343 , 921081
-200000 , -198669 , 980041
0 , -61 , 1000000
200000 , 198608 , 980041
400000 , 389282 , 921081
600000 , 564636 , 825317
800000 , 717285 , 696716
1000000 , 841491 , 540222
1200000 , 932006 , 362365
1400000 , 985412 , 170104
1600000 , 999511 , -29174
1800000 , 973815 , -227172
2000000 , 909240 , -416137

Start CORDIC ?? [Yes From To Nsteps (in microrads)]

You can hardly circumnavigate around the globe with that precision, but it is fast..
Attachment:
Errors Cordic 16bit on Xilinx.PNG
Errors Cordic 16bit on Xilinx.PNG [ 101.07 KiB | Viewed 12934 times ]


I must admit the Xilinx'es tools are so easy to use today.. And it simply works.
I wish the bigger chips (Artix, Kintex) will get available cheap soon :P
Retrobsd/LiteBSD on Spartan6 SLX9 is still doable I guess - uBlaze + MMU + SDRAM/DDR,
but the chip will be most probably full.. Btw, do we have a uBlaze simulator handy :?:

_________________
Pukao Hats Cleaning Services Ltd.


Top
 Profile  
 
PostPosted: Fri Sep 30, 2016 1:11 pm 
Committer
User avatar

Joined: Thu Oct 11, 2012 8:45 am
Posts: 1801
Location: Room 217, Floor 8, Arm 8, Wheel S7, Mars Base Alpha 3
You want to do it with a simple FSM instead of manipulating a buffer. I'm sure that would be simpler and use less code than string manipulation.

If you have specific characters that each byte of a command can be you could then pack them into a byte or word.

For instance:

"o" in the first byte is 0x0001
"i" in the first byte is 0x0002
"t" in the first byte is 0x0003
"l" in the first byte is 0x0004

"u" in the second byte is 0x0010
"n" in the second byte is 0x0020
"m" in the second byte is 0x0030
"o" in the second byte is 0x0040

"p" in the third byte is 0x0100

You then have numeric commands of

ou = 0x0011
in = 0x0022
tm = 0x0033
lop = 0x0144

And unlisted, but potential:

to = 0x0034
im = 0x0023
top = 0x0143

Simpler if you can restrict it all to exactly 2 character commands. That would reduce your processing by a third.

Just read a character at a time and decide what to do with that character depending on what has gone before (how many characters have been read). If it's a space or EOL then do whatever the command tells you. Otherwise you place the numeric equivalent for the character (a small LUT or switch statement) in the right location in the word (just OR it).

The reason for working numerically like that is so that the final decision is:

if (command == 0x11) { .. whatever ... }

instead of complex things like:

if (!strcmp(cmd, "ou")) { ... whatever ...}

or:

if ((cmd[0] == 'o') && (cmd[1] == 'u')) { ... whatever ...}

Processing the numbers can be done in a similar way by reading each character and multiplying by powers of the selected base and adding them to the running total for that number. Multiply itself can be a little costly, so if you can force just hexadecimal it gets much lighter, since you can just use left shifts and ORs for building up the finished number.

_________________
Why not visit my shop? http://majenko.co.uk/catalog
Universal IDE: http://uecide.org
"I was trying to find out if it was possible to only eat one Jaffa Cake. I had to abandon the experiment because I ran out of Jaffa Cakes".


Top
 Profile  
 
PostPosted: Fri Sep 30, 2016 1:55 pm 
Contributor
User avatar

Joined: Thu Nov 08, 2012 7:04 am
Posts: 2400
Location: Rapa Nui
Interesting, thanks. I run currently single core, but plan 2 or more.
There is 8/16/32/64kB per core selectable (mem = rom and ram), total 64kB in my LX9.
I target 16kB, now I am at 27kB with the code, it works as I set core mem to 32kB.
Without the splitter and conversions (simple atoi and long long mul/div/add/sub - mimicking float range) my code is about 13kB.
Still the big chunk there (in 13kB) is the special xil_printf() which is quite large even it is stripped down.
20y back I packed something similar with single precison fp into a 16f88, but that was long time back :)
I do not want mess with that mcu inside too much as that is not my goal, I want use it as a simple connectivity towards internal blackboxes (ie the above cordic box) and other fabric I simply bitbang via a configurable 4x input and 4x output ports (each of them 1..32bit wide). It works..

_________________
Pukao Hats Cleaning Services Ltd.


Top
 Profile  
 
PostPosted: Fri Sep 30, 2016 2:14 pm 
Committer
User avatar

Joined: Thu Oct 11, 2012 8:45 am
Posts: 1801
Location: Room 217, Floor 8, Arm 8, Wheel S7, Mars Base Alpha 3
16F88? Ooooh, la-di-da ;)

My first PIC experience was with the 16F84A since that is all that Maplins had in stock locally ;)

I had to bit-bang all my UART comms, and I only had 1024 words of flash and 68 bytes of RAM to do it in ;)

_________________
Why not visit my shop? http://majenko.co.uk/catalog
Universal IDE: http://uecide.org
"I was trying to find out if it was possible to only eat one Jaffa Cake. I had to abandon the experiment because I ran out of Jaffa Cakes".


Top
 Profile  
 
PostPosted: Fri Sep 30, 2016 2:23 pm 
Contributor
User avatar

Joined: Thu Nov 08, 2012 7:04 am
Posts: 2400
Location: Rapa Nui
Hehe, 16f88 was a big advanced machine. My first pic was the basic stamp - the smallest one with a header at single side, it cost me 35E. 15y before basic stamp I built an 8085 system, it cost me less (btw parts purchased in London, '82, the catalogues at that time were aprox 10cm long adds with a list of 20 components in electronics magazines).
Attachment:
basicstamp1.JPG
basicstamp1.JPG [ 15.04 KiB | Viewed 12924 times ]

_________________
Pukao Hats Cleaning Services Ltd.


Top
 Profile  
 
PostPosted: Fri Sep 30, 2016 2:31 pm 
Committer
User avatar

Joined: Thu Oct 11, 2012 8:45 am
Posts: 1801
Location: Room 217, Floor 8, Arm 8, Wheel S7, Mars Base Alpha 3
25 bytes of RAM is a bit excessive, isn't it? Couldn't you make do with a RAM-less chip and just use the CPU's registers?

_________________
Why not visit my shop? http://majenko.co.uk/catalog
Universal IDE: http://uecide.org
"I was trying to find out if it was possible to only eat one Jaffa Cake. I had to abandon the experiment because I ran out of Jaffa Cakes".


Top
 Profile  
 
PostPosted: Sat Oct 01, 2016 5:27 pm 
Contributor
User avatar

Joined: Thu Nov 08, 2012 7:04 am
Posts: 2400
Location: Rapa Nui
20bit Cordic - much better result..
BTW I spent 6 (six) hours debugging my code and hw, finally I found the -Os mb-gcc optimization (ISE SDK 14.7) is causing 64bit mult starts shoot wrong results (does Xilinx know about :evil: ???)
Attachment:
Cordic 20bit.JPG
Cordic 20bit.JPG [ 82.87 KiB | Viewed 12881 times ]

_________________
Pukao Hats Cleaning Services Ltd.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC


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 post attachments in this forum

Search for:
cron




Powered by phpBB® Forum Software © phpBB Group

BSD Daemon used with permission