From 83189c41daba1bb156cd2953b8547ce9225db246 Mon Sep 17 00:00:00 2001 From: AntonJ Date: Fri, 16 May 2025 18:26:59 +0300 Subject: [PATCH] Project added for completion --- common/rtos.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++ common/rtos.h | 18 ++++++++ project/Makefile | 77 ++++++++++++++++++++++++++++++++++ project/main.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 308 insertions(+) create mode 100644 common/rtos.c create mode 100644 common/rtos.h create mode 100644 project/Makefile create mode 100644 project/main.c diff --git a/common/rtos.c b/common/rtos.c new file mode 100644 index 0000000..0668e65 --- /dev/null +++ b/common/rtos.c @@ -0,0 +1,106 @@ +#include + +#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 +} \ No newline at end of file diff --git a/common/rtos.h b/common/rtos.h new file mode 100644 index 0000000..938e917 --- /dev/null +++ b/common/rtos.h @@ -0,0 +1,18 @@ +#ifndef RTOS_H +#define RTOS_H + +#include + +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 */ \ No newline at end of file diff --git a/project/Makefile b/project/Makefile new file mode 100644 index 0000000..8f7d6c0 --- /dev/null +++ b/project/Makefile @@ -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 diff --git a/project/main.c b/project/main.c new file mode 100644 index 0000000..c2bc3b6 --- /dev/null +++ b/project/main.c @@ -0,0 +1,107 @@ +#include +#include +#include + +#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 +} \ No newline at end of file