8.5 KiB
8.5 KiB
| sub_title | auther | |||||||
|---|---|---|---|---|---|---|---|---|
| Real Time Systems 10 |
|
Week 1.3
assignment 3.1
base project opdr_2_1.
#include <stdint.h>
#define RCC_AHB1ENR_BIT_GPIODEN *(volatile uint32_t*)(0x42000000 + 0x00023830 * 32 + 3 * 4)
#define GPIOD_BASE 0x40020C00
#define GPIOD_MODER *(volatile uint32_t*)(GPIOD_BASE + 0x00)
#define GPIOD_ODR *(volatile uint32_t*)(GPIOD_BASE + 0x14)
#define STK_CTRL *(volatile uint32_t*)(0xE000E010)
#define STK_LOAD *(volatile uint32_t*)(0xE000E014)
int main(void)
{
// GPIO Port D Clock Enable
RCC_AHB1ENR_BIT_GPIODEN = 1;
// GPIO Port D Pin 15 down to 12 Push/Pull Output
GPIOD_MODER = 0x55000000;
// Set green and red LEDs
GPIOD_ODR = 0x5000;
// SysTick enable with clk source to AHB/8
STK_CTRL = (1<<2) | 1;
STK_LOAD = 500000; // 0.5 sec / (8 MHz / 8)
// Do forever:
while (1)
{
// Wait a moment
while ((STK_CTRL & (1 << 16)) == 0);
// Flip all LEDs
GPIOD_ODR ^= 0xF000;
}
}
assignment 3.2
#include <stdint.h>
#include <stm32f4xx.h>
int main(void)
{
// GPIO Port D Clock Enable
RCC->AHB1ENR = RCC_AHB1ENR_GPIODEN;
// GPIO Port D Pin 15 down to 12 Push/Pull Output
GPIOD->MODER = GPIO_MODER_MODER12_0
| GPIO_MODER_MODER13_0
| GPIO_MODER_MODER14_0
| GPIO_MODER_MODER15_0;
// Set green and red LEDs
GPIOD->ODR = GPIO_ODR_OD12 | GPIO_ODR_OD14;
// SysTick enable with clk source to AHB/8
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
SysTick->LOAD = 500000; // 0.5 sec / (8 MHz / 8)
// Do forever:
while (1)
{
// Wait a moment
while ((SysTick->CTRL & (1 << 16)) == 0);
// Flip all LEDs
GPIOD->ODR ^= GPIO_ODR_OD12
| GPIO_ODR_OD13
| GPIO_ODR_OD14
| GPIO_ODR_OD15;
}
}
assignment 3.3
#include <stdint.h>
#include <stdbool.h>
#define RCC_AHB1ENR_BIT_GPIODEN *(volatile uint32_t*)(0x42000000 + 0x00023830 * 32 + 3 * 4)
#define GPIOD_BASE 0x40020C00
#define GPIOD_MODER *(volatile uint32_t*)(GPIOD_BASE + 0x00)
#define GPIOD_ODR *(volatile uint32_t*)(GPIOD_BASE + 0x14)
#define STK_CTRL *(volatile uint32_t*)(0xE000E010)
#define STK_LOAD *(volatile uint32_t*)(0xE000E014)
volatile bool flag = false;
void SysTick_Handler()
{
flag = true;
}
int main(void)
{
// GPIO Port D Clock Enable
RCC_AHB1ENR_BIT_GPIODEN = 1;
// GPIO Port D Pin 15 down to 12 Push/Pull Output
GPIOD_MODER = 0x55000000;
// Set green and red LEDs
GPIOD_ODR = 0x5000;
// SysTick enable with interupt and clk source to AHB/8
STK_CTRL = (1<<1) | 1;
STK_LOAD = 500000; // 0.5 sec / (8 MHz / 8)
// Do forever:
while (1)
{
// Wait a moment
while (!flag)
{
__asm__(" WFI"); // sleep until SysTick
}
flag = false;
// Flip all LEDs
GPIOD_ODR ^= 0xF000;
}
}
C) Why must the flag variable be defined as volatile?
becouse the compiler doesn't know when flag changes. Without volatile optimisations can think it does not change at all.
assignment 3.4
#include <stdint.h>
#include <stm32f4xx.h>
#include <stdbool.h>
volatile bool flag = false;
void SysTick_Handler()
{
flag = true;
}
int main(void)
{
// GPIO Port D Clock Enable
RCC->AHB1ENR = RCC_AHB1ENR_GPIODEN;
// GPIO Port D Pin 15 down to 12 Push/Pull Output
GPIOD->MODER = GPIO_MODER_MODER12_0
| GPIO_MODER_MODER13_0
| GPIO_MODER_MODER14_0
| GPIO_MODER_MODER15_0;
// Set green and red LEDs
GPIOD->ODR = GPIO_ODR_OD12 | GPIO_ODR_OD14;
// SysTick enable with interupt and clk source to AHB/8
SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
SysTick->LOAD = 500000; // 0.5 sec / (8 MHz / 8)
// Do forever:
while (1)
{
// Wait a moment
while (!flag)
{
__asm__(" WFI"); // sleep until SysTick
}
flag = false;
// Flip all LEDs
GPIOD->ODR ^= GPIO_ODR_OD12
| GPIO_ODR_OD13
| GPIO_ODR_OD14
| GPIO_ODR_OD15;
}
}
assignment 3.5
#include <stdint.h>
#include <stm32f4xx.h>
#include <stdbool.h>
volatile bool flag = false;
void SysTick_Handler()
{
flag = true;
}
enum STATE {
STATE_GREEN,
STATE_ORANGE,
STATE_RED
};
int main(void)
{
// GPIO Port D Clock Enable
RCC->AHB1ENR = RCC_AHB1ENR_GPIODEN;
// GPIO Port D Pin 15 down to 12 Push/Pull Output
GPIOD->MODER = GPIO_MODER_MODER12_0
| GPIO_MODER_MODER13_0
| GPIO_MODER_MODER14_0
| GPIO_MODER_MODER15_0;
// Set green and red LEDs
GPIOD->ODR = GPIO_ODR_OD12 | GPIO_ODR_OD14;
// SysTick enable with interupt and clk source to AHB/8
SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
SysTick->LOAD = 500000; // 0.5 sec / (8 MHz / 8)
// time of each color in half seconds
const uint32_t time_green = 10; // 5 seconds
const uint32_t time_orange = 2; // 1 seconds
const uint32_t time_red = 8; // 4 seconds
uint32_t timer = time_green;
enum STATE State = STATE_GREEN;
// Do forever:
while (1)
{
// Wait a moment
while (!flag)
{
__asm__(" WFI"); // sleep until SysTick
}
flag = false;
timer--;
if (timer == 0)
{
// turn off all leds
GPIOD->ODR &= ~(GPIO_ODR_OD12
| GPIO_ODR_OD13
| GPIO_ODR_OD14
| GPIO_ODR_OD15);
switch (State) {
case STATE_GREEN:
State = STATE_ORANGE;
GPIOD->ODR |= GPIO_ODR_OD13;
timer = time_orange;
break;
case STATE_ORANGE:
State = STATE_RED;
GPIOD->ODR |= GPIO_ODR_OD14;
timer = time_red;
break;
case STATE_RED:
State = STATE_GREEN;
GPIOD->ODR |= GPIO_ODR_OD12;
timer = time_green;
break;
}
}
}
}
assignment 3.6
#include <stdint.h>
#include <stm32f4xx.h>
#include <stdbool.h>
volatile uint32_t ISR_Ticks = 0;
struct TASK {
void* fn,
uint32_t counter,
uint32_t counter_rst
};
uint8_t Tasks_len = 0;
struct TASK Tasks[8];
void SysTick_Handler()
{
ISR_Ticks++;
}
bool addTask(void* fn, uint32_t counter)
{
if (Tasks_len >= 8) {
return false;
}
Tasks[Task_len].fn = fn;
Tasks[Task_len].counter = counter;
Tasks[Task_len].counter_rst = counter;
Tasks_len++;
return true;
}
void taskGreen()
{
GPIOD->ODR ^= GPIO_ODR_OD12;
}
void taskOrange()
{
GPIOD->ODR ^= GPIO_ODR_OD13;
}
void taskRed()
{
GPIOD->ODR ^= GPIO_ODR_OD14;
}
void taskBlue()
{
GPIOD->ODR ^= GPIO_ODR_OD15;
}
enum STATE {
STATE_GREEN,
STATE_ORANGE,
STATE_RED
};
int main(void)
{
// GPIO Port D Clock Enable
RCC->AHB1ENR = RCC_AHB1ENR_GPIODEN;
// GPIO Port D Pin 15 down to 12 Push/Pull Output
GPIOD->MODER = GPIO_MODER_MODER12_0
| GPIO_MODER_MODER13_0
| GPIO_MODER_MODER14_0
| GPIO_MODER_MODER15_0;
// Set all leds off
GPIOD->ODR = 0;
// SysTick enable with interupt and clk source to AHB/8
SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
SysTick->LOAD = 1000; // 1 ms / (8 MHz / 8)
addTask(*taskGreen, 200);
addTask(*taskOrange, 500);
addTask(*taskRed, 750);
addTask(*taskBlue, 300);
// Do forever:
while (1)
{
// Wait a moment
while (ISR_Ticks != 0)
{
__asm__(" WFI"); // sleep until SysTick
}
uint32_t ticks = ISR_Ticks;
ISR_Ticks = 0;
for (uint8_t int=0; i<Tasks_len; i++)
{
if (Tasks[i].counter > ticks)
{
Tasks[i].counter -= ticks;
}
else
{
Tasks[i].counter = 0;
}
}
for (uint8_t int=0; i<Tasks_len; i++)
{
if (Tasks[i].counter == 0)
{
(&(Tasks[i].fn))();
}
}
}
}