Skip to content

Commit

Permalink
Add macro definition to schema, and option to protect against inclusi…
Browse files Browse the repository at this point in the history
…on in assembler (#11)
  • Loading branch information
WiseCrohn authored Oct 11, 2023
1 parent 312a3b1 commit 90c95d5
Show file tree
Hide file tree
Showing 6 changed files with 276 additions and 64 deletions.
35 changes: 35 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: doc generation",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/spec-schema/parser/csi_parser.py",
"args": ["--generate-docs", "${workspaceFolder}/api/rvm-csi-spec.yaml", "--doc-out-dir=${workspaceFolder}/auto-gen"],
"console": "integratedTerminal",
"justMyCode": true
},
{
"name": "Python: test doc generation",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/spec-schema/parser/csi_parser.py",
"args": ["--generate-docs", "${workspaceFolder}/spec-schema/parser/test_data/simple.rvm-csi.yaml", "--doc-out-dir=${workspaceFolder}/spec-schema/parser/adoc_output"],
"console": "integratedTerminal",
"justMyCode": true
},
{
"name": "Python: test header generation",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/spec-schema/parser/csi_parser.py",
"args": ["${workspaceFolder}/spec-schema/parser/test_data/simple.rvm-csi.yaml", "--out-dir=${workspaceFolder}/spec-schema/parser/output"],
"console": "integratedTerminal",
"justMyCode": true
},
]
}
110 changes: 55 additions & 55 deletions api/C/include/csi_hl_console.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,61 +43,6 @@
#include "csi_dl_bsp_uart.h"
#include "csi_types.h"

/*
* Configure a circular buffer for use by csi_uprintf when CSI_UPRINTF_OUTPUT is
* defined as CSI_UPRINTF_CIRCBUFF. This function must be called once, before ever
* calling csi_uprintf in that case, and before ever calling csi_uprintf_circbuff.
* It does not need to be called if not using circular buffer output mode.
*
* @param buff: Pointer to circular buffer to use for console output.
* @param size_bytes: Circular buffer size in bytes.
* @return : Status of operation
*/
csi_status_t csi_set_uprintf_circbuff(void *buff, unsigned size_bytes);

/*
* Configure csi_uprintf operation for use when CSI_UPRINTF_OUTPUT is defined as
* CSI_UPRINTF_UART. This function must be called once, before ever calling
* csi_uprintf in that case, and before ever calling csi_uprintf_uart. It does not
* need to be called if not using UART output mode.
*
* @param uart: Pointer to a UART object which must be initialized (through a call
* to csi_uart_init) prior to use.
* @return : Status of operation
*/
csi_status_t csi_set_uprintf_uart(csi_uart_t *uart);

/*
* Semi-hosting version of csi_uprintf. This is not normally called directly by
* application writers. Rather, call csi_uprintf and define CSI_UPRINTF_OUTPUT to
* be CSI_UPRINTF_SEMIHOST.
*
* @param fmt: Formatted string matching that used by printf
* @return : Number of characters printed. A negative number indicates an error.
*/
int csi_uprintf_semihost(char const *fmt, ...) __attribute__((format(printf, 1, 2)));

/*
* Circular buffering version of csi_uprintf. This is not normally called directly
* by application writers. Rather, call csi_uprintf and define CSI_UPRINTF_OUTPUT
* to be CSI_UPRINTF_CIRCBUFF.
*
* @param fmt: Formatted string matching that used by printf
* @return : Number of characters printed. A negative number indicates an error.
*/
int csi_uprintf_circbuff(char const *fmt, ...) __attribute__((format(printf, 1, 2)));

/*
* UART version of csi_uprintf. This is not normally called directly by
* application writers. Rather, call csi_uprintf and define CSI_UPRINTF_OUTPUT to
* be CSI_UPRINTF_UART.
*
* @param fmt: Formatted string matching that used by printf
* @return : Number of characters printed. A negative number indicates an error.
*/
int csi_uprintf_uart(char const *fmt, ...) __attribute__((format(printf, 1, 2)));


