Project added for completion
This commit is contained in:
parent
47d08fa8f6
commit
83189c41da
|
@ -0,0 +1,106 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "rtos.h"
|
||||||
|
|
||||||
|
#include "clock.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "timer_a1.h"
|
||||||
|
|
||||||
|
#include "inc/msp432p401r.h"
|
||||||
|
|
||||||
|
#define THREADS 2
|
||||||
|
#define PERIODIC_THREADS 2
|
||||||
|
#define SIZE 100
|
||||||
|
|
||||||
|
typedef struct Tcb {
|
||||||
|
int32_t *sp; // stack pointer
|
||||||
|
struct Tcb *next; // linked-list
|
||||||
|
int32_t *blocked; // shows on which semaphore it is blocked
|
||||||
|
} Tcb_t;
|
||||||
|
|
||||||
|
PeriodicEvent_t periodic_event_threads[PERIODIC_THREADS];
|
||||||
|
|
||||||
|
Tcb_t tcbs[THREADS];
|
||||||
|
Tcb_t *run_pt;
|
||||||
|
int32_t stacks[THREADS][SIZE];
|
||||||
|
|
||||||
|
void RunPeriodicEvents(void);
|
||||||
|
|
||||||
|
void __attribute__((naked))
|
||||||
|
SysTick_Handler(void) { // 1) Saves R0-R3,R12,LR,PC,PSR
|
||||||
|
__asm( // 2) Prevent interrupt during switch
|
||||||
|
// 3) Save remaining regs r4-11
|
||||||
|
// 4) R0=pointer to run_pt, old thread
|
||||||
|
// 5) Save SP into TCB
|
||||||
|
// 6) R1 = run_pt, new thread
|
||||||
|
// 7) new thread SP; SP = run_pt->sp;
|
||||||
|
// 8) restore regs r4-11
|
||||||
|
// 9) tasks run with interrupts enabled
|
||||||
|
); // 10) restore R0-R3,R12,LR,PC,PSR
|
||||||
|
}
|
||||||
|
|
||||||
|
void __attribute__((naked))
|
||||||
|
StartOS(void) {
|
||||||
|
__asm(// currently running thread
|
||||||
|
// R2 = value of run_pt
|
||||||
|
// new thread SP; SP = run_pt->sp;
|
||||||
|
// restore regs r4-11
|
||||||
|
// restore regs r0-3
|
||||||
|
// discard LR from initial stack
|
||||||
|
// start location
|
||||||
|
// discard PSR
|
||||||
|
// Enable interrupts at processor level
|
||||||
|
); // start first thread
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetInitialStack(int idx) {
|
||||||
|
// Write this code
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize operating system, disable interrupts
|
||||||
|
// Initialize OS controlled I/O: systick, bus clock as fast as possible
|
||||||
|
void RoundRobinInit(void) {
|
||||||
|
CPU_cpsid();
|
||||||
|
ClockInit48MHz();
|
||||||
|
// Write TimerA1Init here 1000 Hz
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddThreads(void (**threads)(void)) {
|
||||||
|
// Write this code
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddPeriodicEventThreads(PeriodicEvent_t *periodic_events) {
|
||||||
|
// Write this code
|
||||||
|
}
|
||||||
|
|
||||||
|
void RoundRobinLaunch(uint32_t time_slice_cycles) {
|
||||||
|
SysTick->CTRL = 0; // 1) disable SysTick during setup
|
||||||
|
SysTick->LOAD = time_slice_cycles - 1; // 2) reload value sets period
|
||||||
|
SysTick->VAL = 0; // 3) any write to current clears it
|
||||||
|
SCB->SHP[11] = 7 << 5; // set priority into top 3 bits of 8-bit register
|
||||||
|
SysTick->CTRL = 0x00000007; // 4) enable SysTick with core clock and interrupts
|
||||||
|
StartOS(); // start on the first task
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunPeriodicEvents(void) {
|
||||||
|
// Write this code (no sleep decreasing)
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scheduler(void) {
|
||||||
|
// Write this code (no sleep check)
|
||||||
|
}
|
||||||
|
|
||||||
|
void Suspend(void) {
|
||||||
|
SysTick->VAL = 0; // any write to current clears it
|
||||||
|
SCB->ICSR |= SCB_ICSR_PENDSTSET_Msk; // trigger SysTick
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrement semaphore
|
||||||
|
void Wait(int32_t *sema_pt) {
|
||||||
|
// Write this code similar to RTOS3
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment semaphore
|
||||||
|
void Signal(int32_t *sema_pt) {
|
||||||
|
// Write this code similar to RTOS3
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef RTOS_H
|
||||||
|
#define RTOS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct PeriodicEvent {
|
||||||
|
void (*event)(void);
|
||||||
|
uint32_t period_ms;
|
||||||
|
} PeriodicEvent_t;
|
||||||
|
|
||||||
|
void RoundRobinInit(void);
|
||||||
|
void AddThreads(void (**threads)(void));
|
||||||
|
void AddPeriodicEventThreads(PeriodicEvent_t *periodic_events);
|
||||||
|
void RoundRobinLaunch(uint32_t time_slice_cycles);
|
||||||
|
void Wait(int32_t *sema_pt);
|
||||||
|
void Signal(int32_t *sema_pt);
|
||||||
|
|
||||||
|
#endif /* RTOS_H */
|
|
@ -0,0 +1,77 @@
|
||||||
|
CC = arm-none-eabi-gcc
|
||||||
|
|
||||||
|
# The location of the C compiler
|
||||||
|
# ARMGCC_ROOT is used by some makefiles that need to know where the compiler
|
||||||
|
# is installed.
|
||||||
|
ARMGCC_BIN := ${shell which ${CC}}
|
||||||
|
ifeq (${shell test -h ${ARMGCC_BIN} && echo "true" || echo "false"}, true)
|
||||||
|
ARMGCC_ROOT := ${shell dirname ${shell readlink ${ARMGCC_BIN}}}/..
|
||||||
|
else
|
||||||
|
ARMGCC_ROOT := ${shell dirname ${ARMGCC_BIN}}/..
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Search for source files that are not in this directory
|
||||||
|
VPATH = ../common/
|
||||||
|
|
||||||
|
OBJECTS = main.o rtos.o timer_a1.o bump.o reflectance.o delay.o motor.o pwm.o cpu.o clock.o system.o startup.o syscalls.o
|
||||||
|
|
||||||
|
NAME = lab
|
||||||
|
|
||||||
|
CFLAGS = -I.. -I../inc -I../common \
|
||||||
|
-D__MSP432P401R__ \
|
||||||
|
-DDeviceFamily_MSP432P401x \
|
||||||
|
-mcpu=cortex-m4 \
|
||||||
|
-march=armv7e-m \
|
||||||
|
-mthumb \
|
||||||
|
-std=c99 \
|
||||||
|
-mfloat-abi=hard \
|
||||||
|
-mfpu=fpv4-sp-d16 \
|
||||||
|
-ffunction-sections \
|
||||||
|
-fdata-sections \
|
||||||
|
-gstrict-dwarf \
|
||||||
|
-Wall \
|
||||||
|
-I$(ARMGCC_ROOT)/arm-none-eabi/include/newlib-nano \
|
||||||
|
-I$(ARMGCC_ROOT)/arm-none-eabi/include
|
||||||
|
|
||||||
|
LFLAGS = -Wl,-T,../config.lds \
|
||||||
|
-Wl,-Map,$(NAME).map \
|
||||||
|
-march=armv7e-m \
|
||||||
|
-mthumb \
|
||||||
|
-mfloat-abi=hard \
|
||||||
|
-mfpu=fpv4-sp-d16 \
|
||||||
|
-static \
|
||||||
|
-Wl,--gc-sections \
|
||||||
|
-lgcc \
|
||||||
|
-lc \
|
||||||
|
-lm \
|
||||||
|
-lnosys \
|
||||||
|
--specs=nano.specs
|
||||||
|
|
||||||
|
all: $(NAME).out
|
||||||
|
@echo "SUCCESS: Compilation completed successfully."
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
@$(CC) $(CFLAGS) -g $< -c -o $@
|
||||||
|
|
||||||
|
cpu.o: ../common/cpu.c
|
||||||
|
@$(CC) $(CFLAGS) $< -c -o $@
|
||||||
|
|
||||||
|
clock.o: ../common/clock.c
|
||||||
|
@$(CC) $(CFLAGS) $< -c -o $@
|
||||||
|
|
||||||
|
system.o: ../system.c
|
||||||
|
@$(CC) $(CFLAGS) $< -c -o $@
|
||||||
|
|
||||||
|
startup.o: ../startup.c
|
||||||
|
@$(CC) $(CFLAGS) $< -c -o $@
|
||||||
|
|
||||||
|
syscalls.o: ../syscalls.c
|
||||||
|
@$(CC) $(CFLAGS) $< -c -o $@
|
||||||
|
|
||||||
|
$(NAME).out: $(OBJECTS)
|
||||||
|
@$(CC) $(OBJECTS) $(LFLAGS) -o $(NAME).out
|
||||||
|
|
||||||
|
clean: # Redirecting both the stderr and stdout to /dev/null
|
||||||
|
@rm -f $(OBJECTS) > /dev/null 2>&1
|
||||||
|
@rm -f $(NAME).out > /dev/null 2>&1
|
||||||
|
@rm -f $(NAME).map > /dev/null 2>&1
|
|
@ -0,0 +1,107 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "rtos.h"
|
||||||
|
#include "pwm.h"
|
||||||
|
#include "bump.h"
|
||||||
|
#include "reflectance.h"
|
||||||
|
#include "motor.h"
|
||||||
|
#include "delay.h"
|
||||||
|
|
||||||
|
#include "inc/msp432p401r.h"
|
||||||
|
|
||||||
|
// bit-banded addresses, positive logic
|
||||||
|
#define SW2IN ((*((volatile uint8_t *)(0x42098010)))^1)
|
||||||
|
#define SW1IN ((*((volatile uint8_t *)(0x42098004)))^1)
|
||||||
|
|
||||||
|
// bit-banded address
|
||||||
|
#define REDLED (*((volatile uint8_t *)(0x42098040)))
|
||||||
|
|
||||||
|
// bit-banded addresses
|
||||||
|
#define BLUEOUT (*((volatile uint8_t *)(0x42098068)))
|
||||||
|
#define GREENOUT (*((volatile uint8_t *)(0x42098064)))
|
||||||
|
#define REDOUT (*((volatile uint8_t *)(0x42098060)))
|
||||||
|
|
||||||
|
#define START_REFLECTANCE 9
|
||||||
|
|
||||||
|
int32_t bump_pressed; // semaphore
|
||||||
|
|
||||||
|
uint8_t bump_data, reflectance_data;
|
||||||
|
|
||||||
|
void SwitchInit(void) {
|
||||||
|
P1->SEL0 &= ~0x12;
|
||||||
|
P1->SEL1 &= ~0x12; // 1) configure P1.4 and P1.1 as GPIO
|
||||||
|
P1->DIR &= ~0x12; // 2) make P1.4 and P1.1 in
|
||||||
|
P1->REN |= 0x12; // 3) enable pull resistors on P1.4 and P1.1
|
||||||
|
P1->OUT |= 0x12; // P1.4 and P1.1 are pull-up
|
||||||
|
}
|
||||||
|
|
||||||
|
void RedLEDInit(void) {
|
||||||
|
P1->SEL0 &= ~0x01;
|
||||||
|
P1->SEL1 &= ~0x01; // 1) configure P1.0 as GPIO
|
||||||
|
P1->DIR |= 0x01; // 2) make P1.0 out
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorLEDInit(void) {
|
||||||
|
P2->SEL0 &= ~0x07;
|
||||||
|
P2->SEL1 &= ~0x07; // 1) configure P2.2-P2.0 as GPIO
|
||||||
|
P2->DIR |= 0x07; // 2) make P2.2-P2.0 out
|
||||||
|
P2->DS |= 0x07; // 3) activate increased drive strength
|
||||||
|
P2->OUT &= ~0x07; // all LEDs off
|
||||||
|
}
|
||||||
|
|
||||||
|
void Task1(void) {
|
||||||
|
while (true) {
|
||||||
|
if (SW1IN && SW2IN) {
|
||||||
|
GREENOUT = 1;
|
||||||
|
} else {
|
||||||
|
GREENOUT = 0;
|
||||||
|
}
|
||||||
|
if (SW1IN || SW2IN) {
|
||||||
|
REDLED = 1;
|
||||||
|
} else {
|
||||||
|
REDLED = 0;
|
||||||
|
}
|
||||||
|
if (SW1IN) {
|
||||||
|
BLUEOUT = 1;
|
||||||
|
} else {
|
||||||
|
BLUEOUT = 0;
|
||||||
|
}
|
||||||
|
if (SW2IN) {
|
||||||
|
REDOUT = 1;
|
||||||
|
} else {
|
||||||
|
REDOUT = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Task2(void) {
|
||||||
|
while (true) {
|
||||||
|
// Motor goes forward and waits until bump is pressed
|
||||||
|
// When pressed, go backward for some time and turn left for some time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Task3(void) {
|
||||||
|
// Read reflectance similar to Lab 3
|
||||||
|
}
|
||||||
|
|
||||||
|
void Task4(void) {
|
||||||
|
// Read bump and signal if any pressed
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
BumpInit();
|
||||||
|
ReflectanceInit();
|
||||||
|
PWMInitMotor(?);
|
||||||
|
MotorInit();
|
||||||
|
RedLEDInit();
|
||||||
|
ColorLEDInit();
|
||||||
|
SwitchInit();
|
||||||
|
RoundRobinInit();
|
||||||
|
AddThreads((void (*[])(void)){Task1, Task2});
|
||||||
|
AddPeriodicEventThreads((PeriodicEvent_t []){{Task3, 1}, {Task4, 100}});
|
||||||
|
RoundRobinLaunch(48000); // 1ms
|
||||||
|
return 0; // never executes
|
||||||
|
}
|
Loading…
Reference in New Issue