Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial Commit

  • Loading branch information...
commit 9c96fa015ee8c80e9ab48154c4ecc4fbcfe13087 0 parents
Brad Luyster authored
509 AVR/Examples/Makefile
... ... @@ -0,0 +1,509 @@
  1 +# Hey Emacs, this is a -*- makefile -*-
  2 +#----------------------------------------------------------------------------
  3 +# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
  4 +#
  5 +# Released to the Public Domain
  6 +#
  7 +# Additional material for this makefile was written by:
  8 +# Peter Fleury
  9 +# Tim Henigan
  10 +# Colin O'Flynn
  11 +# Reiner Patommel
  12 +# Markus Pfaff
  13 +# Sander Pool
  14 +# Frederik Rouleau
  15 +#
  16 +#----------------------------------------------------------------------------
  17 +# On command line:
  18 +#
  19 +# make all = Make software.
  20 +#
  21 +# make clean = Clean out built project files.
  22 +#
  23 +# make coff = Convert ELF to AVR COFF.
  24 +#
  25 +# make extcoff = Convert ELF to AVR Extended COFF.
  26 +#
  27 +# make program = Download the hex file to the device, using avrdude.
  28 +# Please customize the avrdude settings below first!
  29 +#
  30 +# make debug = Start either simulavr or avarice as specified for debugging,
  31 +# with avr-gdb or avr-insight as the front end for debugging.
  32 +#
  33 +# make filename.s = Just compile filename.c into the assembler code only.
  34 +#
  35 +# make filename.i = Create a preprocessed source file for use in submitting
  36 +# bug reports to the GCC project.
  37 +#
  38 +# To rebuild project do "make clean" then "make all".
  39 +#----------------------------------------------------------------------------
  40 +
  41 +
  42 +# MCU name
  43 +MCU = atmega168
  44 +AVRDUDEMCU = m168
  45 +
  46 +
  47 +# Processor frequency.
  48 +# This will define a symbol, F_CPU, in all source code files equal to the
  49 +# processor frequency. You can then use this symbol in your source code to
  50 +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
  51 +# automatically to create a 32-bit value in your source code.
  52 +F_CPU = 16000000
  53 +
  54 +
  55 +# Output format. (can be srec, ihex, binary)
  56 +FORMAT = ihex
  57 +
  58 +
  59 +# Target file name (without extension).
  60 +TARGET = basicAvr
  61 +
  62 +
  63 +# List C source files here. (C dependencies are automatically generated.)
  64 +SRC = $(TARGET).c ../queue.c
  65 +
  66 +
  67 +# List Assembler source files here.
  68 +# Make them always end in a capital .S. Files ending in a lowercase .s
  69 +# will not be considered source files but generated files (assembler
  70 +# output from the compiler), and will be deleted upon "make clean"!
  71 +# Even though the DOS/Win* filesystem matches both .s and .S the same,
  72 +# it will preserve the spelling of the filenames, and gcc itself does
  73 +# care about how the name is spelled on its command-line.
  74 +ASRC =
  75 +
  76 +
  77 +# Optimization level, can be [0, 1, 2, 3, s].
  78 +# 0 = turn off optimization. s = optimize for size.
  79 +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
  80 +OPT = s
  81 +
  82 +
  83 +# Debugging format.
  84 +# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
  85 +# AVR Studio 4.10 requires dwarf-2.
  86 +# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
  87 +DEBUG = dwarf-2
  88 +
  89 +
  90 +# List any extra directories to look for include files here.
  91 +# Each directory must be seperated by a space.
  92 +# Use forward slashes for directory separators.
  93 +# For a directory that has spaces, enclose it in quotes.
  94 +EXTRAINCDIRS =
  95 +
  96 +
  97 +# Compiler flag to set the C Standard level.
  98 +# c89 = "ANSI" C
  99 +# gnu89 = c89 plus GCC extensions
  100 +# c99 = ISO C99 standard (not yet fully implemented)
  101 +# gnu99 = c99 plus GCC extensions
  102 +CSTANDARD = -std=gnu99
  103 +
  104 +
  105 +# Place -D or -U options here
  106 +CDEFS = -DF_CPU=$(F_CPU)UL
  107 +
  108 +
  109 +# Place -I options here
  110 +CINCS =
  111 +
  112 +
  113 +
  114 +#---------------- Compiler Options ----------------
  115 +# -g*: generate debugging information
  116 +# -O*: optimization level
  117 +# -f...: tuning, see GCC manual and avr-libc documentation
  118 +# -Wall...: warning level
  119 +# -Wa,...: tell GCC to pass this to the assembler.
  120 +# -adhlns...: create assembler listing
  121 +CFLAGS = -g$(DEBUG)
  122 +CFLAGS += $(CDEFS) $(CINCS)
  123 +CFLAGS += -O$(OPT)
  124 +CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
  125 +CFLAGS += -Wall -Wstrict-prototypes
  126 +CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
  127 +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
  128 +CFLAGS += $(CSTANDARD)
  129 +
  130 +
  131 +#---------------- Assembler Options ----------------
  132 +# -Wa,...: tell GCC to pass this to the assembler.
  133 +# -ahlms: create listing
  134 +# -gstabs: have the assembler create line number information; note that
  135 +# for use in COFF files, additional information about filenames
  136 +# and function names needs to be present in the assembler source
  137 +# files -- see avr-libc docs [FIXME: not yet described there]
  138 +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
  139 +
  140 +
  141 +#---------------- Library Options ----------------
  142 +# Minimalistic printf version
  143 +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
  144 +
  145 +# Floating point printf version (requires MATH_LIB = -lm below)
  146 +PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
  147 +
  148 +# If this is left blank, then it will use the Standard printf version.
  149 +PRINTF_LIB =
  150 +#PRINTF_LIB = $(PRINTF_LIB_MIN)
  151 +#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
  152 +
  153 +
  154 +# Minimalistic scanf version
  155 +SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
  156 +
  157 +# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
  158 +SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
  159 +
  160 +# If this is left blank, then it will use the Standard scanf version.
  161 +SCANF_LIB =
  162 +#SCANF_LIB = $(SCANF_LIB_MIN)
  163 +#SCANF_LIB = $(SCANF_LIB_FLOAT)
  164 +
  165 +
  166 +MATH_LIB = -lm
  167 +
  168 +
  169 +
  170 +#---------------- External Memory Options ----------------
  171 +
  172 +# 64 KB of external RAM, starting after internal RAM (ATmega128!),
  173 +# used for variables (.data/.bss) and heap (malloc()).
  174 +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
  175 +
  176 +# 64 KB of external RAM, starting after internal RAM (ATmega128!),
  177 +# only used for heap (malloc()).
  178 +#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
  179 +
  180 +EXTMEMOPTS =
  181 +
  182 +
  183 +
  184 +#---------------- Linker Options ----------------
  185 +# -Wl,...: tell GCC to pass this to linker.
  186 +# -Map: create map file
  187 +# --cref: add cross reference to map file
  188 +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
  189 +LDFLAGS += $(EXTMEMOPTS)
  190 +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
  191 +
  192 +
  193 +
  194 +#---------------- Programming Options (avrdude) ----------------
  195 +
  196 +# Programming hardware: alf avr910 avrisp bascom bsd
  197 +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
  198 +#
  199 +# Type: avrdude -c ?
  200 +# to get a full listing.
  201 +#
  202 +AVRDUDE_PROGRAMMER = arduino
  203 +
  204 +# com1 = serial port. Use lpt1 to connect to parallel port.
  205 +AVRDUDE_PORT = /dev/ttyUSB0
  206 +
  207 +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
  208 +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
  209 +
  210 +
  211 +# Uncomment the following if you want avrdude's erase cycle counter.
  212 +# Note that this counter needs to be initialized first using -Yn,
  213 +# see avrdude manual.
  214 +#AVRDUDE_ERASE_COUNTER = -y
  215 +
  216 +# Uncomment the following if you do /not/ wish a verification to be
  217 +# performed after programming the device.
  218 +#AVRDUDE_NO_VERIFY = -V
  219 +
  220 +# Increase verbosity level. Please use this when submitting bug
  221 +# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
  222 +# to submit bug reports.
  223 +#AVRDUDE_VERBOSE = -v -v
  224 +
  225 +AVRDUDE_FLAGS = -p $(AVRDUDEMCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -b 19200
  226 +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
  227 +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
  228 +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
  229 +
  230 +
  231 +
  232 +#---------------- Debugging Options ----------------
  233 +
  234 +# For simulavr only - target MCU frequency.
  235 +DEBUG_MFREQ = $(F_CPU)
  236 +
  237 +# Set the DEBUG_UI to either gdb or insight.
  238 +# DEBUG_UI = gdb
  239 +DEBUG_UI = insight
  240 +
  241 +# Set the debugging back-end to either avarice, simulavr.
  242 +DEBUG_BACKEND = avarice
  243 +#DEBUG_BACKEND = simulavr
  244 +
  245 +# GDB Init Filename.
  246 +GDBINIT_FILE = __avr_gdbinit
  247 +
  248 +# When using avarice settings for the JTAG
  249 +JTAG_DEV = /dev/com1
  250 +
  251 +# Debugging port used to communicate between GDB / avarice / simulavr.
  252 +DEBUG_PORT = 4242
  253 +
  254 +# Debugging host used to communicate between GDB / avarice / simulavr, normally
  255 +# just set to localhost unless doing some sort of crazy debugging when
  256 +# avarice is running on a different computer.
  257 +DEBUG_HOST = localhost
  258 +
  259 +
  260 +
  261 +#============================================================================
  262 +
  263 +
  264 +# Define programs and commands.
  265 +SHELL = sh
  266 +CC = avr-gcc
  267 +OBJCOPY = avr-objcopy
  268 +OBJDUMP = avr-objdump
  269 +SIZE = avr-size
  270 +NM = avr-nm
  271 +AVRDUDE = avrdude
  272 +REMOVE = rm -f
  273 +COPY = cp
  274 +WINSHELL = cmd
  275 +
  276 +
  277 +# Define Messages
  278 +# English
  279 +MSG_ERRORS_NONE = Errors: none
  280 +MSG_BEGIN = -------- begin --------
  281 +MSG_END = -------- end --------
  282 +MSG_SIZE_BEFORE = Size before:
  283 +MSG_SIZE_AFTER = Size after:
  284 +MSG_COFF = Converting to AVR COFF:
  285 +MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
  286 +MSG_FLASH = Creating load file for Flash:
  287 +MSG_EEPROM = Creating load file for EEPROM:
  288 +MSG_EXTENDED_LISTING = Creating Extended Listing:
  289 +MSG_SYMBOL_TABLE = Creating Symbol Table:
  290 +MSG_LINKING = Linking:
  291 +MSG_COMPILING = Compiling:
  292 +MSG_ASSEMBLING = Assembling:
  293 +MSG_CLEANING = Cleaning project:
  294 +
  295 +
  296 +
  297 +
  298 +# Define all object files.
  299 +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
  300 +
  301 +# Define all listing files.
  302 +LST = $(SRC:.c=.lst) $(ASRC:.S=.lst)
  303 +
  304 +
  305 +# Compiler flags to generate dependency files.
  306 +GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d
  307 +
  308 +
  309 +# Combine all necessary flags and optional flags.
  310 +# Add target processor to flags.
  311 +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
  312 +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
  313 +
  314 +
  315 +
  316 +
  317 +
  318 +# Default target.
  319 +all: begin gccversion sizebefore build sizeafter end
  320 +
  321 +build: elf hex eep lss sym
  322 +
  323 +elf: $(TARGET).elf
  324 +hex: $(TARGET).hex
  325 +eep: $(TARGET).eep
  326 +lss: $(TARGET).lss
  327 +sym: $(TARGET).sym
  328 +
  329 +
  330 +
  331 +# Eye candy.
  332 +# AVR Studio 3.x does not check make's exit code but relies on
  333 +# the following magic strings to be generated by the compile job.
  334 +begin:
  335 + @echo
  336 + @echo $(MSG_BEGIN)
  337 +
  338 +end:
  339 + @echo $(MSG_END)
  340 + @echo
  341 +
  342 +
  343 +# Display size of file.
  344 +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
  345 +ELFSIZE = $(SIZE) -A $(TARGET).elf
  346 +AVRMEM = avr-mem.sh $(TARGET).elf $(MCU)
  347 +
  348 +sizebefore:
  349 + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
  350 + $(AVRMEM) 2>/dev/null; echo; fi
  351 +
  352 +sizeafter:
  353 + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
  354 + $(AVRMEM) 2>/dev/null; echo; fi
  355 +
  356 +
  357 +
  358 +# Display compiler version information.
  359 +gccversion :
  360 + @$(CC) --version
  361 +
  362 +
  363 +
  364 +# Program the device.
  365 +program: $(TARGET).hex $(TARGET).eep
  366 + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
  367 +
  368 +
  369 +# Generate avr-gdb config/init file which does the following:
  370 +# define the reset signal, load the target file, connect to target, and set
  371 +# a breakpoint at main().
  372 +gdb-config:
  373 + @$(REMOVE) $(GDBINIT_FILE)
  374 + @echo define reset >> $(GDBINIT_FILE)
  375 + @echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
  376 + @echo end >> $(GDBINIT_FILE)
  377 + @echo file $(TARGET).elf >> $(GDBINIT_FILE)
  378 + @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
  379 +ifeq ($(DEBUG_BACKEND),simulavr)
  380 + @echo load >> $(GDBINIT_FILE)
  381 +endif
  382 + @echo break main >> $(GDBINIT_FILE)
  383 +
  384 +debug: gdb-config $(TARGET).elf
  385 +ifeq ($(DEBUG_BACKEND), avarice)
  386 + @echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
  387 + @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
  388 + $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
  389 + @$(WINSHELL) /c pause
  390 +
  391 +else
  392 + @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
  393 + $(DEBUG_MFREQ) --port $(DEBUG_PORT)
  394 +endif
  395 + @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
  396 +
  397 +
  398 +
  399 +
  400 +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
  401 +COFFCONVERT=$(OBJCOPY) --debugging \
  402 +--change-section-address .data-0x800000 \
  403 +--change-section-address .bss-0x800000 \
  404 +--change-section-address .noinit-0x800000 \
  405 +--change-section-address .eeprom-0x810000
  406 +
  407 +
  408 +coff: $(TARGET).elf
  409 + @echo
  410 + @echo $(MSG_COFF) $(TARGET).cof
  411 + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof
  412 +
  413 +
  414 +extcoff: $(TARGET).elf
  415 + @echo
  416 + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof
  417 + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
  418 +
  419 +
  420 +
  421 +# Create final output files (.hex, .eep) from ELF output file.
  422 +%.hex: %.elf
  423 + @echo
  424 + @echo $(MSG_FLASH) $@
  425 + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
  426 +
  427 +%.eep: %.elf
  428 + @echo
  429 + @echo $(MSG_EEPROM) $@
  430 + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
  431 + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
  432 +
  433 +# Create extended listing file from ELF output file.
  434 +%.lss: %.elf
  435 + @echo
  436 + @echo $(MSG_EXTENDED_LISTING) $@
  437 + $(OBJDUMP) -h -S $< > $@
  438 +
  439 +# Create a symbol table from ELF output file.
  440 +%.sym: %.elf
  441 + @echo
  442 + @echo $(MSG_SYMBOL_TABLE) $@
  443 + $(NM) -n $< > $@
  444 +
  445 +
  446 +
  447 +# Link: create ELF output file from object files.
  448 +.SECONDARY : $(TARGET).elf
  449 +.PRECIOUS : $(OBJ)
  450 +%.elf: $(OBJ)
  451 + @echo
  452 + @echo $(MSG_LINKING) $@
  453 + $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
  454 +
  455 +
  456 +# Compile: create object files from C source files.
  457 +%.o : %.c
  458 + @echo
  459 + @echo $(MSG_COMPILING) $<
  460 + $(CC) -c $(ALL_CFLAGS) $< -o $@
  461 +
  462 +
  463 +# Compile: create assembler files from C source files.
  464 +%.s : %.c
  465 + $(CC) -S $(ALL_CFLAGS) $< -o $@
  466 +
  467 +
  468 +# Assemble: create object files from assembler source files.
  469 +%.o : %.S
  470 + @echo
  471 + @echo $(MSG_ASSEMBLING) $<
  472 + $(CC) -c $(ALL_ASFLAGS) $< -o $@
  473 +
  474 +# Create preprocessed source for use in sending a bug report.
  475 +%.i : %.c
  476 + $(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
  477 +
  478 +
  479 +# Target: clean project.
  480 +clean: begin clean_list end
  481 +
  482 +clean_list :
  483 + @echo
  484 + @echo $(MSG_CLEANING)
  485 + $(REMOVE) $(TARGET).hex
  486 + $(REMOVE) $(TARGET).eep
  487 + $(REMOVE) $(TARGET).cof
  488 + $(REMOVE) $(TARGET).elf
  489 + $(REMOVE) $(TARGET).map
  490 + $(REMOVE) $(TARGET).sym
  491 + $(REMOVE) $(TARGET).lss
  492 + $(REMOVE) $(OBJ)
  493 + $(REMOVE) $(LST)
  494 + $(REMOVE) $(SRC:.c=.s)
  495 + $(REMOVE) $(SRC:.c=.d)
  496 + $(REMOVE) .dep/*
  497 +
  498 +
  499 +
  500 +# Include the dependency files.
  501 +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
  502 +
  503 +
  504 +# Listing of phony targets.
  505 +.PHONY : all begin finish end sizebefore sizeafter gccversion \
  506 +build elf hex eep lss sym coff extcoff \
  507 +clean clean_list program debug gdb-config
  508 +
  509 +
95 AVR/Examples/basicAvr.c
... ... @@ -0,0 +1,95 @@
  1 +#include <stdio.h>
  2 +#include <avr/io.h>
  3 +#include <util/delay.h>
  4 +#include <stdint.h>
  5 +
  6 +#include "../queue.h"
  7 +
  8 +#define FOSC 16000000
  9 +#define BAUD 9600
  10 +#define MYUBRR FOSC/16/BAUD-1
  11 +
  12 +#define sbi(var, mask) ((var) |= (uint8_t)(1 << mask))
  13 +#define cbi(var, mask) ((var) &= (uint8_t)~(1 << mask))
  14 +
  15 +#define STATUS_LED 5
  16 +
  17 +void ioinit(void); // initializes IO
  18 +static int uart_putchar(char c, FILE *stream);
  19 +uint8_t uart_getchar(void);
  20 +
  21 +static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
  22 +
  23 +int testFunction(queue_time_t now)
  24 +{
  25 + printf("Hello World! Time: %d\r\n", now);
  26 + return 0;
  27 +}
  28 +
  29 +int testFunction2(queue_time_t now)
  30 +{
  31 + printf("Stupid World! Time: %d\r\n", now);
  32 + return 0;
  33 +}
  34 +
  35 +int main (void)
  36 +{
  37 + uint32_t x = 0;
  38 +
  39 + ioinit(); //Setup IO pins and defaults
  40 +
  41 + scheduleFunction(testFunction, "Test", 3, 3);
  42 + scheduleFunction(testFunction2, "Test2", 4, 3);
  43 +
  44 + while(1)
  45 + {
  46 +
  47 + scheduleRun(x);
  48 + x++;
  49 +
  50 + if(x == 15)
  51 + {
  52 + scheduleRemoveFunction("Test2");
  53 + scheduleChangeFunction("Test", 15, 4);
  54 + }
  55 +
  56 + sbi(PORTB, STATUS_LED);
  57 + _delay_ms(500);
  58 +
  59 + cbi(PORTB, STATUS_LED);
  60 + _delay_ms(500);
  61 + }
  62 +
  63 + return(0);
  64 +}
  65 +
  66 +void ioinit (void)
  67 +{
  68 + //1 = output, 0 = input
  69 + DDRB = 0b11101111; //PB4 = MISO
  70 + DDRC = 0b11111111; //
  71 + DDRD = 0b11111110; //PORTD (RX on PD0)
  72 +
  73 + //USART Baud rate: 9600
  74 + UBRR0H = MYUBRR >> 8;
  75 + UBRR0L = MYUBRR;
  76 + UCSR0B = (1<<RXEN0)|(1<<TXEN0);
  77 +
  78 + stdout = &mystdout; //Required for printf init
  79 +}
  80 +
  81 +static int uart_putchar(char c, FILE *stream)
  82 +{
  83 + //if (c == '\n') uart_putchar('\r', stream);
  84 +
  85 + loop_until_bit_is_set(UCSR0A, UDRE0);
  86 + UDR0 = c;
  87 +
  88 + return 0;
  89 +}
  90 +
  91 +uint8_t uart_getchar(void)
  92 +{
  93 + while( !(UCSR0A & (1<<RXC0)) );
  94 + return(UDR0);
  95 +}
138 AVR/queue.c
... ... @@ -0,0 +1,138 @@
  1 +#include <stdint.h>
  2 +#include <string.h>
  3 +#include <stdio.h>
  4 +
  5 +#include "queue.h"
  6 +
  7 +static uint8_t queueStart = 0;
  8 +static uint8_t queueEnd = 0;
  9 +static uint8_t itemsInQueue = 0;
  10 +
  11 +static queueItem scheduleQueue[QUEUE_DEPTH];
  12 +
  13 +static int scheduleQueueGetTop(queueItem *returnItem);
  14 +static int internalScheduleFunction(queueItem pItem);
  15 +
  16 +int scheduleFunction(queuedFunction pFunction, const char *pId, queue_time_t pInitialRun, queue_time_t pRecur)
  17 +{
  18 + int rv = 0;
  19 +
  20 + queueItem newItem;
  21 + newItem.fPtr = pFunction;
  22 + memset(newItem.itemName, 0, NAME_LIMIT);
  23 + memcpy(newItem.itemName, pId, strlen(pId));
  24 + newItem.recur = pRecur;
  25 + newItem.next = pInitialRun;
  26 +
  27 + rv = internalScheduleFunction(newItem);
  28 +
  29 + return rv;
  30 +}
  31 +
  32 +int scheduleRemoveFunction(const char *pId)
  33 +{
  34 + queueItem target;
  35 + int rv = 0;
  36 + for (int i = 0; i < itemsInQueue; ++i)
  37 + {
  38 + if(scheduleQueueGetTop(&target) == 0)
  39 + {
  40 + if(strcmp(target.itemName, pId) != 0)
  41 + {
  42 + internalScheduleFunction(target);
  43 + }
  44 + } else {
  45 + rv = -1;
  46 + break;
  47 + }
  48 + }
  49 +
  50 + return rv;
  51 +}
  52 +
  53 +int scheduleChangeFunction(const char *pId, queue_time_t pNewNext, queue_time_t pNewRecur)
  54 +{
  55 + queueItem target;
  56 + int rv = 0;
  57 + for (int i = 0; i < itemsInQueue; ++i)
  58 + {
  59 + if(scheduleQueueGetTop(&target) == 0)
  60 + {
  61 + if(strcmp(target.itemName, pId) == 0)
  62 + {
  63 + target.next = pNewNext;
  64 + target.recur = pNewRecur;
  65 + }
  66 + internalScheduleFunction(target);
  67 + } else {
  68 + rv = -1;
  69 + break;
  70 + }
  71 + }
  72 +
  73 + return rv;
  74 +}
  75 +
  76 +int scheduleRun(queue_time_t pNow)
  77 +{
  78 + queueItem target;
  79 + int rv = 0;
  80 + for (int i = 0; i < itemsInQueue; ++i)
  81 + {
  82 + if(scheduleQueueGetTop(&target)==0)
  83 + {
  84 + if(target.next <= pNow)
  85 + {
  86 + int tRv;
  87 + tRv = (target.fPtr)(pNow);
  88 + if(tRv == 0)
  89 + {
  90 + rv++;
  91 + }
  92 + if(target.recur != 0)
  93 + {
  94 + target.next = pNow + target.recur;
  95 + internalScheduleFunction(target);
  96 + }
  97 + } else {
  98 + internalScheduleFunction(target);
  99 + }
  100 + } else {
  101 + rv = -1;
  102 + break;
  103 + }
  104 + }
  105 +
  106 + return rv;
  107 +}
  108 +
  109 +static int scheduleQueueGetTop(queueItem *returnItem)
  110 +{
  111 + int rv = 0;
  112 + //Remove the top item, stuff it into returnItem
  113 + if (queueEnd != queueStart) {
  114 + queueItem tempQueueItem = scheduleQueue[queueStart];
  115 + //This Algorithm also from Wikipedia.
  116 + queueStart = (queueStart + 1) % QUEUE_DEPTH;
  117 + *returnItem = tempQueueItem;
  118 + itemsInQueue--;
  119 + } else {
  120 + //if the buffer is empty, return an error code
  121 + rv = -1;
  122 + }
  123 +
  124 + return rv;
  125 +}
  126 +
  127 +static int internalScheduleFunction(queueItem pItem)
  128 +{
  129 + int rv = 0;
  130 + if ((queueEnd + 1) % QUEUE_DEPTH != queueStart) {
  131 + scheduleQueue[queueEnd] = pItem;
  132 + queueEnd = (queueEnd + 1) % QUEUE_DEPTH;
  133 + itemsInQueue++;
  134 + } else {
  135 + rv = -1;
  136 + }
  137 + return rv;
  138 +}
26 AVR/queue.h
... ... @@ -0,0 +1,26 @@
  1 +#ifndef QUEUE_H
  2 +#define QUEUE_H
  3 +
  4 +// Settings
  5 +#define QUEUE_DEPTH 10
  6 +#define NAME_LIMIT 8
  7 +typedef uint32_t queue_time_t;
  8 +
  9 +typedef int (*queuedFunction)(queue_time_t);
  10 +
  11 +typedef struct _queue_item
  12 +{
  13 + queuedFunction fPtr;
  14 + queue_time_t recur;
  15 + queue_time_t next;
  16 + char itemName[NAME_LIMIT];
  17 +} queueItem;
  18 +
  19 +//Functions
  20 +int scheduleFunction(queuedFunction, const char *, queue_time_t, queue_time_t);
  21 +int scheduleRemoveFunction(const char *);
  22 +int scheduleChangeFunction(const char *, queue_time_t, queue_time_t);
  23 +
  24 +int scheduleRun(queue_time_t);
  25 +
  26 +#endif
147 Arduino/Queue.cpp
... ... @@ -0,0 +1,147 @@
  1 +#include "Queue.h"
  2 +
  3 +Queue::Queue()
  4 +{
  5 + _itemsInQueue = 0;
  6 + _queueStart = 0;
  7 + _queueEnd = 0;
  8 +}
  9 +
  10 +int Queue::scheduleFunction(queuedFunction func, const char * id, unsigned long initialRun, unsigned long recur)
  11 +{
  12 + int rv = 0;
  13 +
  14 + if(strlen(id) > 7)
  15 + {
  16 + rv = -1;
  17 + } else {
  18 +
  19 + queueItem newItem;
  20 + newItem.fPtr = func;
  21 + memset(newItem.itemName, 0, 8);
  22 + memcpy(newItem.itemName, id, strlen(id));
  23 + newItem.recur = recur;
  24 + newItem.next = initialRun;
  25 +
  26 + rv = _addToQueue(newItem);
  27 + }
  28 +
  29 + return rv;
  30 +}
  31 +
  32 +int Queue::scheduleRemoveFunction(const char * id)
  33 +{
  34 + queueItem target;
  35 + int rv = -1;
  36 + for (int i = 0; i < _itemsInQueue; ++i)
  37 + {
  38 + if(_queueGetTop(target) == 0)
  39 + {
  40 + if(strcmp(target.itemName, id) == 0)
  41 + {
  42 + rv = 0;
  43 + } else {
  44 + _addToQueue(target);
  45 + }
  46 + } else {
  47 + rv = -1;
  48 + break;
  49 + }
  50 + }
  51 +
  52 + return rv;
  53 +}
  54 +
  55 +int Queue::scheduleChangeFunction(const char * id, unsigned long nextRunTime, unsigned long newRecur)
  56 +{
  57 + queueItem target;
  58 + int rv = -1;
  59 + for (int i = 0; i < _itemsInQueue; ++i)
  60 + {
  61 + if(_queueGetTop(target) == 0)
  62 + {
  63 + if(strcmp(target.itemName, id) == 0)
  64 + {
  65 + target.next = nextRunTime;
  66 + target.recur = newRecur;
  67 + rv = 0;
  68 + }
  69 + _addToQueue(target);
  70 + } else {
  71 + rv = -1;
  72 + break;
  73 + }
  74 + }
  75 +
  76 + return rv;
  77 +}
  78 +
  79 +int Queue::Run(unsigned long now)
  80 +{
  81 + queueItem target;
  82 + int rv = 0;
  83 + if(_itemsInQueue == 0)
  84 + {
  85 + rv = -1;
  86 + }
  87 + for (int i = 0; i < _itemsInQueue; ++i)
  88 + {
  89 + if(_queueGetTop(target)==0)
  90 + {
  91 + if(target.next <= now)
  92 + {
  93 + int tRv;
  94 + tRv = (target.fPtr)(now);
  95 + if(tRv == 0)
  96 + {
  97 + rv++;
  98 + }
  99 + if(target.recur != 0)
  100 + {
  101 + target.next = now + target.recur;
  102 + _addToQueue(target);
  103 + }
  104 + } else {
  105 + _addToQueue(target);
  106 + }
  107 + } else {
  108 + rv = -1;
  109 + break;
  110 + }
  111 + }
  112 +
  113 + return rv;
  114 +}
  115 +
  116 +int Queue::_queueGetTop(queueItem &item)
  117 +{
  118 + int rv = 0;
  119 + //Remove the top item, stuff it into item
  120 + if (_queueEnd != _queueStart) {
  121 + queueItem tempQueueItem = _schedule[_queueStart];
  122 + //This Algorithm also from Wikipedia.
  123 + _queueStart = (_queueStart + 1) % QueueScheduleSize;
  124 + item = tempQueueItem;
  125 + _itemsInQueue--;
  126 + } else {
  127 + //if the buffer is empty, return an error code
  128 + rv = -1;
  129 + }
  130 +
  131 + return rv;
  132 +}
  133 +
  134 +int Queue::_addToQueue(queueItem item)
  135 +{
  136 + //This is just a circular buffer, and this algorithm is stolen from wikipedia
  137 + int rv = 0;
  138 + if ((_queueEnd + 1) % QueueScheduleSize != _queueStart) {
  139 + _schedule[_queueEnd] = item;
  140 + _queueEnd = (_queueEnd + 1) % QueueScheduleSize;
  141 + _itemsInQueue++;
  142 + } else {
  143 + //if buffer is full, error
  144 + rv = -1;
  145 + }
  146 + return rv;
  147 +}
39 Arduino/Queue.h
... ... @@ -0,0 +1,39 @@
  1 +#ifndef QUEUE_H
  2 +#define QUEUE_H
  3 +
  4 +#include "Arduino.h"
  5 +
  6 +typedef int (*queuedFunction)(unsigned long);
  7 +
  8 +#define QueueScheduleSize 11
  9 +
  10 +struct queueItem {
  11 + queuedFunction fPtr;
  12 + unsigned long next;
  13 + unsigned long recur;
  14 + char itemName[8];
  15 +};
  16 +
  17 +class Queue
  18 +{
  19 +private:
  20 + unsigned int _queueStart;
  21 + unsigned int _queueEnd;
  22 + unsigned int _itemsInQueue;
  23 + queueItem _schedule[QueueScheduleSize];
  24 +
  25 + int _queueGetTop(queueItem &item);
  26 + int _addToQueue(queueItem item);
  27 +
  28 +public:
  29 + Queue();
  30 +
  31 + int scheduleFunction(queuedFunction func, const char * id, unsigned long initialRun, unsigned long recur);
  32 + int scheduleRemoveFunction(const char * id);
  33 + int scheduleChangeFunction(const char * id, unsigned long nextRunTime, unsigned long newRecur);
  34 +
  35 + int Run(unsigned long now);
  36 + /* data */
  37 +};
  38 +
  39 +#endif
185 Arduino/Tests/arduinoTests.ino
... ... @@ -0,0 +1,185 @@
  1 +#include <Queue.h>
  2 +
  3 +/*
  4 + Blink
  5 + Turns on an LED on for one second, then off for one second, repeatedly.
  6 +
  7 + This example code is in the public domain.
  8 + */
  9 +
  10 +void setup() {
  11 + // initialize the digital pin as an output.
  12 + // Pin 13 has an LED connected on most Arduino boards:
  13 + pinMode(13, OUTPUT);
  14 + Serial.begin(9600);
  15 + Serial.println("Alive");
  16 +
  17 + int testStatus = 0;
  18 + testStatus |= test_addTooMany();
  19 + testStatus |= test_removeNonExistent();
  20 + testStatus |= test_tooManyCharacters();
  21 + testStatus |= test_changeNonExistent();
  22 + testStatus |= test_runEmpty();
  23 +
  24 + if(testStatus == 0)
  25 + {
  26 + Serial.println("All tests passed.");
  27 + } else {
  28 + Serial.println("Something Failed.");
  29 + }
  30 +
  31 +}
  32 +
  33 +void loop() {
  34 + delay(1000);
  35 +}
  36 +
  37 +int testFunction(unsigned long now)
  38 +{
  39 + Serial.print("Hello: ");
  40 + Serial.print(now);
  41 + Serial.println();
  42 +}
  43 +
  44 +int test_addTooMany(void)
  45 +{
  46 + Queue testQueue;
  47 + int rv;
  48 + int testStatus = 0;
  49 + rv = testQueue.scheduleFunction(testFunction, "Test1", 5000, 1000);
  50 + if(rv != 0)
  51 + {
  52 + Serial.println("test_addTooMany failed.");
  53 + testStatus = -1;
  54 + }
  55 + rv = testQueue.scheduleFunction(testFunction, "Test2", 5000, 1000);
  56 + if(rv != 0)
  57 + {
  58 + Serial.println("test_addTooMany failed.");
  59 + testStatus = -1;
  60 + }
  61 + rv = testQueue.scheduleFunction(testFunction, "Test3", 5000, 1000);
  62 + if(rv != 0)
  63 + {
  64 + Serial.println("test_addTooMany failed.");
  65 + testStatus = -1;
  66 + }
  67 + rv = testQueue.scheduleFunction(testFunction, "Test4", 5000, 1000);
  68 + if(rv != 0)
  69 + {
  70 + Serial.println("test_addTooMany failed.");
  71 + testStatus = -1;
  72 + }
  73 + rv = testQueue.scheduleFunction(testFunction, "Test5", 5000, 1000);
  74 + if(rv != 0)
  75 + {
  76 + Serial.println("test_addTooMany failed.");
  77 + testStatus = -1;
  78 + }
  79 + rv = testQueue.scheduleFunction(testFunction, "Test6", 5000, 1000);
  80 + if(rv != 0)
  81 + {
  82 + Serial.println("test_addTooMany failed.");
  83 + testStatus = -1;
  84 + }
  85 + rv = testQueue.scheduleFunction(testFunction, "Test7", 5000, 1000);
  86 + if(rv != 0)
  87 + {
  88 + Serial.println("test_addTooMany failed.");
  89 + testStatus = -1;
  90 + }
  91 + rv = testQueue.scheduleFunction(testFunction, "Test8", 5000, 1000);
  92 + if(rv != 0)
  93 + {
  94 + Serial.println("test_addTooMany failed.");
  95 + testStatus = -1;
  96 + }
  97 + rv = testQueue.scheduleFunction(testFunction, "Test9", 5000, 1000);
  98 + if(rv != 0)
  99 + {
  100 + Serial.println("test_addTooMany failed.");
  101 + testStatus = -1;
  102 + }
  103 + rv = testQueue.scheduleFunction(testFunction, "Test10", 5000, 1000);
  104 + if(rv != 0)
  105 + {
  106 + Serial.println("test_addTooMany failed.");
  107 + testStatus = -1;
  108 + }
  109 + rv = testQueue.scheduleFunction(testFunction, "Test11", 5000, 1000);
  110 + if(rv != -1)
  111 + {
  112 + Serial.println("test_addTooMany failed.");
  113 + testStatus = -1;
  114 + }
  115 +
  116 + return testStatus;
  117 +}
  118 +
  119 +int test_removeNonExistent(void)
  120 +{
  121 + Queue testQueue;
  122 + int rv;
  123 + int testStatus = 0;
  124 + rv = testQueue.scheduleFunction(testFunction, "Test", 5000, 1000);
  125 + if(rv != 0)
  126 + {
  127 + Serial.println("test_removeNonExistent failed.");
  128 + testStatus = -1;
  129 + }
  130 + rv = testQueue.scheduleRemoveFunction("Fail");
  131 + if(rv != -1)
  132 + {
  133 + Serial.println("test_removeNonExistent failed.");
  134 + testStatus = -1;
  135 + }
  136 + return testStatus;
  137 +}
  138 +
  139 +int test_tooManyCharacters(void)
  140 +{
  141 + Queue testQueue;
  142 + int rv;
  143 + int testStatus = 0;
  144 + rv = testQueue.scheduleFunction(testFunction, "ReallyLongName", 5000, 1000);
  145 + if(rv != -1)
  146 + {
  147 + Serial.println("test_tooManyCharacters failed.");
  148 + testStatus = -1;
  149 + }
  150 + return testStatus;
  151 +}
  152 +
  153 +int test_changeNonExistent(void)
  154 +{
  155 + Queue testQueue;
  156 + int rv;
  157 + int testStatus = 0;
  158 + rv = testQueue.scheduleFunction(testFunction, "Test", 5000, 1000);
  159 + if(rv != 0)
  160 + {
  161 + Serial.println("test_changeNonExistent failed.");
  162 + testStatus = -1;
  163 + }
  164 + rv = testQueue.scheduleChangeFunction("Fail", 1000, 1000);
  165 + if(rv != -1)
  166 + {
  167 + Serial.println("test_changeNonExistent failed.");
  168 + testStatus = -1;
  169 + }
  170 + return testStatus;
  171 +}
  172 +
  173 +int test_runEmpty(void)
  174 +{
  175 + Queue myQueue;
  176 + int rv = 0;
  177 + int testStatus = 0;
  178 + rv = myQueue.Run(10);
  179 + if (rv != -1)
  180 + {
  181 + Serial.println("test_runEmpty failed.");
  182 + testStatus = -1;
  183 + }
  184 + return testStatus;
  185 +}

0 comments on commit 9c96fa0

Please sign in to comment.
Something went wrong with that request. Please try again.