Skip to content
Snippets Groups Projects
Verified Commit b64e91b8 authored by rahix's avatar rahix
Browse files

Merge branch 'rahix/api-demo'

parents f4500148 e57d3da6
No related branches found
No related tags found
No related merge requests found
#ifndef _API_H
#define _API_H
#include <stdint.h>
#ifndef API
# define API(id, def) def
#endif
#define API_BUZZER 0x35c3
API(API_BUZZER, void api_set_buzzer(uint8_t state));
typedef struct {
uint8_t red;
uint8_t green;
uint8_t blue;
} led_color_t;
#define API_LED 0xc0ffee
API(API_LED, void api_set_led(uint8_t led, led_color_t color));
#define API_TEST 0xdeadc0de
API(API_TEST, void api_test(char test0, short test1, int test2, long test3));
#endif /* _API_H */
#include <stdlib.h>
#include "api/api_caller.h"
#include "tmr_utils.h"
void* api_call_start (uint32_t id, void* args, uint32_t size)
{
// aquire semaphore
while (E_BUSY == SEMA_GetSema (API_CALL_SEMA)) ;
ApiCallSpace->id = id;
ApiCallSpace->returning = 0;
return ApiCallSpace->buf;
}
void* api_call_bother_dispatcher (void* buf)
{
SEMA_FreeSema (API_CALL_SEMA);
// TODO: set event
while(1) {
// aquire semaphore
while (E_BUSY == SEMA_GetSema (API_CALL_SEMA)) ;
if (ApiCallSpace->returning == 1) {
break;
}
SEMA_FreeSema(API_CALL_SEMA);
TMR_Delay(MXC_TMR2, MSEC(100), 0);
}
SEMA_FreeSema(API_CALL_SEMA);
return NULL;
}
#include "mxc_errors.h"
#include "api_common.h"
void* api_call (uint32_t id, void *args, uint32_t size);
void* api_call_bother_dispatcher (void* buf);
#include <stdint.h>
#define API_CALL_SEMA 0
struct api_call
{
uint32_t id;
uint8_t returning;
unsigned char buf[1];
};
static struct api_call *ApiCallSpace = (struct api_call *)0x20080001;
#include "api_dispatcher.h"
int api_init (sys_cfg_sema_t *sys_cfg)
{
int ret;
ret = SEMA_Init (sys_cfg);
/* Set the status of the flag to a valid initial state (right before
* api-calls are made) */
ApiCallSpace->returning = 1;
return ret;
}
/* Generated function */
void __api_dispatch_call(uint32_t id, void*buffer);
void api_dispatcher()
{
while (SEMA_GetSema(API_CALL_SEMA) == E_BUSY) {}
if (ApiCallSpace->returning == 1) {
SEMA_FreeSema(API_CALL_SEMA);
return;
}
printf("core1: Catched API CALL!\n");
__api_dispatch_call(ApiCallSpace->id, ApiCallSpace->buf);
ApiCallSpace->returning = 1;
SEMA_FreeSema(API_CALL_SEMA);
}
#include "api_common.h"
#include "mxc_sys.h"
int api_init (sys_cfg_sema_t *sys_cfg);
void api_dispatcher();
#include "board.h"
#include "gpio.h"
#include "mxc_delay.h"
#include "api.h"
#include "tmr_utils.h"
#include "leds.h"
#include "api/api_dispatcher.h"
static const gpio_cfg_t motor_pin = {PORT_0, PIN_8, GPIO_FUNC_OUT, GPIO_PAD_NONE};
void api_set_buzzer(uint8_t state)
{
if (state) {
printf("API: Turning motor ON!\n");
GPIO_OutSet(&motor_pin);
} else {
printf("API: Turning motor OFF!\n");
GPIO_OutClr(&motor_pin);
}
}
void api_set_led(uint8_t led, led_color_t color)
{
printf("API: Changing color of led %d.\n", led);
printf("Color { r: %3d, g: %3d, b: %3d }\n", color.red, color.green, color.blue);
leds_set(led, color.red, color.green, color.blue);
leds_update();
}
void api_test(char test0, short test1, int test2, long test3)
{
printf ("test0: %x, test1: %d, test2: %x, test3: %lx\n",
test0, (int)test1, test2, test3);
}
int main(void)
{
api_init(NULL);
leds_init();
while (1) {
api_dispatcher();
TMR_Delay(MXC_TMR1, MSEC(100), 0);
}
#if 0
// Enable rxev on core1
MXC_GCR->evten |= 0x20;
for (int i = 0; 1; i++) {
__asm volatile("wfe");
printf("core1: Hello! %d\n", i);
}
#endif
}
source ../../.gdbinit
set confirm off
echo Loading core1 image ...
file ../../build/hw-tests/api-demo/api-demo-core1.elf
load
echo Loading core0 image ...
file ../../build/hw-tests/api-demo/api-demo-core0.elf
load
reset
quit
import argparse
import contextlib
import os
import re
import subprocess
def main():
parser = argparse.ArgumentParser(
description="Generate the API stubs from a header file."
)
parser.add_argument(
"-H", "--header", required=True, help="The header to base the definitions on."
)
parser.add_argument(
"-c", "--client", required=True, help="The output client-side c source file."
)
parser.add_argument(
"-s", "--server", required=True, help="The output server-side c source file."
)
args = parser.parse_args()
with contextlib.ExitStack() as cx:
# Run the preprocessor on the header file to get the API definitions.
#
# For this, we first need a source to include the header which contains
# an alternative definition of the `API` macro that marks definitions in
# a way we can find later on.
api_src = """\
#define API(id, def) __GENERATE_API $ __GEN_ID_##id $ def $
#include "{header}"
""".format(
header=os.path.relpath(args.header)
)
# Evaluate the preprocessor
source = subprocess.check_output(
["gcc", "-E", "-"], input=api_src.encode()
).decode()
# Parse the header for API definitions
matcher = re.compile(
r"__GENERATE_API \$ __GEN_ID_(?P<id>\w+) \$ void (?P<decl>.+?)\((?P<args>.*?)\) \$",
re.DOTALL | re.MULTILINE,
)
args_matcher = re.compile(r"(?P<type>\w+(?:\*+|\s+))(?P<name>\w+),")
# Open output files
f_client = cx.enter_context(open(args.client, "w"))
f_server = cx.enter_context(open(args.server, "w"))
print('#include "{}"\n'.format(
os.path.basename(args.header)
), file=f_client)
print("""\
#include "{}"
void __api_dispatch_call(uint32_t id, void*buffer)
{{
switch (id) {{""".format(
os.path.basename(args.header)
), file=f_server)
for match in matcher.finditer(source):
api_id = match.group("id")
api_decl = match.group("decl")
api_args = match.group("args")
api_args_names = []
api_args_types = []
api_args_sizes = []
# Destructure args
for match in args_matcher.finditer(api_args + ","):
arg_type = match.group("type").strip()
arg_name = match.group("name")
api_args_names.append(arg_name)
api_args_types.append(arg_type)
api_args_sizes.append("sizeof({})".format(arg_type))
print(
"""\
/* Autogenerated stub for {id} */
void {cdecl}({cargs})
{{
const int size = {total_size};
void*buffer;
buffer = api_call_start({id}, size);
/* TODO: Check if buffer is no NULL */
""".format(
id=api_id,
cdecl=api_decl,
cargs=api_args,
total_size=" + ".join(api_args_sizes),
),
file=f_client,
)
print("""\
case {id}:
{cdecl}(""".format(id=api_id, cdecl=api_decl),
file=f_server,
)
for i, (arg, ty) in enumerate(zip(api_args_names, api_args_types)):
print(
""" *({type}*)(buffer + {offset}) = {arg};""".format(
type=ty,
offset=" + ".join(api_args_sizes[:i]) if i > 0 else "0",
arg=arg,
),
file=f_client,
)
if i != 0:
print(",", file=f_server)
print(
"""\
*({type}*)(buffer + {offset})""".format(
type=ty,
offset=" + ".join(api_args_sizes[:i]) if i > 0 else "0",
),
file=f_server,
end="",
)
print("""
);
break;""".format(
cdecl=api_decl,
args=", ".join(api_args_names),
),
file=f_server,
)
print(
"""
printf("Sending call {id}\\nBUF: ");
for (int i = 0; i < size; i++) {{
printf("0x%02x ", ((char*)buffer)[i]);
}}
printf("\\n");
api_call_bother_dispatcher(buffer);
}}
""".format(
id=api_id
),
file=f_client,
)
print("""\
default:
printf("Error: API function %x is unknown!!\\n", {id});
break;
}}
}}""".format(
id=api_id,
), file=f_server)
if __name__ == "__main__":
main()
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "card10.h"
#include "tmr_utils.h"
#include "api.h"
void Core1_Start(void) {
//MXC_GCR->gp0 = (uint32_t)(&__isr_vector_core1);
MXC_GCR->gp0 = 0x10040000;
MXC_GCR->perckcn1 &= ~MXC_F_GCR_PERCKCN1_CPU1;
}
void Core1_Stop(void) {
MXC_GCR->perckcn1 |= MXC_F_GCR_PERCKCN1_CPU1;
}
int main(void)
{
int count = 0;
led_color_t red = {0x10, 0, 0};
card10_init();
card10_diag();
printf("API Test.\n");
printf("core0: Starting dispatcher on core1\n");
Core1_Start();
TMR_Delay(MXC_TMR0, MSEC(100), 0);
api_set_buzzer(1);
TMR_Delay(MXC_TMR0, MSEC(300), 0);
api_set_buzzer(0);
api_set_led(5, red);
api_test(0xAB, 0x7DEF, 0x01, 0x02);
while(1) {
printf("count = %d\n", count++);
TMR_Delay(MXC_TMR0, SEC(1), 0);
}
}
api_stubs = custom_target(
'api_*.c',
input: 'api.h',
output: ['api_client.c', 'api_server.c'],
command: [
python3,
meson.current_source_dir() + '/genapi.py',
'-H', '@INPUT0@',
'-c', '@OUTPUT0@', '-s', '@OUTPUT1@',
],
depend_files: 'genapi.py',
)
name = 'api-demo-core0'
executable(
name + '.elf',
'main.c',
'./api/api_caller.c',
api_stubs[0],
dependencies: [libcard10, max32665_startup_core0],
link_whole: [max32665_startup_core0_lib, board_card10_lib],
link_args: [
'-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
],
)
name = 'api-demo-core1'
executable(
name + '.elf',
'core1-dispatcher.c',
'./api/api_dispatcher.c',
api_stubs[1],
dependencies: [libcard10, max32665_startup_core1],
link_whole: [max32665_startup_core1_lib, board_card10_lib],
link_args: [
'-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
],
)
subdir('api-demo/')
subdir('bmatest/')
subdir('bmetest/')
subdir('dual-core/')
......
......@@ -27,5 +27,7 @@ add_global_link_arguments(
language: 'c',
)
python3 = import('python').find_installation('python3')
subdir('lib/')
subdir('hw-tests/')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment