Skip to content

Commit

Permalink
performance optimization, memory optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
bunnie committed May 31, 2016
1 parent 851c6f3 commit 58a90f4
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 97 deletions.
10 changes: 8 additions & 2 deletions orchard/Makefile
Expand Up @@ -5,7 +5,7 @@

# Compiler options here.
ifeq ($(USE_OPT),)
USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 -nostdlib -fstack-protector
USE_OPT = -O3 -ggdb -fomit-frame-pointer -falign-functions=16 -nostdlib -fstack-protector
endif

# C specific options here (added to USE_OPT).
Expand Down Expand Up @@ -43,6 +43,12 @@ ifeq ($(USE_VERBOSE_COMPILE),)
USE_VERBOSE_COMPILE = no
endif

# If enabled, this option makes the build process faster by not compiling
# modules not used in the current configuration.
ifeq ($(USE_SMART_BUILD),)
USE_SMART_BUILD = yes
endif

#
# Build global options
##############################################################################
Expand All @@ -54,7 +60,7 @@ endif
# Stack size to be allocated to the Cortex-M process stack. This stack is
# the stack used by the main() thread.
ifeq ($(USE_PROCESS_STACKSIZE),)
USE_PROCESS_STACKSIZE = 0x500
USE_PROCESS_STACKSIZE = 196
endif

# Stack size to the allocated to the Cortex-M main/exceptions stack. This
Expand Down
4 changes: 2 additions & 2 deletions orchard/analog.c
Expand Up @@ -53,7 +53,7 @@ static void adc_temperature_end_cb(ADCDriver *adcp, adcsample_t *buffer, size_t
celcius = 25000 - delta;

chSysLockFromISR();
chEvtBroadcastI(&adc_celcius_event);
// chEvtBroadcastI(&adc_celcius_event);
chSysUnlockFromISR();
}

Expand Down Expand Up @@ -101,7 +101,7 @@ static void adc_mic_end_cb(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
}

chSysLockFromISR();
chEvtBroadcastI(&adc_mic_event);
// chEvtBroadcastI(&adc_mic_event);
chSysUnlockFromISR();
}

Expand Down
4 changes: 2 additions & 2 deletions orchard/chconf.h
Expand Up @@ -100,7 +100,7 @@
* does not spawn the idle thread. The application @p main()
* function becomes the idle thread and must implement an
* infinite loop. */
#define CH_CFG_NO_IDLE_THREAD FALSE
#define CH_CFG_NO_IDLE_THREAD TRUE

/** @} */

Expand Down Expand Up @@ -267,7 +267,7 @@
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_QUEUES FALSE
#define CH_CFG_USE_QUEUES TRUE

