mirror of
https://github.com/Klipper3d/klipper.git
synced 2025-08-05 04:54:11 -06:00
build: Use compile_time_request system for init, tasks, and shutdown
Avoid using linker magic to define the init, task, and shutdown functions. Instead, use the compile_time_request system. This simplifies the build and produces more efficient code. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
ca9756413f
commit
a82e949c00
26 changed files with 82 additions and 127 deletions
|
@ -80,7 +80,7 @@ DECL_COMMAND(command_query_analog_in,
|
|||
"query_analog_in oid=%c clock=%u sample_ticks=%u sample_count=%c"
|
||||
" rest_ticks=%u min_value=%hu max_value=%hu");
|
||||
|
||||
static void
|
||||
void
|
||||
analog_in_task(void)
|
||||
{
|
||||
static uint16_t next;
|
||||
|
@ -106,7 +106,7 @@ analog_in_task(void)
|
|||
}
|
||||
DECL_TASK(analog_in_task);
|
||||
|
||||
static void
|
||||
void
|
||||
analog_in_shutdown(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
|
|
@ -14,7 +14,7 @@ src-$(CONFIG_AVR_USBSERIAL) += avr/usbserial.c ../lib/pjrc_usb_serial/usb_serial
|
|||
src-$(CONFIG_AVR_SERIAL) += avr/serial.c
|
||||
|
||||
# Suppress broken "misspelled signal handler" warnings on gcc 4.8.1
|
||||
CFLAGS_klipper.o := $(CFLAGS_klipper.o) $(if $(filter 4.8.1, $(shell $(CC) -dumpversion)), -w)
|
||||
CFLAGS_klipper.elf := $(CFLAGS_klipper.elf) $(if $(filter 4.8.1, $(shell $(CC) -dumpversion)), -w)
|
||||
|
||||
# Build the additional hex output file
|
||||
target-y += $(OUT)klipper.elf.hex
|
||||
|
|
|
@ -25,7 +25,7 @@ static uint8_t transmit_pos, transmit_max;
|
|||
|
||||
DECL_CONSTANT(SERIAL_BAUD, CONFIG_SERIAL_BAUD);
|
||||
|
||||
static void
|
||||
void
|
||||
serial_init(void)
|
||||
{
|
||||
if (CONFIG_SERIAL_BAUD_U2X) {
|
||||
|
|
|
@ -71,7 +71,7 @@ timer_repeat_set(uint16_t next)
|
|||
}
|
||||
|
||||
// Reset the timer - clear settings and dispatch next timer immediately
|
||||
static void
|
||||
void
|
||||
timer_reset(void)
|
||||
{
|
||||
uint16_t now = timer_get();
|
||||
|
@ -81,7 +81,7 @@ timer_reset(void)
|
|||
}
|
||||
DECL_SHUTDOWN(timer_reset);
|
||||
|
||||
static void
|
||||
void
|
||||
timer_init(void)
|
||||
{
|
||||
if (CONFIG_AVR_CLKPR != -1 && (uint8_t)CONFIG_AVR_CLKPR != CLKPR) {
|
||||
|
@ -193,7 +193,7 @@ done:
|
|||
|
||||
// Periodic background task that temporarily boosts priority of
|
||||
// timers. This helps prioritize timers when tasks are idling.
|
||||
static void
|
||||
void
|
||||
timer_task(void)
|
||||
{
|
||||
irq_disable();
|
||||
|
|
|
@ -14,7 +14,7 @@ static char receive_buf[USBSERIAL_BUFFER_SIZE];
|
|||
static uint8_t receive_pos;
|
||||
static char transmit_buf[USBSERIAL_BUFFER_SIZE];
|
||||
|
||||
static void
|
||||
void
|
||||
usbserial_init(void)
|
||||
{
|
||||
usb_init();
|
||||
|
|
|
@ -18,7 +18,7 @@ ISR(WDT_vect)
|
|||
shutdown("Watchdog timer!");
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
watchdog_reset(void)
|
||||
{
|
||||
wdt_reset();
|
||||
|
@ -29,7 +29,7 @@ watchdog_reset(void)
|
|||
}
|
||||
DECL_TASK(watchdog_reset);
|
||||
|
||||
static void
|
||||
void
|
||||
watchdog_init(void)
|
||||
{
|
||||
// 0.5s timeout, interrupt and system reset
|
||||
|
|
|
@ -65,7 +65,7 @@ move_request_size(int size)
|
|||
move_item_size = size;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
move_reset(void)
|
||||
{
|
||||
if (!move_count)
|
||||
|
@ -201,7 +201,7 @@ DECL_COMMAND_FLAGS(command_get_uptime, HF_IN_SHUTDOWN, "get_uptime");
|
|||
#define SUMSQ_BASE 256
|
||||
DECL_CONSTANT(STATS_SUMSQ_BASE, SUMSQ_BASE);
|
||||
|
||||
static void
|
||||
void
|
||||
stats_task(void)
|
||||
{
|
||||
static uint32_t last, count, sumsq;
|
||||
|
|
|
@ -197,7 +197,7 @@ error:
|
|||
shutdown("Message encode error");
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
sendf_shutdown(void)
|
||||
{
|
||||
writeb(&in_sendf, 0);
|
||||
|
@ -289,7 +289,7 @@ nak:
|
|||
}
|
||||
|
||||
// Background task that reads commands from the board serial port
|
||||
static void
|
||||
void
|
||||
command_task(void)
|
||||
{
|
||||
// Process commands.
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
// Linker script that defines symbols around sections. The DECL_X()
|
||||
// macros need this linker script to place _start and _end symbols
|
||||
// around the list of declared items.
|
||||
#include "autoconf.h" // CONFIG_MACH_AVR
|
||||
#include "compiler.h" // __PASTE
|
||||
|
||||
#if CONFIG_MACH_AVR
|
||||
#define DECL_SECTION .progmem.data.
|
||||
#else
|
||||
#define DECL_SECTION .rodata.
|
||||
#endif
|
||||
|
||||
#define DECLWRAPPER(NAME) \
|
||||
__PASTE(DECL_SECTION, NAME) : SUBALIGN(1) { \
|
||||
NAME ## _start = . ; \
|
||||
*( .rodata. ## NAME ##.pre* ) \
|
||||
*( .rodata. ## NAME ##* ) \
|
||||
*( .rodata. ## NAME ##.post* ) \
|
||||
NAME ## _end = . ; \
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
DECLWRAPPER(taskfuncs)
|
||||
DECLWRAPPER(initfuncs)
|
||||
DECLWRAPPER(shutdownfuncs)
|
||||
}
|
|
@ -112,7 +112,7 @@ command_end_stop_query(uint32_t *args)
|
|||
}
|
||||
DECL_COMMAND(command_end_stop_query, "end_stop_query oid=%c");
|
||||
|
||||
static void
|
||||
void
|
||||
end_stop_task(void)
|
||||
{
|
||||
static uint16_t next;
|
||||
|
|
|
@ -40,7 +40,7 @@ irq_poll(void)
|
|||
}
|
||||
|
||||
// Clear the active irq if a shutdown happened in an irq handler
|
||||
static void
|
||||
void
|
||||
clear_active_irq(void)
|
||||
{
|
||||
uint32_t psr;
|
||||
|
|
|
@ -82,7 +82,7 @@ timer_dispatch_many(void)
|
|||
|
||||
// Periodic background task that temporarily boosts priority of
|
||||
// timers. This helps prioritize timers when tasks are idling.
|
||||
static void
|
||||
void
|
||||
timer_task(void)
|
||||
{
|
||||
irq_disable();
|
||||
|
@ -91,7 +91,7 @@ timer_task(void)
|
|||
}
|
||||
DECL_TASK(timer_task);
|
||||
|
||||
static void
|
||||
void
|
||||
timer_irq_shutdown(void)
|
||||
{
|
||||
timer_repeat_until = timer_read_time() + TIMER_IDLE_REPEAT_TICKS;
|
||||
|
|
|
@ -67,7 +67,7 @@ command_schedule_digital_out(uint32_t *args)
|
|||
DECL_COMMAND(command_schedule_digital_out,
|
||||
"schedule_digital_out oid=%c clock=%u value=%c");
|
||||
|
||||
static void
|
||||
void
|
||||
digital_out_shutdown(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
@ -212,7 +212,7 @@ command_schedule_soft_pwm_out(uint32_t *args)
|
|||
DECL_COMMAND(command_schedule_soft_pwm_out,
|
||||
"schedule_soft_pwm_out oid=%c clock=%u value=%hu");
|
||||
|
||||
static void
|
||||
void
|
||||
soft_pwm_shutdown(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
|
|
@ -9,9 +9,10 @@ dirs-y += lib/pru_rpmsg
|
|||
CFLAGS += -Os -mmcu=am335x.pru1
|
||||
CFLAGS += -Ilib/pru_rpmsg/include -Ilib/pru_rpmsg/include/am335x
|
||||
|
||||
CFLAGS_klipper.o := $(filter-out -mmcu=%, $(CFLAGS_klipper.o))
|
||||
CFLAGS_klipper.elf := $(CFLAGS) -minrt -T src/pru/pru.lds
|
||||
CFLAGS_klipper.elf := $(filter-out -mmcu=%, $(CFLAGS))
|
||||
CFLAGS_klipper.elf += -Wl,-r -nostdlib -Wl,-T,src/pru/pru.lds
|
||||
CFLAGS_pru0.elf := $(filter-out -mmcu=%, $(CFLAGS)) -minrt -mmcu=am335x.pru0
|
||||
CFLAGS_pru1.elf := $(CFLAGS) -minrt
|
||||
|
||||
# Add source files
|
||||
src-y := $(filter-out debugcmds.c, $(src-y))
|
||||
|
@ -22,8 +23,12 @@ pru0-y := pru/pru0.c
|
|||
pru0-y += ../lib/pru_rpmsg/pru_rpmsg.c ../lib/pru_rpmsg/pru_virtqueue.c
|
||||
|
||||
# Build the additional PRU0 binary
|
||||
target-y += $(OUT)pru0.elf
|
||||
target-y += $(OUT)pru0.elf $(OUT)pru1.elf
|
||||
|
||||
$(OUT)pru0.elf: $(patsubst %.c, $(OUT)src/%.o,$(pru0-y))
|
||||
@echo " Linking $@"
|
||||
$(Q)$(CC) $(CFLAGS_pru0.elf) $^ -o $@
|
||||
|
||||
$(OUT)pru1.elf: $(OUT)klipper.elf
|
||||
@echo " Linking $@"
|
||||
$(Q)$(CC) $(CFLAGS_pru1.elf) $^ -o $@
|
||||
|
|
|
@ -75,7 +75,7 @@ irq_poll(void)
|
|||
_irq_poll();
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
timer_shutdown(void)
|
||||
{
|
||||
// Reenable timer irq
|
||||
|
@ -86,12 +86,13 @@ timer_shutdown(void)
|
|||
}
|
||||
DECL_SHUTDOWN(timer_shutdown);
|
||||
|
||||
static void
|
||||
void
|
||||
timer_init(void)
|
||||
{
|
||||
CT_IEP.TMR_CNT = 0;
|
||||
timer_shutdown();
|
||||
}
|
||||
DECL_INIT(timer_init);
|
||||
|
||||
|
||||
/****************************************************************
|
||||
|
@ -211,8 +212,6 @@ main(void)
|
|||
;
|
||||
writel(&SHARED_MEM->signal, SIGNAL_PRU1_READY);
|
||||
|
||||
timer_init();
|
||||
|
||||
sched_main();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ command_schedule_pwm_out(uint32_t *args)
|
|||
DECL_COMMAND(command_schedule_pwm_out,
|
||||
"schedule_pwm_out oid=%c clock=%u value=%hu");
|
||||
|
||||
static void
|
||||
void
|
||||
pwm_shutdown(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
|
|
@ -16,14 +16,14 @@ DECL_CONSTANT(MCU, "sam3x8e");
|
|||
* watchdog handler
|
||||
****************************************************************/
|
||||
|
||||
static void
|
||||
void
|
||||
watchdog_reset(void)
|
||||
{
|
||||
WDT->WDT_CR = 0xA5000001;
|
||||
}
|
||||
DECL_TASK(watchdog_reset);
|
||||
|
||||
static void
|
||||
void
|
||||
watchdog_init(void)
|
||||
{
|
||||
uint32_t timeout = 32768 / 2; // 500ms timeout
|
||||
|
|
|
@ -27,7 +27,7 @@ static uint32_t transmit_pos, transmit_max;
|
|||
|
||||
DECL_CONSTANT(SERIAL_BAUD, CONFIG_SERIAL_BAUD);
|
||||
|
||||
static void
|
||||
void
|
||||
serial_init(void)
|
||||
{
|
||||
gpio_peripheral('A', PIO_PA8A_URXD, 'A', 1);
|
||||
|
|
|
@ -25,7 +25,7 @@ timer_read_time(void)
|
|||
return TC0->TC_CHANNEL[0].TC_CV;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
timer_init(void)
|
||||
{
|
||||
TcChannel *tc = &TC0->TC_CHANNEL[0];
|
||||
|
@ -44,7 +44,7 @@ timer_init(void)
|
|||
}
|
||||
DECL_INIT(timer_init);
|
||||
|
||||
static void
|
||||
void
|
||||
timer_shutdown(void)
|
||||
{
|
||||
// Reenable timer irq
|
||||
|
|
40
src/sched.c
40
src/sched.c
|
@ -1,6 +1,6 @@
|
|||
// Basic scheduling functions and startup/shutdown code.
|
||||
//
|
||||
// Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
|
||||
// Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
|
@ -167,7 +167,7 @@ sched_timer_dispatch(void)
|
|||
}
|
||||
|
||||
// Shutdown all user timers on an emergency stop.
|
||||
static void
|
||||
void
|
||||
sched_timer_shutdown(void)
|
||||
{
|
||||
timer_list = &deleted_timer;
|
||||
|
@ -209,11 +209,8 @@ run_shutdown(void)
|
|||
{
|
||||
uint32_t cur = timer_read_time();
|
||||
shutdown_status = 2;
|
||||
struct callback_handler *p;
|
||||
foreachdecl(p, shutdownfuncs) {
|
||||
void (*func)(void) = READP(p->func);
|
||||
func();
|
||||
}
|
||||
extern void ctr_run_shutdownfuncs(void);
|
||||
ctr_run_shutdownfuncs();
|
||||
shutdown_status = 1;
|
||||
irq_enable();
|
||||
|
||||
|
@ -252,39 +249,20 @@ sched_shutdown(uint_fast8_t reason)
|
|||
* Startup and background task processing
|
||||
****************************************************************/
|
||||
|
||||
// Invoke all init functions (as declared by DECL_INIT)
|
||||
static void
|
||||
run_init(void)
|
||||
{
|
||||
struct callback_handler *p;
|
||||
foreachdecl(p, initfuncs) {
|
||||
void (*func)(void) = READP(p->func);
|
||||
func();
|
||||
}
|
||||
}
|
||||
|
||||
// Invoke all background task functions (as declared by DECL_TASK)
|
||||
static void
|
||||
run_task(void)
|
||||
{
|
||||
struct callback_handler *p;
|
||||
foreachdecl(p, taskfuncs) {
|
||||
irq_poll();
|
||||
void (*func)(void) = READP(p->func);
|
||||
func();
|
||||
}
|
||||
}
|
||||
// Auto-generated code in out/compile_time_requests.c
|
||||
extern void ctr_run_initfuncs(void);
|
||||
extern void ctr_run_taskfuncs(void);
|
||||
|
||||
// Main loop of program
|
||||
void
|
||||
sched_main(void)
|
||||
{
|
||||
run_init();
|
||||
ctr_run_initfuncs();
|
||||
|
||||
int ret = setjmp(shutdown_jmp);
|
||||
if (ret)
|
||||
run_shutdown();
|
||||
|
||||
for (;;)
|
||||
run_task();
|
||||
ctr_run_taskfuncs();
|
||||
}
|
||||
|
|
20
src/sched.h
20
src/sched.h
|
@ -2,14 +2,14 @@
|
|||
#define __SCHED_H
|
||||
|
||||
#include <stdint.h> // uint32_t
|
||||
#include "compiler.h" // __section
|
||||
#include "ctr.h" // DECL_CTR
|
||||
|
||||
// Declare an init function (called at firmware startup)
|
||||
#define DECL_INIT(FUNC) _DECL_CALLBACK(initfuncs, FUNC)
|
||||
#define DECL_INIT(FUNC) _DECL_CALLLIST(ctr_run_initfuncs, FUNC)
|
||||
// Declare a task function (called periodically during normal runtime)
|
||||
#define DECL_TASK(FUNC) _DECL_CALLBACK(taskfuncs, FUNC)
|
||||
#define DECL_TASK(FUNC) _DECL_CALLLIST(ctr_run_taskfuncs, FUNC)
|
||||
// Declare a shutdown function (called on an emergency stop)
|
||||
#define DECL_SHUTDOWN(FUNC) _DECL_CALLBACK(shutdownfuncs, FUNC)
|
||||
#define DECL_SHUTDOWN(FUNC) _DECL_CALLLIST(ctr_run_shutdownfuncs, FUNC)
|
||||
|
||||
// Timer structure for scheduling timed events (see sched_add_timer() )
|
||||
struct timer {
|
||||
|
@ -33,15 +33,7 @@ void sched_report_shutdown(void);
|
|||
void sched_main(void);
|
||||
|
||||
// Compiler glue for DECL_X macros above.
|
||||
struct callback_handler {
|
||||
void (*func)(void);
|
||||
};
|
||||
#define _DECL_CALLBACK(NAME, FUNC) \
|
||||
const struct callback_handler _DECL_ ## NAME ## _ ## FUNC __visible \
|
||||
__section(".rodata." __stringify(NAME) ) = { .func = FUNC }
|
||||
|
||||
#define foreachdecl(ITER, NAME) \
|
||||
extern typeof(*ITER) NAME ## _start[], NAME ## _end[]; \
|
||||
for (ITER = NAME ## _start ; ITER < NAME ## _end ; ITER ++)
|
||||
#define _DECL_CALLLIST(NAME, FUNC) \
|
||||
DECL_CTR("_DECL_CALLLIST " __stringify(NAME) " " __stringify(FUNC))
|
||||
|
||||
#endif // sched.h
|
||||
|
|
|
@ -117,7 +117,7 @@ console_push_output(uint8_t len)
|
|||
****************************************************************/
|
||||
|
||||
// Periodically sleep so we don't consume all CPU
|
||||
static void
|
||||
void
|
||||
simu_pause(void)
|
||||
{
|
||||
// XXX - should check that no timers are present.
|
||||
|
|
|
@ -284,7 +284,7 @@ stepper_stop(struct stepper *s)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
stepper_shutdown(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue