I wrote a simple sketch to be run with the ArduinoTiny project. The target is an ATTiny2313. The simple sketch came out to be 4200Bytes. When written in C code, its only 800.
I’d like to suggest a checkbox that will compile a sketch in minimalistic mode.
Here is the code which I am talking about.
/*
Barnes and Nobel Nook Tablet Mod Chip
Copyright 2011 Adam Outler - hkvc
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-Adam Outler adamoutler, gmail.com
*/
boolean Position[3]={true,true,true};//Place holders for operation
int inByte; //current byte
String Message=""; //current string of bytes
//begin sketch
void setup() {
Serial.begin(115200); //Initialize UART and set baud for serial
Serial.println("I are your god now");
}
void loop() {
if (Serial.available()) {
inByte = Serial.read();
if ( inByte == 10 ){
Message="";
}
else {
Message=Message +(char)inByte; //dump char into string
if (Message == "OMAP44XX SDP # "){
if ( Position[1]){
Serial.println("O hai Nook Im in ur memory");
Serial.println("mmcinit 0; fatload mmc 0:1 0x81000000 new.flashing_boot.img;");
Serial.println("Mai kernel is ur kernel");
Position[1]=(!Position[1]);
return;
} else if ( Position[2]){
Serial.println("Ur Security is my target");
Serial.println("mw.l 80e84794 e1a00000; mw.l 80e847fc e1a00000; mw.l 80e84808 e1a00000; mw.l 80e847a0 e1a00000;");
Serial.println("Ur Security is neutralized");
Position[2]=(!Position[2]);
return;
}
else if ( Position[3]){
Serial.println("boot mai kernel now");
Serial.print("booti 0x81000000");
Serial.println("k thx bai");
Position[3]=(!Position[3]);
return;
}
}
}
}
if (millis()>=60000){
lockup;
}
}
void lockup(){
while(true){
delay(50000);//program cannot end, only sleep
}
}
The basic gist of this program is to monitor for a string, then respond with one of 3 strings. I added some extra stuff into it as well.
The problem is that this compiles over 4K and it does not need to be more than 1K. Here’s a similar program written in all C.
#include <avr/io.h>
#include <avr/pgmspace.h>
// Use a 3.6864MHz clock
#define F_CPU 3686400UL
#define BAUD 115200UL
// Must be loaded after defines above
#include <util/setbaud.h>
// These strings won't fit in RAM
char LOADMMC[] PROGMEM = "mmcinit 0; fatload mmc 0:1 0x81000000 new.flashing_boot.img;";
char OPCODES[] PROGMEM = "mw.l 80e84794 e1a00000; mw.l 80e847fc e1a00000; mw.l 80e84808 e1a00000; mw.l 80e847a0 e1a00000;";
char BOOTCMD[] PROGMEM = "booti 0x81000000";
void uart_putchar(char c) {
// Wait until transmitter ready
loop_until_bit_is_set(UCSRA, UDRE);
UDR = c;
}
void uart_puts_progmem(char *s) {
char b;
// While the byte read from flash isn't a null byte, keep sending
while ('\0' != (b = pgm_read_byte(s++))) {
uart_putchar(b);
}
}
void init_uart() {
// Set baud rate using setbaud macros
UBRRH = UBRRH_VALUE;
UBRRL = UBRRL_VALUE;
#if USE_2X
UCSRA |= _BV(U2X);
#else
UCSRA &= ~_BV(U2X);
#endif
// Enable receiver/transmitter
UCSRB = _BV(RXEN) | _BV(TXEN);
// TxD pin PD1 set to output
DDRD |= _BV(PD1);
// RxD pin PD0 set to input
DDRD &= ~_BV(PD0);
}
void send_string(int i) {
switch (i) {
case 0:
uart_puts_progmem(BOOTCMD);
break;
case 1:
uart_puts_progmem(OPCODES);
break;
case 2:
uart_puts_progmem(LOADMMC);
// Disable interrupts and put the micro to sleep - it will never wake up ( :( )
asm("CLI");
MCUCR |= _BV(SM1) | _BV(SM0) | _BV(SE);
asm("SLEEP");
break;
}
}
int main(void)
{
char c;
int state, i;
// Turn off peripherals we aren't using
PRR |= _BV(PRTIM1) | _BV(PRTIM0) | _BV(PRUSI);
init_uart();
while(1)
{
// Use a state machine to detect the prompt
if (UCSRA & _BV(RXC)) {
c = UDR;
switch (state) {
case 0:
if (c == 'S') state++;
break;
case 1:
if (c == 'D') state++;
else state = 0;
break;
case 2:
if (c == 'P') state++;
else state = 0;
break;
case 3:
if (c == ' ') state++;
else state = 0;
break;
case 4:
if (c == '#') state++;
else state = 0;
break;
case 5:
if (c == ' ') send_string(i++);
state = 0;
break;
}
}
}
}
It seems to me that size would be a concern when prototyping.
Thanks for reading and considering this proposal for a minimalistic compilation option.