Project added for completion

This commit is contained in:
AntonJ 2025-05-16 18:26:59 +03:00
parent 47d08fa8f6
commit 83189c41da
4 changed files with 308 additions and 0 deletions

106
common/rtos.c Normal file
View File

@ -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
}

18
common/rtos.h Normal file
View File

@ -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 */

77
project/Makefile Normal file
View File

@ -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

107
project/main.c Normal file
View File

@ -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
}