It is currently Wed Jul 06, 2011 8:20 pm

All times are UTC - 8 hours




 Page 1 of 1 [ 7 posts ] 
Author Message
 Post subject: Code size woes
PostPosted: Fri Mar 11, 2011 9:18 am 

Joined: Sat Feb 19, 2011 3:34 pm
Posts: 5
Location: Mountain View, CA
I'm now bumping up against the code size limit every time I try to add any new code, and have had to comment out all my basic notification code to finish the other stuff I'm working on. Is there any hope for more space in the future, or should I focus on getting more work to happen phone/computer side and try to use the watch as a dumb display?

Also, I'm trying to do a bunch of sun/moon/rise/set calculations that might be a bunch more code, but could just as easily use a lookup table in the resources, but there doesn't seem to be an easy way to read anything but images and fonts from resources. Even simple data file access would suffice.

Thoughts, suggestions?


Offline
 Profile  
 
 Post subject: Re: Code size woes
PostPosted: Fri Mar 11, 2011 11:16 am 
User avatar

Joined: Mon Feb 14, 2011 7:07 pm
Posts: 172
I'd recommend crunching as much data as possible on the phone/laptop side.

We'll be working on increasing available code size, but it's a tough problem. Does anyone have any experience with paging binary executable out of external memory and having it run on a microcontroller?



_________________
---

Lead designer of inPulse
Offline
 Profile  
 
 Post subject: Re: Code size woes
PostPosted: Fri Mar 11, 2011 9:48 pm 

Joined: Sat Feb 19, 2011 3:34 pm
Posts: 5
Location: Mountain View, CA
OK :)

And what about the possibility of putting stuff like data/tables/strings in the resources segment with some sort of lookup function. Would that be feasible?


Offline
 Profile  
 
 Post subject: Re: Code size woes
PostPosted: Sat Mar 12, 2011 1:04 am 
User avatar

Joined: Mon Feb 14, 2011 7:07 pm
Posts: 172
Yes, definitely! Do you want to post what you have and we can hack out an api for that? It will most likely be stored as a resource, and accessed in a similar way to an image.



_________________
---

Lead designer of inPulse
Offline
 Profile  
 
 Post subject: Re: Code size woes
PostPosted: Sat Mar 12, 2011 8:09 pm 

Joined: Sat Feb 19, 2011 3:34 pm
Posts: 5
Location: Mountain View, CA
For my purposes, I'm gonna have a table like this:


Jan. Feb. Mar. Apr. May June
Day Rise Set Rise Set Rise Set Rise Set Rise Set Rise Set
h m h m h m h m h m h m h m h m h m h m h m h m
01 0723 1701 0712 1733 0640 1802 0554 1831 0514 1858 0449 1924
02 0723 1702 0711 1734 0639 1803 0553 1832 0513 1859 0449 1924
03 0723 1703 0710 1735 0637 1804 0551 1833 0511 1900 0449 1925
04 0723 1704 0709 1736 0636 1805 0550 1834 0510 1901 0448 1926
05 0723 1705 0708 1737 0634 1806 0548 1835 0509 1902 0448 1926
06 0723 1706 0707 1738 0633 1807 0547 1836 0508 1903 0448 1927
07 0723 1706 0706 1739 0632 1808 0545 1837 0507 1904 0448 1927
08 0723 1707 0705 1740 0630 1809 0544 1837 0506 1904 0448 1928

* My hope was that I can basically have a data file where I can ask to read 4 bytes from (((month * 31) + day) * 4), turn that into a time.
I expect this would be optimal from a speed perspective, since reading the entire file into memory may be infeasible. The basics of open file, seek and read may be sufficient for this. I'll probably have moon phase and a few other things encoded in the same way. My C is rusty, but I'm assuming I can define a struct and use sizeof and some other calculations to extract what is effectively a record from a data file.

Other things that I find myself doing:

char *types_text[12] = {"mail", "sms", "cal", "phone", "cal", "cal", "bbm", "alarm", "all"};
char *hours_text[12] = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve"};
char *minutes_format[14] = {"%s\no'clock", "just\nafter\n%s","five\npast\n%s","ten\npast\n%s","quarter\npast\n%s","twenty\npast\n%s","twentyfive\npast\n%s","half\npast\n%s","twentyfive\nto\n%s","twenty\nto\n%s","quarter\nto\n%s","ten\nto\n%s","five\nto\n%s","almost\n%s"};
int minutes_advance_index = 7;

* I know these don't add too much to the code size, but it might be nice to have text files be readable in (either as a blob with newlines or an array) to avoid having to waste it on code.


* While I'm making demands, one last request: PNG support! I want 24 bit alpha for my sun and moon images:)


Offline
 Profile  
 
 Post subject: Re: Code size woes
PostPosted: Sun Mar 13, 2011 4:25 am 

Joined: Sun Feb 27, 2011 11:32 am
Posts: 71
You can save on RAM footprint if you replace:
// test0.c
char *types_text[12] = {"mail", "sms", "cal", "phone", "cal", "cal", "bbm", "alarm", "all"};

with one of these options:
// test1.c
const char * const types_text[] = {"mail", "sms", "cal", "phone", "cal", "cal", "bbm", "alarm", "all"};