/*
* Max number of characters that can be printed by a single csi_uprintf call. This
* determines the amount of space that the function call will occupy on the stack
Expand Down Expand Up @@ -189,4 +134,59 @@ int csi_uprintf_uart(char const *fmt, ...) __attribute__((format(printf, 1, 2)))
#endif


/*
* Configure a circular buffer for use by csi_uprintf when CSI_UPRINTF_OUTPUT is
* defined as CSI_UPRINTF_CIRCBUFF. This function must be called once, before ever
* calling csi_uprintf in that case, and before ever calling csi_uprintf_circbuff.
* It does not need to be called if not using circular buffer output mode.
*
* @param buff: Pointer to circular buffer to use for console output.
* @param size_bytes: Circular buffer size in bytes.
* @return : Status of operation
*/
csi_status_t csi_set_uprintf_circbuff(void *buff, unsigned size_bytes);

/*
* Configure csi_uprintf operation for use when CSI_UPRINTF_OUTPUT is defined as
* CSI_UPRINTF_UART. This function must be called once, before ever calling
* csi_uprintf in that case, and before ever calling csi_uprintf_uart. It does not
* need to be called if not using UART output mode.
*
* @param uart: Pointer to a UART object which must be initialized (through a call
* to csi_uart_init) prior to use.
* @return : Status of operation
*/
csi_status_t csi_set_uprintf_uart(csi_uart_t *uart);

/*
* Semi-hosting version of csi_uprintf. This is not normally called directly by
* application writers. Rather, call csi_uprintf and define CSI_UPRINTF_OUTPUT to
* be CSI_UPRINTF_SEMIHOST.
*
* @param fmt: Formatted string matching that used by printf
* @return : Number of characters printed. A negative number indicates an error.
*/
int csi_uprintf_semihost(char const *fmt, ...) __attribute__((format(printf, 1, 2)));

/*
* Circular buffering version of csi_uprintf. This is not normally called directly
* by application writers. Rather, call csi_uprintf and define CSI_UPRINTF_OUTPUT
* to be CSI_UPRINTF_CIRCBUFF.
*
* @param fmt: Formatted string matching that used by printf
* @return : Number of characters printed. A negative number indicates an error.
*/
int csi_uprintf_circbuff(char const *fmt, ...) __attribute__((format(printf, 1, 2)));

/*
* UART version of csi_uprintf. This is not normally called directly by
* application writers. Rather, call csi_uprintf and define CSI_UPRINTF_OUTPUT to
* be CSI_UPRINTF_UART.
*
* @param fmt: Formatted string matching that used by printf
* @return : Number of characters printed. A negative number indicates an error.
*/
int csi_uprintf_uart(char const *fmt, ...) __attribute__((format(printf, 1, 2)));


#endif /* CSI_HL_CONSOLE_H */
54 changes: 54 additions & 0 deletions spec-schema/parser/doc_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,53 @@ def format_adoc_function(function, linked_sections):

return out_str

def format_adoc_macro(macro):
''' Builds adoc level 3 & 4 section for supplied macro declaration.
Returns function adoc string.
'''
out_str = heading_marker(3) + macro['name'] + '[[' + macro['name'] + ']]' "\n"
out_str += '''
[source, c]
----
'''
out_str += macro['code']
out_str += "----\n\n"

out_str += macro['description'] + "\n"

if 'notes' in macro.keys():
for note in macro['notes']:
out_str += note + "\n\n"

out_str += heading_marker(4) + "Return\n"

if 'c-return-value' in macro.keys():
out_str += "`" + macro['c-return-value']['type'] + "` - " + \
macro['c-return-value']['description'] + "\n\n"

out_str += heading_marker(4) + "Parameters\n"

if 'c-params' in macro.keys():
for param in macro['c-params']:

param_type = param['type']
param_name = param['name']
if param_type[-1] == '*': # pointer
param_type = param_type.rstrip('* ')
param_name = "*" + param_name

out_str += param_type + " `" + param_name + "` - " + param['description'] + "\n\n"

if 'notes' in param.keys():
out_str += format_text_from_array(param['notes'])
out_str += "\n"
else:
out_str += "Macro takes no parameters\n\n"

return out_str



