-
Notifications
You must be signed in to change notification settings - Fork 2
/
teensy_size.c
153 lines (129 loc) · 4.45 KB
/
teensy_size.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include "minimal_elf.h"
void die(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
unsigned char *filedata = NULL;
FILE *fp = NULL;
const char * model_name(int num)
{
switch (num) {
case 0x19: return "Teensy 1.0";
case 0x1A: return "Teensy++ 1.0";
case 0x1B: return "Teensy 2.0";
case 0x1C: return "Teensy++ 2.0";
case 0x1D: return "Teensy 3.0";
case 0x1E: return "Teensy 3.1";
case 0x1F: return "Teensy 3.5";
case 0x20: return "Teensy LC";
case 0x21: return "Teensy 3.2";
case 0x22: return "Teensy 3.6";
case 0x23: return "Teensy 4-Beta1";
case 0x24: return "Teensy 4.0";
case 0x25: return "Teensy 4.1";
case 0x26: return "Teensy MicroMod";
}
return "Teensy";
}
uint32_t flash_size(int model)
{
if (model == 0x24) return 2031616; // Teensy 4.0
if (model == 0x25) return 8126464; // Teensy 4.1
if (model == 0x26) return 16515072; // MicroMod
return 0;
}
int main(int argc, char **argv)
{
int retval = 0;
if (argc < 2) die("usage: teensy_size <file.elf>\n");
const char *filename = argv[1];
fp = fopen(filename, "rb");
if (!fp) die("Unable to open for reading %s\n", filename);
fseek(fp, 0, SEEK_END);
size_t filesize = ftell(fp);
filedata = malloc(filesize);
if (!filedata) die("unable to allocate %ld bytes\n", (long)filesize);
rewind(fp);
if (fread(filedata, 1, filesize, fp) != filesize) die("Unable to read %s\n", filename);
fclose(fp);
fp = NULL;
int r = parse_elf(filedata);
if (r != 0) die("Unable to parse %s, err = %d\n", filename, r);
int model = elf_teensy_model_id(filedata);
if (!model) die("Can't determine Teensy model from %s\n", filename);
//print_elf_info();
//printf("Teensy Model is %02X (%s)\n", model, model_name(model));
if (model == 0x24 || model == 0x25 || model == 0x26) {
uint32_t text_headers = elf_section_size(".text.headers");
uint32_t text_code = elf_section_size(".text.code");
uint32_t text_progmem = elf_section_size(".text.progmem");
uint32_t text_itcm = elf_section_size(".text.itcm");
uint32_t arm_exidx = elf_section_size(".ARM.exidx");
uint32_t data = elf_section_size(".data");
uint32_t bss = elf_section_size(".bss");
uint32_t bss_dma = elf_section_size(".bss.dma");
uint32_t text_csf = elf_section_size(".text.csf");
uint32_t flash_total = text_headers + text_code + text_progmem
+ text_itcm + arm_exidx + data + text_csf;
uint32_t flash_headers = text_headers + text_csf;
uint32_t flash_code = text_code + text_itcm + arm_exidx;
uint32_t flash_data = text_progmem + data;
uint32_t itcm = text_itcm + arm_exidx;
uint32_t itcm_blocks = (itcm + 0x7FFF) >> 15;
uint32_t itcm_total = itcm_blocks * 32768;
uint32_t itcm_padding = itcm_total - itcm;
uint32_t dtcm = data + bss;
uint32_t ram2 = bss_dma;
int32_t free_flash = (int32_t)flash_size(model) - (int32_t)flash_total;
int32_t free_for_local = 512*1024 - (int32_t)itcm_total - (int32_t)dtcm;
int32_t free_for_malloc = (int32_t)512*1024 - (int32_t)ram2;
if ((free_flash < 0) || (free_for_local <= 0) || (free_for_malloc < 0)) retval = -1;
FILE *fout = stderr; // Arduino 1.8.x discards info unless stderr
const char *prefix = "teensy_size: ";
const char *ardua = getenv("ARDUINO_USER_AGENT");
if (ardua && strstr(ardua, "arduino-cli")) {
prefix = "";
if (retval == 0) fout = stdout;
}
fprintf(fout,
"%sMemory Usage on %s:\n", prefix, model_name(model));
fprintf(fout,
"%s FLASH: code:%u, data:%u, headers:%u free for files:%d\n",
(free_flash < 0) ? "" : prefix,
flash_code, flash_data, flash_headers, free_flash);
fprintf(fout,
"%s RAM1: variables:%u, code:%u, padding:%u free for local variables:%d\n",
(free_for_local <= 0) ? "" : prefix,
dtcm, itcm, itcm_padding, free_for_local);
fprintf(fout,
"%s RAM2: variables:%u free for malloc/new:%d\n",
(free_for_malloc < 0) ? "" : prefix,
ram2, free_for_malloc);
if (model == 0x25) {
uint32_t bss_extram = elf_section_size(".bss.extram");
if (bss_extram > 0) {
fprintf(fout,
"%s EXTRAM: variables:%u\n", prefix, bss_extram);
}
}
if (retval != 0) {
fprintf(fout,"Error program exceeds memory space\n");
}
fflush(fout);
}
free(filedata);
return retval;
}
void die(const char *format, ...)
{
va_list args;
va_start(args, format);
fprintf(stderr, "teensy_size: ");
vfprintf(stderr, format, args);
va_end(args);
if (fp) fclose(fp);
if (filedata) free(filedata);
exit(1);
}