/**
* @brief Core Memory Manager APIs.
Expand Down
53 changes: 34 additions & 19 deletions orchard/dv-serialmode.c
Expand Up @@ -3,6 +3,7 @@

#include "orchard.h"
#include "orchard-shell.h"
#include "orchard-events.h"
#include "oled.h"
#include "gfx.h"

Expand All @@ -12,7 +13,7 @@
#define MAX_ROWS 4
#define TEXT_LEN (MAX_COLS * MAX_ROWS)
static char text_buffer[TEXT_LEN];
static uint8_t write_ptr = 0;
static int8_t write_ptr = 0;

uint8_t isprint_local(char c) {
return ((c >= ' ' && c <= '~') ? 1 : 0);
Expand All @@ -26,10 +27,11 @@ int find_printable_window(void) {

// starting from the last written character, search backwards...
while( chars_searched < TEXT_LEN ) {
if( (text_buffer[cur_ptr] == '\n') || (text_buffer[cur_ptr] == '\r' ) ) {
if( text_buffer[cur_ptr] == '\n' ) {
// chprintf(stream, "n");
num_lines++;
if( num_lines == (MAX_ROWS+1) ) { // forward back over the final newline we found
// MAX_ROWS+1 if you want to show the current incoming line too
if( num_lines == (MAX_ROWS+2) ) { // forward back over the final newline we found
cur_ptr++; cur_ptr %= TEXT_LEN;
break;
}
Expand All @@ -46,7 +48,8 @@ int find_printable_window(void) {
// chprintf(stream, "c");
num_lines++;
chars_since_newline = 0;
if( num_lines >= (MAX_ROWS+1) ) {
// MAX_ROWS+1 if you want to show the current incoming line too
if( num_lines >= (MAX_ROWS+2) ) {
cur_ptr++; cur_ptr %= TEXT_LEN;
break;
}
Expand All @@ -69,7 +72,7 @@ int find_printable_window(void) {
return cur_ptr;
}

void update_screen(void) {
void updateSerialScreen(void) {
coord_t width;
coord_t font_height;
font_t font;
Expand All @@ -96,7 +99,7 @@ void update_screen(void) {
if( cur_char == write_ptr )
break;

if( (text_buffer[cur_char] == '\n') || (text_buffer[cur_char] == '\r') ) {
if( text_buffer[cur_char] == '\n' ) {
str_to_render[i] = ' ';
cur_char++; i++; chars_processed++;
cur_char %= TEXT_LEN;
Expand Down Expand Up @@ -126,26 +129,38 @@ void update_screen(void) {
void dvInit(void) {
int i;
for( i = 0; i < TEXT_LEN; i++ ) {
text_buffer[i] = ' '; // init with whitespace
text_buffer[i] = ' '; // init with whitespace, use something else for debugging hints
}
text_buffer[TEXT_LEN-1] = '\n'; // simulate final newline
write_ptr = 0;
}

void dvDoSerial(void) {
char c;

if(chSequentialStreamRead((BaseSequentialStream *) stream, (uint8_t *)&c, 1) == 0)
return;

// chSequentialStreamPut((BaseSequentialStream *)stream, c); // local echo to tx

text_buffer[write_ptr] = c;
int8_t prev_ptr;

while(TRUE) {
prev_ptr = write_ptr - 1;
if( prev_ptr == -1 )
prev_ptr = TEXT_LEN - 1;

if(chSequentialStreamRead((BaseSequentialStream *) stream, (uint8_t *)&c, 1) == 0)
return; // we keep on running until the buffer is empty

if( c == '\r' )
c = '\n';

// if CRLF, eat multiple CRLF
if( c == '\n' ) {
if( text_buffer[prev_ptr] == '\n' )
return;
}

text_buffer[write_ptr] = c;

write_ptr++;
write_ptr %= TEXT_LEN;
text_buffer[write_ptr] = ' '; // rule: current spot we're pointing to for write cannot be a newline
write_ptr++;
write_ptr %= TEXT_LEN;
text_buffer[write_ptr] = ' '; // rule: current spot we're pointing to for write cannot be a newline
}

update_screen();

}
1 change: 1 addition & 0 deletions orchard/dv-serialmode.h
@@ -1,2 +1,3 @@
void dvInit(void);
void dvDoSerial(void);
void updateSerialScreen(void);
2 changes: 1 addition & 1 deletion orchard/halconf.h
Expand Up @@ -284,7 +284,7 @@
* buffers.
*/
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE 16
#define SERIAL_BUFFERS_SIZE 32
#endif

/*===========================================================================*/
Expand Down
144 changes: 80 additions & 64 deletions orchard/main.c
Expand Up @@ -37,8 +37,12 @@
#include "kl02x.h"

struct evt_table orchard_app_events;
event_source_t ta_update_event;
event_source_t adc_celcius_event;
event_source_t refresh_event;
event_source_t serial_event;
uint8_t serial_init = 0;

static virtual_timer_t led_vt;
static virtual_timer_t refresh_vt;

static void mode_cb(EXTDriver *extp, expchannel_t channel);
static void option_cb(EXTDriver *extp, expchannel_t channel);
Expand Down Expand Up @@ -69,6 +73,8 @@ typedef enum {
} dv_mode;
static char current_mode = MODE_SERIAL;

#define REFRESH_RATE 50 // in ms

static void print_mcu_info(void) {
uint32_t sdid = SIM->SDID;
const char *famid[] = {
Expand Down Expand Up @@ -113,6 +119,24 @@ static void print_mcu_info(void) {
pins[(sdid >> 0) & 15]);
}

static void led_cb(void *arg) {
(void) arg;

palTogglePad(GPIOA, 6);
chSysLockFromISR();
chVTSetI(&led_vt, MS2ST(500), led_cb, NULL);
chSysUnlockFromISR();
}

static void refresh_cb(void *arg) {
(void) arg;

chSysLockFromISR();
chVTSetI(&refresh_vt, MS2ST(REFRESH_RATE), refresh_cb, NULL);
chEvtBroadcastI(&refresh_event);
chSysUnlockFromISR();
}

static void mode_cb(EXTDriver *extp, expchannel_t channel) {
(void)extp;
(void)channel;
Expand All @@ -129,45 +153,29 @@ static void adc_celcius_handler(eventid_t id) {
chprintf(stream, "celcius: %d\n\r", analogReadTemperature());
}

static void update_handler(eventid_t id) {
static void refresh_handler(eventid_t id) {
(void) id;

switch(current_mode) {
case MODE_SERIAL:
updateSerialScreen();
break;
default:
break;
}
}

void init_update_events(void) {
chEvtObjectInit(&ta_update_event);
evtTableHook(orchard_app_events, ta_update_event, update_handler);
static void serial_handler(eventid_t id) {
(void) id;
dvDoSerial();
}

static thread_t *blink_tp = NULL;
static THD_WORKING_AREA(waEvHandlerThread, 96);
static thread_t *evHandler_tp = NULL;
static THD_WORKING_AREA(waEvHandlerThread, 0x500);

static THD_FUNCTION(evHandlerThread, arg) {
(void)arg;

chRegSetThreadName("Event dispatcher");
while(true) {
chEvtDispatch(evtHandlers(orchard_app_events), chEvtWaitOne(ALL_EVENTS));
}
}

/*
* Application entry point.
*/
int main(void)
{
/*
* System initializations.
* - HAL initialization, this also initializes the configured device drivers
* and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
*/
halInit();
chSysInit();

// set this low here in case something crashes later on, at least we have the LED on to indicate power-on
palWritePad(GPIOA, 6, PAL_LOW); // mcu_led

adcStart(&ADCD1, &adccfg1);
analogStart();
Expand All @@ -181,26 +189,13 @@ int main(void)
print_mcu_info();
chprintf(stream, "free memory at boot: %d bytes\r\n", chCoreGetStatusX());

orchardGfxInit();
oledOrchardBanner();

// orchardShellRestart();

evtTableInit(orchard_app_events, 9);

init_update_events();

chEvtObjectInit(&adc_celcius_event);
evtTableHook(orchard_app_events, adc_celcius_event, adc_celcius_handler);

// chEvtObjectInit(&accel_event);
// evtTableHook(orchard_app_events, accel_event, accel_irq);
// accelStart(i2cDriver);
chEvtObjectInit(&refresh_event);
evtTableHook(orchard_app_events, refresh_event, refresh_handler);

// chEvtObjectInit(&accel_test_event);
// evtTableHook(orchard_app_events, accel_test_event, accel_test);

// evtTableHook(orchard_app_events, accel_pulse, accel_pulse_handler);
chEvtObjectInit(&serial_event);
evtTableHook(orchard_app_events, serial_event, serial_handler);

extStart(&EXTD1, &ext_config); // enables interrupts on gpios

Expand All @@ -209,27 +204,48 @@ int main(void)
// palWritePad(GPIOB, 13,PAL_HIGH); // oled_dc

// palWritePad(GPIOB, 11,PAL_HIGH); // oled_res
orchardGfxInit();
oledOrchardBanner();

chprintf(stream, "free memory after gfx init: %d bytes\r\n", chCoreGetStatusX());

blink_tp = chThdCreateStatic(waEvHandlerThread, sizeof(waEvHandlerThread), NORMALPRIO - 20, evHandlerThread, NULL);
// start refreshing the screen
chVTObjectInit(&refresh_vt);
chVTSet(&refresh_vt, MS2ST(REFRESH_RATE), refresh_cb, NULL);

chprintf(stream, "free memory into main loop: %d bytes\r\n", chCoreGetStatusX());
serial_init = 1;

dvInit();
while(true) {
chEvtDispatch(evtHandlers(orchard_app_events), chEvtWaitOne(ALL_EVENTS));
}
}

/*
* Application entry point.
*/
int main(void)
{
/*
* System initializations.
* - HAL initialization, this also initializes the configured device drivers
* and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
*/
halInit();
chSysInit();

// set this low here in case something crashes later on, at least we have the LED on to indicate power-on
palWritePad(GPIOA, 6, PAL_LOW); // mcu_led

chVTObjectInit(&led_vt);
chVTSet(&led_vt, MS2ST(500), led_cb, NULL);

evHandler_tp = chThdCreateStatic(waEvHandlerThread, sizeof(waEvHandlerThread), NORMALPRIO + 10, evHandlerThread, NULL);

while (TRUE) {
switch(current_mode) {
case MODE_SERIAL:
dvDoSerial();
break;

default:
break;
}

// blink LED, without using a sleep function
if( (ST2MS(chVTGetSystemTimeX()) & 0x3FF) < 0x200 )
palWritePad(GPIOA, 6, PAL_LOW);
else
palWritePad(GPIOA, 6, PAL_HIGH);
// this is now an idle loop
}

}
Expand Down

0 comments on commit 58a90f4

Please sign in to comment.