def generate_c_module_adoc(module, out_dir, module_sub_dir, adoc_optimization, linked_sections):
''' Builds adoc file for a module.
Inputs are the module definition and the output directory & sub directory for the
Expand Down Expand Up @@ -190,6 +237,13 @@ def generate_c_module_adoc(module, out_dir, module_sub_dir, adoc_optimization, l
out_str += "\n"
out_str += "\n"

if 'macros' in module.keys():
out_str += heading_marker(2) + "Macros\n"
for macro in module['macros']:
out_str += format_adoc_macro(macro)
out_str += "\n"
out_str += "\n"

if 'c-definitions' in module.keys():
out_str += heading_marker(2) + "Definitions\n"
for fragment in module['c-definitions']:
Expand Down
65 changes: 56 additions & 9 deletions spec-schema/parser/header_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,37 @@ def format_c_function(function):

return out_str

def format_c_macro(macro):
''' Takes a macro object.
Returns a string containing the associated header file content.
'''

# Start the comment.
out_str = "/*\n "

out_str += format_c_comment_lines(macro['description'])
out_str += "*\n "
if 'notes' in macro.keys():
for note in macro['notes']:
out_str += format_c_comment_lines(note)
out_str += "*\n "

if 'c-params' in macro.keys():
for param in macro['c-params']:
out_str += format_c_comment_lines("@param " + param['name'] + ": " + param['description'])
if 'c-return-value' in macro.keys():
out_str += format_c_comment_lines("@return " + ": " + macro['c-return-value']['description'])

# Close comment
out_str += "*/\n"

# Write out the macro code
out_str += macro['code']
out_str += "\n"

return out_str


def generate_c(api_definition, module_definitions, out_dir):
''' Top level function which iterates through each of the modules in the api definition
to build C header content and write it an appropriate file.
Expand Down Expand Up @@ -173,28 +204,44 @@ def generate_c(api_definition, module_definitions, out_dir):
for include_file in module['c-include-files']:
out_str += format_c_include_file(include_file)
out_str += "\n"


# Protection against inclusion in assembler code if required
if 'no-assembler' in module.keys():
if module['no-assembler']:
out_str += "#ifndef __ASSEMBLER__\n\n"

# Add type declarations
if 'c-type-declarations' in module.keys():
for type_declaration in module['c-type-declarations']:
out_str += format_c_type_declaration(type_declaration)
out_str += "\n"
out_str += "\n"

# Add function declarations
if 'functions' in module.keys():
for function in module['functions']:
out_str += format_c_function(function)
out_str += "\n"
out_str += "\n"

# Add code fragments
if 'c-definitions' in module.keys():
for fragment in module['c-definitions']:
out_str += "/*\n " + format_c_comment_lines(fragment['comment']) + "*/\n"
out_str += fragment['fragment'] + '\n'
out_str += "\n"


# Add macros
if 'macros' in module.keys():
for macro in module['macros']:
out_str += format_c_macro(macro)
out_str += "\n"

# Add function declarations
if 'functions' in module.keys():
for function in module['functions']:
out_str += format_c_function(function)
out_str += "\n"
out_str += "\n"

# Protection against inclusion in assembler code if required
if 'no-assembler' in module.keys():
if module['no-assembler']:
out_str += "#endif // __ASSEMBLER__\n\n"

# Close guard against multiple inclusion
out_str += "#endif /* " + def_file_name + " */ \n"

Expand Down
26 changes: 26 additions & 0 deletions spec-schema/parser/test_data/example-module4.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module:
name: Platform Discovery
description: Functions for discovery of platform characteristics
c-specific: false
no-assembler: true
c-filename: csi_discovery.h
c-type-declarations:
- name: csi_timer_count_t
Expand All @@ -13,3 +14,28 @@ module:
c-return-value:
description: clock frequency in Hz
type: const unsigned
macros:
- name: csi_csr_swap
description: >
Read contents of a CSR to a temporary variable, write val into
the register, then return previous contents.
c-params:
- name: csr
description: CSR name as understood by assembler
type: string
- name: val
description: Value to write to CSR
type: int
c-return-value:
description: Previous CSR contents
type: int
code: |
#define csi_csr_swap(csr, val) \
({ \
rv_csr_t __v = (unsigned long)(val); \
__ASM volatile("csrrw %0, " STRINGIFY(csr) ", %1" \
: "=r"(__v) \
: "rK"(__v) \
: "memory"); \
__v; \
})
Loading

0 comments on commit 90c95d5

Please sign in to comment.