Cleanup 2

pull/1/head
Felix Kopp 4 years ago
parent 7a6c34b14e
commit 424f5a902f
No known key found for this signature in database
GPG Key ID: C478BA0A85F75728

@ -27,7 +27,8 @@ ARDIX_ARCH_PWD = $(PWD)/arch/at91sam3x8e
ARDIX_SOURCES += \
$(ARDIX_ARCH_PWD)/sched.c \
$(ARDIX_ARCH_PWD)/startup.c
$(ARDIX_ARCH_PWD)/startup.c \
$(ARDIX_ARCH_PWD)/sys.c
ARDIX_ASM_SOURCES += \
$(ARDIX_ARCH_PWD)/isr_pend_sv.S

@ -37,9 +37,12 @@ extern "C"
{
#endif /* __cplusplus */
/**
* Set the PENDSV bit in the system control block.
*/
static __always_inline void sched_pendsv_req(void)
{
SCB_ICSR |= SCB_PENDSVSET_MASK;
REG_SCB_ICSR |= REG_SCB_ICSR_PENDSVSET_BIT;
}
void isr_sys_tick(void)
@ -51,12 +54,42 @@ void isr_sys_tick(void)
sched_pendsv_req();
}
void sched_init_process_regs(struct reg_snapshot *reg_snap, void (*entry)(void))
{
memset(reg_snap, 0, sizeof(*reg_snap));
reg_snap->hw.lr = (void *)0xFFFFFFF9U;
reg_snap->hw.pc = entry;
reg_snap->hw.psr = 0x01000000U;
}
/**
* Set the NVIC priority grouping field in `AIRCR`.
* Only values from 0..7 are allowed, see the SAM3X documentation.
*
* @param prio_group: The new priority grouping value.
*/
static inline void sched_nvic_set_prio_group(uint32_t prio_group)
{
uint32_t reg_val = REG_SCB_AIRCR;
reg_val &= ~(REG_SCB_AIRCR_VECTKEY_MASK | REG_SCB_AIRCR_PRIGROUP_MASK);
reg_val = reg_val
| REG_SCB_AIRCR_VECTKEY_VAL(REG_SCB_AIRCR_VECTKEY_MAGIC)
| REG_SCB_AIRCR_PRIGROUP_VAL(prio_group);
REG_SCB_AIRCR = reg_val;
}
int sched_hwtimer_init(unsigned int freq)
{
uint32_t ticks = F_CPU / freq;
uint32_t ticks = sys_core_clock / freq;
if (ticks > REG_SYSTICK_LOAD_RELOAD_MASK)
return 1;
/* Ensure SysTick and PendSV are preemptive */
sched_nvic_set_prio_group(0b011);
REG_SYSTICK_LOAD = (ticks & REG_SYSTICK_LOAD_RELOAD_MASK) - 1;
REG_SYSTICK_VAL = 0U;
REG_SYSTICK_CTRL = REG_SYSTICK_CTRL_CLKSOURCE_BIT /* MCK */
@ -66,10 +99,20 @@ int sched_hwtimer_init(unsigned int freq)
return 0;
}
inline void sched_atomic_enter(void)
{
REG_SYSTICK_CTRL &= ~REG_SYSTICK_CTRL_ENABLE_BIT;
}
inline void sched_atomic_leave(bool resched)
{
REG_SYSTICK_CTRL |= REG_SYSTICK_CTRL_ENABLE_BIT;
}
void sched_exec_early(void)
{
REG_SYSTICK_VAL = 0U; /* Reset timer */
sched_pendsv_req();
}
#ifdef __cplusplus

@ -32,6 +32,8 @@
#include <ardix/string.h>
#include <toolchain.h>
uint32_t sys_core_clock = 4000000UL; /* default internal 4MHz RC oscillator */
int sys_init(void)
{
/*
@ -104,5 +106,6 @@ int sys_init(void)
/* turn osc write protection on again */
REG_PMC_WPMR |= REG_PMC_WPMR_WPEN_BIT;
sys_core_clock = 84000000UL;
return 0;
}

@ -29,8 +29,8 @@
#include <ardix/types.h>
/** CPU clock frequency in Hertz */
#define F_CPU 84000000UL
/** Current (volatile) system frequency in Hertz. */
extern uint32_t sys_core_clock;
/** Pointer size in bytes */
#define PTRSIZE 4
@ -150,21 +150,21 @@ struct reg_snapshot {
*/
/** UART Control Register */
#define REG_UART_CR (*(uint32_t *)0x400E0800U)
#define REG_UART_CR (*(uint32_t *)0x400E0800U)
/** UART Control Register Reset Status Bits bitmask (for `REG_UART_CR`) */
#define REG_RSTSTA_MASK ((uint32_t)1 << 8)
#define REG_UART_CR_RSTSTA_MASK ((uint32_t)1 << 8)
/** UART Control Register Transmitter Disable bitmaask (for `REG_UART_CR`) */
#define REG_TXDIS_MASK ((uint32_t)1 << 7)
#define REG_UART_CR_TXDIS_MASK ((uint32_t)1 << 7)
/** UART Control Register Transmitter Enable bitmaask (for `REG_UART_CR`) */
#define REG_TXEN_MASK ((uint32_t)1 << 6)
#define REG_UART_CS_TXEN_MASK ((uint32_t)1 << 6)
/** UART Control Register Receiver Disable bitmask (for `REG_UART_CR`) */
#define REG_RXDIS_MASK ((uint32_t)1 << 5)
#define REG_UART_CS_RXDIS_MASK ((uint32_t)1 << 5)
/** UART Control Register Receiver Enable bitmask (for `REG_UART_CR`) */
#define REG_RXEN_MASK ((uint32_t)1 << 4)
#define REG_UART_CS_RXEN_MASK ((uint32_t)1 << 4)
/** UART Control Register Reset Transmitter bitmask (for `REG_UART_CR`) */
#define REG_RSTTX_MASK ((uint32_t)1 << 3)
#define REG_UART_CS_RSTTX_MASK ((uint32_t)1 << 3)
/** UART Control Register Reset Receiver bitmask (for `REG_UART_CR`) */
#define REG_RSTRX_MASK ((uint32_t)1 << 2)
#define REG_UART_CS_RSTRX_MASK ((uint32_t)1 << 2)
/** UART Mode Register */
#define REG_UART_MR (*(uint32_t *)0x400E0804U)
@ -174,26 +174,47 @@ struct reg_snapshot {
*/
/** System Control Block: Interrupt Control and State Register */
#define SCB_ICSR (*(uint32_t *)0xE000ED04U)
/** ICSR PendSV set-pending bit bitmask (for `SCB_ICSR`) */
#define SCB_PENDSVSET_MASK ((uint32_t)1 << 28)
/** ICSR PendSV clear-pending bit bitmask (for `SCB_ICSR`) */
#define SCB_PENDSVCLR_MASK ((uint32_t)1 << 27)
/** ICSR SysTick exception set-pending bit bitmask (for `SCB_ICSR`) */
#define SCB_PENDSTSET_MASK ((uint32_t)1 << 26)
/** ICSR SysTick exception clear-pending bit bitmask (for `SCB_ICSR`) */
#define SCB_PENDSTCLR_MASK ((uint32_t)1 << 25)
/** ICSR Interrupt pending flag, excluding Faults bitmask (for `SCB_ICSR`) */
#define SCB_ISRPENDING_MASK ((uint32_t)1 << 22)
#define REG_SCB_ICSR (*(uint32_t *)0xE000ED04U)
/** ICSR PendSV set-pending bit bitmask */
#define REG_SCB_ICSR_PENDSVSET_BIT ((uint32_t)1 << 28)
/** ICSR PendSV clear-pending bit bitmask */
#define REG_SCB_ICSR_PENDSVCLR_BIT ((uint32_t)1 << 27)
/** ICSR SysTick exception set-pending bit bitmask */
#define REG_SCB_ICSR_PENDSTSET_BIT ((uint32_t)1 << 26)
/** ICSR SysTick exception clear-pending bit bitmask */
#define REG_SCB_ICSR_PENDSTCLR_BIT ((uint32_t)1 << 25)
/** ICSR Interrupt pending flag, excluding Faults bitmask */
#define REG_SCB_ICSR_ISRPENDING_BIT ((uint32_t)1 << 22)
/**
* ICSR bitmask for highest priority pending & enabled exception
* (for `SCB_ICSR`). The value is shifted 12 to the left.
*/
#define SCB_VECTPENDING_MASK ((uint32_t)0b1111111111u << 12)
/** ICSR bitmask for whether there are preempted active exceptions (for `SCB_ICSR`) */
#define SCB_RETTOBASE_MASK ((uint32_t)1 << 11)
/** ICSR active exception number bitmask (for `SCB_ICSR`) */
#define SCB_VECTACTIVE_MASK ((uint32_t)0b111111111u)
#define REG_SCB_ICSR_VECTPENDING_MASK ((uint32_t)0b1111111111u << 12)
#define REG_SCB_ICSR_VECTPENDING_VAL(x) \
( ((uint32_t)(x) << 12) & REG_SCB_ICSR_VECTPENDING_MASK )
/** ICSR bitmask for whether there are preempted active exceptions */
#define REG_SCB_ICSR_RETTOBASE_BIT ((uint32_t)1 << 11)
/** ICSR active exception number bitmask */
#define REG_SCB_ICSR_VECTACTIVE_MASK ((uint32_t)0b111111111u)
#define REG_SCB_ICSR_VECTACTIVE_VAL(x) \
((uint32_t)(x) & REG_SCB_ICSR_VECTACTIVE_MASK)
/*
* System Control Block:
* Application Interrupt and Reset Control Register
*/
/** Application Interrupt and Reset Control Register (AIRCR) */
#define REG_SCB_AIRCR (*(uint32_t *)0xE000ED0CU)
#define REG_SCB_AIRCR_VECTKEY_MASK ((uint32_t)0xFFFF << 16)
#define REG_SCB_AIRCR_VECTKEY_VAL(x) \
( ((uint32_t)(x) << 16) & REG_SCB_AIRCR_VECTKEY_MASK )
#define REG_SCB_AIRCR_VECTKEY_MAGIC 0x05FA
#define REG_SCB_AIRCR_ENDIANESS_BIT ((uint32_t)1 << 15)
#define REG_SCB_AIRCR_PRIGROUP_MASK ((uint32_t)0x3 << 8)
#define REG_SCB_AIRCR_PRIGROUP_VAL(x) \
( ((uint32_t)(x) << 8) & REG_SCB_AIRCR_PRIGROUP_MASK )
#define REG_SCB_AIRCR_SYSRESETREQ_BIT ((uint32_t)1 << 2)
/*
* Enhanced Embedded Flash Controller (EEFC)

@ -45,7 +45,7 @@
#endif
enum proc_state {
/** Process is dead / ddoesn't exist */
/** Process is dead / doesn't exist */
PROC_DEAD,
/** Process is ready for execution or currently running. */
PROC_READY,
@ -131,3 +131,13 @@ void msleep(unsigned long int msecs);
* @param usecs: The amount of microseconds to halt the CPU for.
*/
void atomic_udelay(unsigned long int usecs);
/**
* Attempt to acquire an atomic lock.
*
* @param mutex: The pointer to the mutex.
* @returns `0` if the lock could be acquired, and `-EAGAIN` if not.
*/
int atomic_lock(atomic_t *mutex);
void atomic_unlock(atomic_t *mutex);

@ -33,10 +33,34 @@
#define __SIZE_TYPE__ unsigned long int
#endif /* __SIZE_TYPE__ */
#if __SIZEOF_SIZE_T__ == 1
#define _SSIZE_TYPE_ int8_t;
#elif __SIZEOF_SIZE_T__ == 2
#define _SSIZE_TYPE_ int16_t;
#else
#define _SSIZE_TYPE_ int32_t;
#endif /* __SIZEOF_SIZE_T__ */
/** Unsigned size specifier. */
typedef __SIZE_TYPE__ size_t;
/** Signed size specifier (negative sizes mean error codes). */
typedef signed long int ssize_t;
typedef __PTRDIFF_TYPE__ ssize_t;
#if CONFIG_SCHED_MAXPROC < 128
#define _PID_TYPE_ int8_t
#elif CONFIG_SCHED_MAXPROC < 65536
#define _PID_TYPE_ int16_t
#else
#define _PID_TYPE_ int32_t
#endif /* SCHED_MAXPROC */
/** Process identifier. */
typedef int8_t pid_t;
typedef _PID_TYPE_ pid_t;
#ifndef __SIG_ATOMIC_TYPE__
#define __SIG_ATOMIC_TYPE__ int
#endif /* __SIG_ATOMIC_TYPE__ */
typedef struct {
__SIG_ATOMIC_TYPE__ lock;
} atomic_t;

@ -0,0 +1,53 @@
/*
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2020 Felix Kopp <sandtler@sandtler.club>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#define CHAR_MAX __SCHAR_MAX__
#define CHAR_MIN (CHAR_MAX + 1)
#define UCHAR_MAX ((unsigned char)0 - 1)
#define UCHAR_MIN ((unsigned char)0)
#define SHRT_MAX __SHRT_MAX__
#define SHRT_MIN (SHRT_MAX + 1)
#define USHRT_MAX ((unsigned short)0 - 1)
#define USHRT_MIN ((unsigned short)0)
#define INT_MAX __INT_MAX__
#define INT_MIN (INT_MAX + 1)
#define UINT_MAX ((unsigned int)0 - 1)
#define UINT_MIN ((unsigned int)0)
#define LONG_MAX __LONG_MAX__
#define LONG_MIN (LONG_MAX + 1)
#define ULONG_MAX ((unsigned long)0 - 1)
#define ULONG_MIN ((unsigned long)0)
#define LLONG_MAX __LLONG_MAX__
#define LLONG_MIN (LLONG_MAX + 1)
#define ULLONG_MAX ((unsigned long long)0 - 1)
#define ULLONG_MIN ((unsigned long long)0)

@ -25,6 +25,8 @@
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <arch/hardware.h>
#include <ardix/sched.h>
#include <stdint.h>
#include <stddef.h>
@ -47,6 +49,10 @@ void do_bootstrap(void)
uint32_t state = (1 << 27);
uint32_t count = 0;
sys_init();
sched_init();
REG_PIOB_OER |= state;
REG_PIOB_PER |= state;
@ -63,6 +69,7 @@ void do_bootstrap(void)
REG_PIOB_CODR |= state;
on = true;
}
count = 0;
}
}

@ -45,6 +45,30 @@ struct process *_current_process;
*/
static struct process procs[CONFIG_SCHED_MAXPROC + 1];
/**
* Find an unused process slot in the `procs` array, insert that process into
* the scheduler's ring queue and return it. Must run in atomic context.
*
* @returns A pointer to the new process slot, or `NULL` if none are available.
*/
static struct process *sched_find_free_slot_and_link(void)
{
pid_t i;
struct process *newproc = NULL;
for (i = 1; i < CONFIG_SCHED_MAXPROC + 1; i++) {
if (procs[i].pid == -1 && procs[i].state == PROC_DEAD) {
newproc = &procs[i];
newproc->next = procs[i - 1].next;
procs[i - 1].next = newproc;
newproc->pid = i;
break;
}
}
return newproc;
}
int sched_init(void)
{
int i;
@ -95,8 +119,6 @@ void *sched_process_switch(void *curr_sp)
if (_current_process->state != PROC_SLEEP)
_current_process->state = PROC_QUEUE;
sched_interrupts++;
while (true) {
nextproc = nextproc->next;
if (sched_proc_should_run(nextproc)) {

Loading…
Cancel
Save