// test2.c
const char types_text[][6] = {"mail", "sms", "cal", "phone", "cal", "cal", "bbm", "alarm", "all"};

// test3. c
const char types_text[] = "mail" "\0" "sms" "\0" "phone" "\0" "cal" "\0" "bbm" "\0" "alarm" "\0" "all";
const unsigned char types_offset[] = { 0, 5, 15, 9, 15, 15, 19, 23, 29 };


The first change allows the compiler to keep text_types in the read-only section so that it doesn't take space in both the text and data segments, as well as sizes the array automatically; you have 12 pointer slots allocated, at 4 bytes per slot, but are only using 9 of them. Also note that the array is of type "const char * const" so that both the strings are constant and the pointers are immutable. (I'm surprised that arm-gcc doesn't warn about the type error in test0.c: "mail" is of type const char *, but the array is of char *)

You can save a few more bytes in this particular case since the words are all similar in size with the third change. This avoids the need to have the array of pointers, which can be costly if there are many elements, but quite wasteful if the sizes of the elements vary too much.

There are a few more bytes to be saved (ten more in this case, for a total of 1/2 the size of the original version), if you store all of the strings as a single literal and then a const uint8_t table of offsets from the start of the string. Essentially creating the pointer lookup table by hand. I don't see an easy way to automate that process, which makes it much less attractive. The repeated string "cal" is reused three times, which is something the compiler had already done in the previous three versions.

/tmp: arm-elf-size test*.o
   text      data       bss       dec       hex   filename
     40        48         0        88        58   test0.o
     76         0         0        76        4c   test1.o
     54         0         0        54        36   test2.o
     44         0         0        44        2c   test3.o


Offline
 Profile  
 
 Post subject: Re: Code size woes
PostPosted: Tue Apr 05, 2011 7:51 pm 

Joined: Tue Feb 22, 2011 11:57 am
Posts: 3
I don't think the C preprocessor or compiler could generate the offset list but any number of more powerful tools (e.g. python) could.
Given an input file of, say
mail
sms
cal
phone
cal
cal
bbm
alarm
all

We want to generate
const char types_text[] = "mail" "\0" "sms" "\0" "phone" "\0" "cal" "\0" "bbm" "\0" "alarm" "\0" "all";
const unsigned char types_offset[] = { 0, 5, 15, 9, 15, 15, 19, 23, 29 };

So we could do something like
#!/usr/bin/python2

import sys

prog = sys.argv.pop(0)

for filename in sys.argv:
  lines = open(filename).read().splitlines()
  unique = list(set(lines))
  unique_offset = [0]
  for string in unique:
    unique_offset.append(len(string) + unique_offset[-1] + 1)
  offset = []
  for line in lines:
    offset.append(str(unique_offset[unique.index(line)]))

  print 'const char ' + filename + '[] = "' + '" "\\0" "'.join(unique) + '";'
  print 'const unsigned char ' + filename + '_offset[] = { ' + ', '.join(offset) + ' };'

Which gives
const char types[] = "bbm" "\0" "alarm" "\0" "sms" "\0" "all" "\0" "phone" "\0" "cal" "\0" "mail";
const unsigned char types_offset[] = { 22, 8, 19, 14, 19, 19, 0, 3, 11 };

Not the same order as created manually, but I think that's OK; types_offset gives the words in same order.
C program to test (should spit out the same text as the input file)
#include <stdio.h>
#include "types.h"

int main(int argc, char **argv)
{
   int i;
   for (i = 0; i < sizeof(types_offset)/sizeof(*types_offset); i++)
     puts(&types[types_offset[i]]);

  return 0;
}


For the table of rise/set times, a two-dimensional array of a struct should work
EDIT: switched from BCD ({0x0723} for 7:23) to standard number format and seperate fields ({7,23}). BCD and a single 16-bit field might look a little better when writing the table, but complicates using values.
struct hrmin {
  uint8_t hour;
  uint8_t minute;
};

struct riseset {
  struct hrmin rise;
  struct hrmin set;
};

const struct riseset riseset_table[12][31] = {
  { /* January */
    { { 7, 23 }, { 17, 1 }, }, /* 01 */
    { { 7, 23 }, { 17, 2 }, }, /* 02 */
     ...
  },
  { /* February, with optionally verbose syntax */
    {
      .rise = { 7, 23 },
      .set = { .hour = 17, .minute = 1 },
    }, /* 01 */
    { { 7, 23 }, { 17, 2 }, }, /* 02 */
  },
  ...
};

const struct riseset *get_riseset(int32_t mon, int32_t mday)
{
  return &riseset_table[mon - 1][mday - 1];
}

/* for example, print rise time for January 2 */
int main(int argc, char **argv)
{
  struct riseset *January2 = get_riseset(1,2);
  printf("%d:%d\n", January2->rise.hour, January2->rise.minute);
}


Offline
 Profile  
 
Display posts from previous:  Sort by  
 Page 1 of 1 [ 7 posts ] 

All times are UTC - 8 hours


Who is online

Users browsing this forum: No registered users and 1 guest


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:
Jump to: