Skip to content
Snippets Groups Projects
Commit 70a199c0 authored by Sergi Hernandez's avatar Sergi Hernandez
Browse files

Added the implementation of a scheduler to call functions at given periods using a timer.

parent 5f948ff9
No related branches found
No related tags found
No related merge requests found
# setup
# modified by zerom for WinARM 8/2010
COMPILE_OPTS = -mlittle-endian -mthumb -mthumb-interwork
COMPILE_OPTS += -Wall -O2 -fno-common
#COMPILE_OPTS += -Wall -g -fno-common
COMPILE_OPTS += -ffreestanding -nostdlib
COMPILE_OPTS_M4_FPU = -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mcpu=cortex-m4
COMPILE_OPTS_M0 = -mfloat-abi=softfp -mcpu=cortex-m0
COMPILE_OPTS_M0plus = -mfloat-abi=softfp -mcpu=cortex-m0plus
COMPILE_OPTS_M3 = -mfloat-abi=softfp -mcpu=cortex-m3
INCLUDE_DIRS = -I./include/ -I../utils/include
DOC_DIR = ./doc
TCHAIN_PREFIX=arm-none-eabi-
CC = $(TCHAIN_PREFIX)gcc
CFLAGS = $(COMPILE_OPTS) $(INCLUDE_DIRS)
AR = $(TCHAIN_PREFIX)ar
ARFLAGS = cr
SCHEDULER_OUT_M4_FPU = ./lib/scheduler_m4_fpu.a
SCHEDULER_OUT_M0 = ./lib/scheduler_m0.a
SCHEDULER_OUT_M0plus = ./lib/scheduler_m0plus.a
SCHEDULER_OUT_M3 = ./lib/scheduler_m3.a
SRC_DIR=./src/
SRC=$(wildcard $(SRC_DIR)*.c)
SCHEDULER_M4_FPU_OBJ_DIR=build/m4_fpu/
SCHEDULER_M4_FPU_OBJS_TMP = $(notdir $(SRC:.c=.o))
SCHEDULER_M4_FPU_OBJS = $(patsubst %,$(SCHEDULER_M4_FPU_OBJ_DIR)%,$(SCHEDULER_M4_FPU_OBJS_TMP))
SCHEDULER_M0_OBJ_DIR=build/m0/
SCHEDULER_M0_OBJS_TMP = $(notdir $(SRC:.c=.o))
SCHEDULER_M0_OBJS = $(patsubst %,$(SCHEDULER_M0_OBJ_DIR)%,$(SCHEDULER_M0_OBJS_TMP))
SCHEDULER_M0plus_OBJ_DIR=build/m0plus/
SCHEDULER_M0plus_OBJS_TMP = $(notdir $(SRC:.c=.o))
SCHEDULER_M0plus_OBJS = $(patsubst %,$(SCHEDULER_M0plus_OBJ_DIR)%,$(SCHEDULER_M0plus_OBJS_TMP))
SCHEDULER_M3_OBJ_DIR=build/m3/
SCHEDULER_M3_OBJS_TMP = $(notdir $(SRC:.c=.o))
SCHEDULER_M3_OBJS = $(patsubst %,$(SCHEDULER_M3_OBJ_DIR)%,$(SCHEDULER_M3_OBJS_TMP))
all: $(SCHEDULER_OUT_M4_FPU) $(SCHEDULER_OUT_M0) $(SCHEDULER_OUT_M0plus) $(SCHEDULER_OUT_M3)
$(SCHEDULER_M4_FPU_OBJ_DIR)%.o: $(SRC_DIR)%.c
$(CC) -c $(CFLAGS) $(COMPILE_OPTS_M4_FPU) -o $@ $<
$(SCHEDULER_M0_OBJ_DIR)%.o: $(SRC_DIR)%.c
$(CC) -c $(CFLAGS) $(COMPILE_OPTS_M0) -o $@ $<
$(SCHEDULER_M0plus_OBJ_DIR)%.o: $(SRC_DIR)%.c
$(CC) -c $(CFLAGS) $(COMPILE_OPTS_M0plus) -o $@ $<
$(SCHEDULER_M3_OBJ_DIR)%.o: $(SRC_DIR)%.c
$(CC) -c $(CFLAGS) $(COMPILE_OPTS_M3) -o $@ $<
mkdir_build:
mkdir -p build/m4_fpu
mkdir -p build/m0
mkdir -p build/m0plus
mkdir -p build/m3
$(SCHEDULER_OUT_M4_FPU): mkdir_build $(SCHEDULER_M4_FPU_OBJS)
mkdir -p lib
$(AR) $(ARFLAGS) $@ $(SCHEDULER_M4_FPU_OBJS)
$(SCHEDULER_OUT_M0): mkdir_build $(SCHEDULER_M0_OBJS)
mkdir -p lib
$(AR) $(ARFLAGS) $@ $(SCHEDULER_M0_OBJS)
$(SCHEDULER_OUT_M0plus): mkdir_build $(SCHEDULER_M0plus_OBJS)
mkdir -p lib
$(AR) $(ARFLAGS) $@ $(SCHEDULER_M0plus_OBJS)
$(SCHEDULER_OUT_M3): mkdir_build $(SCHEDULER_M3_OBJS)
mkdir -p lib
$(AR) $(ARFLAGS) $@ $(SCHEDULER_M3_OBJS)
doc:
doxygen $(DOC_DIR)/doxygen.conf
clean:
rm -f $(SCHEDULER_M4_FPU_OBJS)
rm -f $(SCHEDULER_M0_OBJS)
rm -f $(SCHEDULER_M0plus_OBJS)
rm -f $(SCHEDULER_M3_OBJS)
rm -rf lib
rm -rf build
rm -rf doc/html
.PHONY: all clean doc
#ifndef _SCHEDULER_H
#define _SCHEDULER_H
#ifndef SCHEDULER_MAX_CHANNELS
#define SCHEDULER_MAX_CHANNELS 4
#endif
#ifndef TIM_CHANNEL_1
#define TIM_CHANNEL_1 0x00000000U
#endif
#ifndef TIM_CHANNEL_2
#define TIM_CHANNEL_2 0x00000004U
#endif
#ifndef TIM_CHANNEL_3
#define TIM_CHANNEL_3 0x00000008U
#endif
#ifndef TIM_CHANNEL_4
#define TIM_CHANNEL_4 0x0000000CU
#endif
typedef enum {SCHED_CH1=0,SCHED_CH2=1,SCHED_CH3=2,SCHED_CH4=3} sched_channel_t;
typedef struct{
void (*function)(void);
unsigned char period_ms;
unsigned int pulse;
unsigned char enabled;
}TSchedulerChannel;
typedef struct{
TSchedulerChannel channels[SCHEDULER_MAX_CHANNELS];
unsigned char num_channels;
unsigned short int prescaler;
void (* start)(sched_channel_t);
void (* stop)(sched_channel_t);
void (* set_pulse)(sched_channel_t,unsigned short,unsigned char);
}TScheduler;
void scheduler_init(TScheduler *scheduler,unsigned char num_channels, unsigned short int prescaler);
void scheduler_interrupt(TScheduler *scheduler,sched_channel_t channel_id);
unsigned short int scheduler_get_pulse(TScheduler *scheduler, sched_channel_t channel_id);
void scheduler_set_channel(TScheduler *scheduler,sched_channel_t channel_id, void (*function)(void), unsigned char period_ms);
void scheduler_enable_channel(TScheduler *scheduler,sched_channel_t channel_id);
void scheduler_change_period(TScheduler *scheduler,sched_channel_t channel_id,unsigned char period_ms);
void scheduler_disable_channel(TScheduler *scheduler,sched_channel_t channel_id);
#endif
#include "scheduler.h"
extern unsigned int SystemCoreClock;
/* private functions */
unsigned short int scheduler_ms_to_pulse(TScheduler *scheduler,unsigned char period_ms)
{
return (SystemCoreClock/(scheduler->prescaler*1000))*period_ms;
}
unsigned int scheduler_get_channel(sched_channel_t channel_id)
{
switch(channel_id)
{
case SCHED_CH1: return TIM_CHANNEL_1;
case SCHED_CH2: return TIM_CHANNEL_2;
case SCHED_CH3: return TIM_CHANNEL_3;
case SCHED_CH4: return TIM_CHANNEL_4;
default: return TIM_CHANNEL_1;
}
}
void scheduler_init(TScheduler *scheduler,unsigned char num_channels, unsigned short int prescaler)
{
unsigned char i=0;
for(i=0;i<SCHEDULER_MAX_CHANNELS;i++)
{
scheduler->channels[i].function=0x00000000;
scheduler->channels[i].period_ms=0;
scheduler->channels[i].enabled=0x00;
}
scheduler->num_channels=num_channels;
scheduler->prescaler=prescaler;
scheduler->stop=0x00000000;
scheduler->start=0x00000000;
scheduler->set_pulse=0x00000000;
}
void scheduler_interrupt(TScheduler *scheduler,sched_channel_t channel_id)
{
if(channel_id<scheduler->num_channels)
{
if(scheduler->set_pulse!=0x00000000)
scheduler->set_pulse(channel_id,scheduler->channels[channel_id].pulse,0x01);
if(scheduler->channels[channel_id].function!=0x00000000)
scheduler->channels[channel_id].function();
}
}
void scheduler_set_channel(TScheduler *scheduler,sched_channel_t channel_id, void (*function)(void), unsigned char period_ms)
{
if(channel_id<scheduler->num_channels)
{
if(scheduler->channels[channel_id].enabled==0x01)
{
if(scheduler->stop!=0x00000000)
scheduler->stop(channel_id);
scheduler->channels[channel_id].enabled=0x00;
}
scheduler->channels[channel_id].function=function;
scheduler->channels[channel_id].period_ms=period_ms;
scheduler->channels[channel_id].pulse=scheduler_ms_to_pulse(scheduler,period_ms);
}
}
void scheduler_enable_channel(TScheduler *scheduler,sched_channel_t channel_id)
{
if(channel_id<scheduler->num_channels)
{
if(scheduler->channels[channel_id].enabled==0x00)
{
if(scheduler->set_pulse!=0x00000000)
scheduler->set_pulse(channel_id,scheduler->channels[channel_id].pulse,0x00);
if(scheduler->start!=0x00000000)
scheduler->start(channel_id);
scheduler->channels[channel_id].enabled=0x01;
}
}
}
void scheduler_change_period(TScheduler *scheduler,sched_channel_t channel_id,unsigned char period_ms)
{
if(channel_id<scheduler->num_channels)
scheduler->channels[channel_id].period_ms=period_ms;
}
void scheduler_disable_channel(TScheduler *scheduler,sched_channel_t channel_id)
{
if(channel_id<scheduler->num_channels)
{
if(scheduler->channels[channel_id].enabled==0x01)
{
if(scheduler->stop!=0x00000000)
scheduler->stop(channel_id);
scheduler->channels[channel_id].enabled=0x0;
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment