mirror of
https://github.com/andreili/katapult.git
synced 2025-08-24 03:44:06 +02:00
sched: Add sched.c and sched.h files to make importing Klipper code easier
Add the sched.c code and associated DECL_INIT(), DECL_TASK() macros so that it is easier to import low-level Klipper code into the CanBoot repo. These additional code wrappers do not increase the overall binary size as gcc does a good job of inlining the wrappers and removing unused code during the compile process. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
ae687a404d
commit
db6a9b4d96
@ -10,6 +10,7 @@ FILEHEADER = """
|
|||||||
/* DO NOT EDIT! This is an autogenerated file. See scripts/buildcommands.py. */
|
/* DO NOT EDIT! This is an autogenerated file. See scripts/buildcommands.py. */
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "board/irq.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -19,6 +20,43 @@ def error(msg):
|
|||||||
|
|
||||||
Handlers = []
|
Handlers = []
|
||||||
|
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# C call list generation
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# Create dynamic C functions that call a list of other C functions
|
||||||
|
class HandleCallList:
|
||||||
|
def __init__(self):
|
||||||
|
self.call_lists = {'ctr_run_initfuncs': []}
|
||||||
|
self.ctr_dispatch = { '_DECL_CALLLIST': self.decl_calllist }
|
||||||
|
def decl_calllist(self, req):
|
||||||
|
funcname, callname = req.split()[1:]
|
||||||
|
self.call_lists.setdefault(funcname, []).append(callname)
|
||||||
|
def update_data_dictionary(self, data):
|
||||||
|
pass
|
||||||
|
def generate_code(self, options):
|
||||||
|
code = []
|
||||||
|
for funcname, funcs in self.call_lists.items():
|
||||||
|
func_code = [' extern void %s(void);\n %s();' % (f, f)
|
||||||
|
for f in funcs]
|
||||||
|
if funcname == 'ctr_run_taskfuncs':
|
||||||
|
add_poll = ' irq_poll();\n'
|
||||||
|
func_code = [add_poll + fc for fc in func_code]
|
||||||
|
func_code.append(add_poll)
|
||||||
|
fmt = """
|
||||||
|
void
|
||||||
|
%s(void)
|
||||||
|
{
|
||||||
|
%s
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
code.append(fmt % (funcname, "\n".join(func_code).strip()))
|
||||||
|
return "".join(code)
|
||||||
|
|
||||||
|
Handlers.append(HandleCallList())
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Enumeration and static string generation
|
# Enumeration and static string generation
|
||||||
######################################################################
|
######################################################################
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
# Main code build rules
|
# Main code build rules
|
||||||
|
|
||||||
src-y += canboot_main.c led.c
|
src-y += canboot_main.c sched.c led.c
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "ctr.h" // DECL_CTR
|
#include "ctr.h" // DECL_CTR
|
||||||
#include "led.h" // check_blink_time
|
#include "led.h" // check_blink_time
|
||||||
#include "byteorder.h" // cpu_to_le32
|
#include "byteorder.h" // cpu_to_le32
|
||||||
|
#include "sched.h" // sched_run_init
|
||||||
|
|
||||||
#define PROTO_VERSION 0x00010000 // Version 1.0.0
|
#define PROTO_VERSION 0x00010000 // Version 1.0.0
|
||||||
#define PROTO_SIZE 4
|
#define PROTO_SIZE 4
|
||||||
@ -291,12 +292,10 @@ check_double_reset(void)
|
|||||||
static void
|
static void
|
||||||
enter_bootloader(void)
|
enter_bootloader(void)
|
||||||
{
|
{
|
||||||
can_init();
|
sched_run_init();
|
||||||
led_init();
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
canbus_rx_task();
|
sched_run_tasks();
|
||||||
canbus_tx_task();
|
|
||||||
check_blink_time(blink_time);
|
check_blink_time(blink_time);
|
||||||
if (complete && canbus_tx_clear())
|
if (complete && canbus_tx_clear())
|
||||||
// wait until we are complete and the ack has returned
|
// wait until we are complete and the ack has returned
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "board/internal.h" // __CORTEX_M
|
#include "board/internal.h" // __CORTEX_M
|
||||||
#include "irq.h" // irqstatus_t
|
#include "irq.h" // irqstatus_t
|
||||||
|
#include "sched.h" // DECL_SHUTDOWN
|
||||||
|
|
||||||
void
|
void
|
||||||
irq_disable(void)
|
irq_disable(void)
|
||||||
@ -71,3 +72,4 @@ clear_active_irq(void)
|
|||||||
"1:\n"
|
"1:\n"
|
||||||
: "=&r"(temp) : "r"(psr), "r"(0xfffffff9) : "r12", "cc");
|
: "=&r"(temp) : "r"(psr), "r"(0xfffffff9) : "r12", "cc");
|
||||||
}
|
}
|
||||||
|
DECL_SHUTDOWN(clear_active_irq);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "byteorder.h" // cpu_to_le32
|
#include "byteorder.h" // cpu_to_le32
|
||||||
#include "canbus.h" // canbus_set_uuid
|
#include "canbus.h" // canbus_set_uuid
|
||||||
#include "canboot_main.h"
|
#include "canboot_main.h"
|
||||||
|
#include "sched.h" // sched_wake_task
|
||||||
|
|
||||||
static uint32_t canbus_assigned_id;
|
static uint32_t canbus_assigned_id;
|
||||||
static uint8_t canbus_uuid[CANBUS_UUID_LEN];
|
static uint8_t canbus_uuid[CANBUS_UUID_LEN];
|
||||||
@ -19,7 +20,7 @@ static uint8_t canbus_uuid[CANBUS_UUID_LEN];
|
|||||||
* Data transmission over CAN
|
* Data transmission over CAN
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
|
|
||||||
static volatile uint8_t canbus_tx_wake;
|
static struct task_wake canbus_tx_wake;
|
||||||
static uint8_t transmit_buf[96], transmit_pos, transmit_max;
|
static uint8_t transmit_buf[96], transmit_pos, transmit_max;
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
@ -31,15 +32,14 @@ canbus_tx_clear(void)
|
|||||||
void
|
void
|
||||||
canbus_notify_tx(void)
|
canbus_notify_tx(void)
|
||||||
{
|
{
|
||||||
canbus_tx_wake = 1;
|
sched_wake_task(&canbus_tx_wake);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
canbus_tx_task(void)
|
canbus_tx_task(void)
|
||||||
{
|
{
|
||||||
if (!canbus_tx_wake)
|
if (!sched_check_wake(&canbus_tx_wake))
|
||||||
return;
|
return;
|
||||||
canbus_tx_wake = 0;
|
|
||||||
uint32_t id = canbus_assigned_id;
|
uint32_t id = canbus_assigned_id;
|
||||||
if (!id) {
|
if (!id) {
|
||||||
transmit_pos = transmit_max = 0;
|
transmit_pos = transmit_max = 0;
|
||||||
@ -57,6 +57,7 @@ canbus_tx_task(void)
|
|||||||
}
|
}
|
||||||
transmit_pos = tpos;
|
transmit_pos = tpos;
|
||||||
}
|
}
|
||||||
|
DECL_TASK(canbus_tx_task);
|
||||||
|
|
||||||
// Encode and transmit a "response" message
|
// Encode and transmit a "response" message
|
||||||
void
|
void
|
||||||
@ -93,8 +94,8 @@ canboot_sendf(uint8_t* data, uint16_t size)
|
|||||||
|
|
||||||
// Available commands and responses
|
// Available commands and responses
|
||||||
#define CANBUS_CMD_QUERY_UNASSIGNED 0x00
|
#define CANBUS_CMD_QUERY_UNASSIGNED 0x00
|
||||||
#define CANBUS_CMD_SET_NODEID_CANBOOT 0x11
|
#define CANBUS_CMD_SET_CANBOOT_NODEID 0x11
|
||||||
#define CANBUS_CMD_CLEAR_NODE_ID_CANBOOT 0x12
|
#define CANBUS_CMD_CLEAR_CANBOOT_NODEID 0x12
|
||||||
#define CANBUS_RESP_NEED_NODEID 0x20
|
#define CANBUS_RESP_NEED_NODEID 0x20
|
||||||
|
|
||||||
// Helper to verify a UUID in a command matches this chip's UUID
|
// Helper to verify a UUID in a command matches this chip's UUID
|
||||||
@ -118,7 +119,7 @@ can_process_query_unassigned(uint32_t id, uint32_t len, uint8_t *data)
|
|||||||
uint8_t send[8];
|
uint8_t send[8];
|
||||||
send[0] = CANBUS_RESP_NEED_NODEID;
|
send[0] = CANBUS_RESP_NEED_NODEID;
|
||||||
memcpy(&send[1], canbus_uuid, sizeof(canbus_uuid));
|
memcpy(&send[1], canbus_uuid, sizeof(canbus_uuid));
|
||||||
send[7] = CANBUS_CMD_SET_NODEID_CANBOOT;
|
send[7] = CANBUS_CMD_SET_CANBOOT_NODEID;
|
||||||
// Send with retry
|
// Send with retry
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int ret = canbus_send(CANBUS_ID_ADMIN_RESP, 8, send);
|
int ret = canbus_send(CANBUS_ID_ADMIN_RESP, 8, send);
|
||||||
@ -128,7 +129,7 @@ can_process_query_unassigned(uint32_t id, uint32_t len, uint8_t *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
can_process_clear_node_id(void)
|
can_process_clear_canboot_nodeid(void)
|
||||||
{
|
{
|
||||||
canbus_assigned_id = 0;
|
canbus_assigned_id = 0;
|
||||||
canbus_set_filter(canbus_assigned_id);
|
canbus_set_filter(canbus_assigned_id);
|
||||||
@ -143,7 +144,7 @@ can_id_conflict(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
can_process_set_nodeid(uint32_t id, uint32_t len, uint8_t *data)
|
can_process_set_canboot_nodeid(uint32_t id, uint32_t len, uint8_t *data)
|
||||||
{
|
{
|
||||||
if (len < 8)
|
if (len < 8)
|
||||||
return;
|
return;
|
||||||
@ -168,11 +169,11 @@ can_process(uint32_t id, uint32_t len, uint8_t *data)
|
|||||||
case CANBUS_CMD_QUERY_UNASSIGNED:
|
case CANBUS_CMD_QUERY_UNASSIGNED:
|
||||||
can_process_query_unassigned(id, len, data);
|
can_process_query_unassigned(id, len, data);
|
||||||
break;
|
break;
|
||||||
case CANBUS_CMD_SET_NODEID_CANBOOT:
|
case CANBUS_CMD_SET_CANBOOT_NODEID:
|
||||||
can_process_set_nodeid(id, len, data);
|
can_process_set_canboot_nodeid(id, len, data);
|
||||||
break;
|
break;
|
||||||
case CANBUS_CMD_CLEAR_NODE_ID_CANBOOT:
|
case CANBUS_CMD_CLEAR_CANBOOT_NODEID:
|
||||||
can_process_clear_node_id();
|
can_process_clear_canboot_nodeid();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,7 +183,13 @@ can_process(uint32_t id, uint32_t len, uint8_t *data)
|
|||||||
* CAN packet reading
|
* CAN packet reading
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
|
|
||||||
static volatile uint8_t canbus_rx_wake;
|
static struct task_wake canbus_rx_wake;
|
||||||
|
|
||||||
|
void
|
||||||
|
canbus_notify_rx(void)
|
||||||
|
{
|
||||||
|
sched_wake_task(&canbus_rx_wake);
|
||||||
|
}
|
||||||
|
|
||||||
// Handle incoming data (called from IRQ handler)
|
// Handle incoming data (called from IRQ handler)
|
||||||
void
|
void
|
||||||
@ -194,19 +201,12 @@ canbus_process_data(uint32_t id, uint32_t len, uint8_t *data)
|
|||||||
canbus_notify_rx();
|
canbus_notify_rx();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
canbus_notify_rx(void)
|
|
||||||
{
|
|
||||||
canbus_rx_wake = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Task to process incoming commands and admin messages
|
// Task to process incoming commands and admin messages
|
||||||
void
|
void
|
||||||
canbus_rx_task(void)
|
canbus_rx_task(void)
|
||||||
{
|
{
|
||||||
if (!canbus_rx_wake)
|
if (!sched_check_wake(&canbus_rx_wake))
|
||||||
return;
|
return;
|
||||||
canbus_rx_wake = 0;
|
|
||||||
|
|
||||||
// Read any pending CAN packets
|
// Read any pending CAN packets
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -221,6 +221,8 @@ canbus_rx_task(void)
|
|||||||
can_process(id, ret, data);
|
can_process(id, ret, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DECL_TASK(canbus_rx_task);
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
* Setup and shutdown
|
* Setup and shutdown
|
||||||
@ -248,3 +250,4 @@ canbus_shutdown(void)
|
|||||||
canbus_notify_tx();
|
canbus_notify_tx();
|
||||||
canbus_notify_rx();
|
canbus_notify_rx();
|
||||||
}
|
}
|
||||||
|
DECL_SHUTDOWN(canbus_shutdown);
|
||||||
|
@ -12,15 +12,12 @@ int canbus_read(uint32_t *id, uint8_t *data);
|
|||||||
int canbus_send(uint32_t id, uint32_t len, uint8_t *data);
|
int canbus_send(uint32_t id, uint32_t len, uint8_t *data);
|
||||||
void canbus_set_filter(uint32_t id);
|
void canbus_set_filter(uint32_t id);
|
||||||
void canbus_reboot(void);
|
void canbus_reboot(void);
|
||||||
void can_init(void);
|
|
||||||
|
|
||||||
// canbus.c
|
// canbus.c
|
||||||
void canbus_notify_tx(void);
|
void canbus_notify_tx(void);
|
||||||
void canbus_notify_rx(void);
|
void canbus_notify_rx(void);
|
||||||
void canbus_process_data(uint32_t id, uint32_t len, uint8_t *data);
|
void canbus_process_data(uint32_t id, uint32_t len, uint8_t *data);
|
||||||
void canbus_set_uuid(void *data);
|
void canbus_set_uuid(void *data);
|
||||||
void canbus_tx_task(void);
|
|
||||||
void canbus_rx_task(void);
|
|
||||||
uint8_t canbus_tx_clear(void);
|
uint8_t canbus_tx_clear(void);
|
||||||
|
|
||||||
#endif // canbus.h
|
#endif // canbus.h
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "board/misc.h" // timer_read_time
|
#include "board/misc.h" // timer_read_time
|
||||||
#include "ctr.h" // DECL_CTR
|
#include "ctr.h" // DECL_CTR
|
||||||
#include "led.h" // check_blink_time
|
#include "led.h" // check_blink_time
|
||||||
|
#include "sched.h" // DECL_INIT
|
||||||
|
|
||||||
DECL_CTR("DECL_LED_PIN " __stringify(CONFIG_STATUS_LED_PIN));
|
DECL_CTR("DECL_LED_PIN " __stringify(CONFIG_STATUS_LED_PIN));
|
||||||
extern uint32_t led_gpio, led_gpio_high; // Generated by buildcommands.py
|
extern uint32_t led_gpio, led_gpio_high; // Generated by buildcommands.py
|
||||||
@ -27,6 +28,7 @@ led_init(void)
|
|||||||
udelay(10);
|
udelay(10);
|
||||||
last_blink_time = timer_read_time();
|
last_blink_time = timer_read_time();
|
||||||
}
|
}
|
||||||
|
DECL_INIT(led_init);
|
||||||
|
|
||||||
void
|
void
|
||||||
check_blink_time(uint32_t usec)
|
check_blink_time(uint32_t usec)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#ifndef __LED_H
|
#ifndef __LED_H
|
||||||
#define __LED_H
|
#define __LED_H
|
||||||
|
|
||||||
void led_init();
|
|
||||||
void check_blink_time(uint32_t usec);
|
void check_blink_time(uint32_t usec);
|
||||||
|
|
||||||
#endif // led.h
|
#endif // led.h
|
||||||
|
41
src/sched.c
Normal file
41
src/sched.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Basic scheduling functions and startup code
|
||||||
|
//
|
||||||
|
// Copyright (C) 2016-2022 Kevin O'Connor <kevin@koconnor.net>
|
||||||
|
//
|
||||||
|
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||||
|
|
||||||
|
#include "board/io.h" // readb
|
||||||
|
#include "sched.h" // sched_check_periodic
|
||||||
|
|
||||||
|
// Note that a task is ready to run
|
||||||
|
void
|
||||||
|
sched_wake_task(struct task_wake *w)
|
||||||
|
{
|
||||||
|
writeb(&w->wake, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a task is ready to run (as indicated by sched_wake_task)
|
||||||
|
uint8_t
|
||||||
|
sched_check_wake(struct task_wake *w)
|
||||||
|
{
|
||||||
|
if (!readb(&w->wake))
|
||||||
|
return 0;
|
||||||
|
writeb(&w->wake, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sched_run_init(void)
|
||||||
|
{
|
||||||
|
// Run all init functions marked with DECL_INIT()
|
||||||
|
extern void ctr_run_initfuncs(void);
|
||||||
|
ctr_run_initfuncs();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sched_run_tasks(void)
|
||||||
|
{
|
||||||
|
// Run all task functions marked with DECL_TASK()
|
||||||
|
extern void ctr_run_taskfuncs(void);
|
||||||
|
ctr_run_taskfuncs();
|
||||||
|
}
|
29
src/sched.h
Normal file
29
src/sched.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef __SCHED_H
|
||||||
|
#define __SCHED_H
|
||||||
|
|
||||||
|
#include <stdint.h> // uint32_t
|
||||||
|
#include "ctr.h" // DECL_CTR
|
||||||
|
|
||||||
|
// Declare an init function (called at firmware startup)
|
||||||
|
#define DECL_INIT(FUNC) _DECL_CALLLIST(ctr_run_initfuncs, FUNC)
|
||||||
|
// Declare a task function (called periodically during normal runtime)
|
||||||
|
#define DECL_TASK(FUNC) _DECL_CALLLIST(ctr_run_taskfuncs, FUNC)
|
||||||
|
// Declare a shutdown function (called on an emergency stop)
|
||||||
|
#define DECL_SHUTDOWN(FUNC) _DECL_CALLLIST(ctr_run_shutdownfuncs, FUNC)
|
||||||
|
|
||||||
|
// Task waking struct
|
||||||
|
struct task_wake {
|
||||||
|
uint8_t wake;
|
||||||
|
};
|
||||||
|
|
||||||
|
// sched.c
|
||||||
|
void sched_wake_task(struct task_wake *w);
|
||||||
|
uint8_t sched_check_wake(struct task_wake *w);
|
||||||
|
void sched_run_init(void);
|
||||||
|
void sched_run_tasks(void);
|
||||||
|
|
||||||
|
// Compiler glue for DECL_X macros above.
|
||||||
|
#define _DECL_CALLLIST(NAME, FUNC) \
|
||||||
|
DECL_CTR("_DECL_CALLLIST " __stringify(NAME) " " __stringify(FUNC))
|
||||||
|
|
||||||
|
#endif // sched.h
|
@ -13,7 +13,7 @@
|
|||||||
#include "generic/armcm_boot.h" // armcm_enable_irq
|
#include "generic/armcm_boot.h" // armcm_enable_irq
|
||||||
#include "generic/canbus.h" // canbus_notify_tx
|
#include "generic/canbus.h" // canbus_notify_tx
|
||||||
#include "internal.h" // enable_pclock
|
#include "internal.h" // enable_pclock
|
||||||
#include "ctr.h" // DECL_CONSTANT_STR
|
#include "sched.h" // DECL_INIT
|
||||||
|
|
||||||
#if CONFIG_STM32_CANBUS_PA11_PA12 || CONFIG_STM32_CANBUS_PA11_PA12_REMAP
|
#if CONFIG_STM32_CANBUS_PA11_PA12 || CONFIG_STM32_CANBUS_PA11_PA12_REMAP
|
||||||
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PA11,PA12");
|
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PA11,PA12");
|
||||||
@ -317,3 +317,4 @@ can_init(void)
|
|||||||
uint64_t hash = fasthash64((uint8_t*)UID_BASE, 12, 0xA16231A7);
|
uint64_t hash = fasthash64((uint8_t*)UID_BASE, 12, 0xA16231A7);
|
||||||
canbus_set_uuid(&hash);
|
canbus_set_uuid(&hash);
|
||||||
}
|
}
|
||||||
|
DECL_INIT(can_init);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user