Skip to content

Latest commit

 

History

History
151 lines (82 loc) · 6.48 KB

File metadata and controls

151 lines (82 loc) · 6.48 KB

C++ Code generation

API

def ccode(self,directory,config=Configuration())

It is a method of the Schedule object returned by computeSchedule.

It generate C++ code implementing the static schedule.

  • directory : The directory where to generate the C++ files
  • config : An optional configuration object

Options for C Code Generation

C OptionalArgs (default = [])

Optional arguments to pass to the C API.

The are 3 variants :

  • cOptionalInitArgs : For init function
  • cOptionalExecutionArgs : For main scheduler function
  • cOptionalFreeArgs : for free function

It can either use a string or a list of string where an element is an argument of the function (and should be valid C).

For instance, with:

conf.cOptionalArgs=["int someVariable"]

The API of the generated scheduler function would be:

uint32_t scheduler(int *error,int someVariable)

switchCase (default = True)

When the schedule is encoded as an array, it can either be an array of function pointers (switchCase false) or an array of indexes for a state machine (switchCase true)

eventRecorder (default = False)

Enable the generation of CMSIS EventRecorder intrumentation in the code. You need to use the file cg.scvd that is providing definition of the following events for display in the Event Recorder:

  • Schedule iteration
  • Node execution
  • Error

appConfigCName (default = "app_config.h")

Name of custom header in generated C code. If you use several scheduler, you may want to use different headers for each one.

postCustomCName (default = "")

Name of custom header in generated C code coming after all of the other includes. By default none is used.

genericNodeCName (default = "GenericNodes.h")

Name of GenericNodes header in generated C code. If you use several scheduler, you may want to use different headers for each one.

This file can be used from the CMSIS-Stream repository. It can also be generated by the Python using the function generateGenericNodes(destination_folder)

appNodesCName (default = "AppNodes.h")

Name of AppNodes header in generated C code. If you use several scheduler, you may want to use different headers for each one.

schedulerCFileName (default = "scheduler")

Name of scheduler cpp and header in generated C code. If you use several scheduler, you may want to use different headers for each one.

If the option is set to xxx, the names generated will be xxx.cpp and xxx.h

CAPI (default = True)

By default, the scheduler function is callable from C. When false, it is a standard C++ API.

CMSISDSP (default = False)

If you use any of the datatypes or functions of the CMSIS-DSP, you need to include the arm_math.h in the scheduler file. This option can thus be set to True. You can also use the custom.h header file to include any additional header

When this property is false, cstdint is included instead of arm_math.h to provide definitions for standard types like int32_t, uint32_t etc ... Otherwise those definitions are provided by arm_math.h

asynchronous (default = False)

This mode is deprecated. Instead use the fullyAsynchronous mode.

fullyAsynchronous (default = False)

When true, the scheduling is for a dynamic / asynchronous flow. A node may not always produce or consume the same amount of data. As consequence, a scheduling can fail. Each node needs to implement a prepareForRunning function to identify and recover from FIFO underflows and overflows.

A synchronous schedule is not used as start so the FIFO lengths cannot be computed during the scheduling. You need to specify the lengths of the FIFOs using the option fifoAsyncLength of the connect methods. This length is expressed in samples.

The option fullyAsynchonous implies switchCase. This disables memoryOptimizations.

Synchronous FIFOs that are just buffers will be considered as FIFOs in asynchronous mode.

More info are available in the documentation for this mode.

FIFOIncrease (default 0)

In case of dynamic / asynchronous scheduling, the FIFOs may need to be bigger than what is computed assuming a static / synchronous scheduling. This option is used to increase the FIFO size. It represents a percent increase.

For instance, a value of 10 means the FIFO will have their size updated from oldSize to 1.1 * oldSize which is (1 + 10%)* oldSize

If the value is a float instead of an int it will be used as is. For instance, 1.1 would increase the size by 1.1 and be equivalent to the setting 10 (for 10 percent).

It is deprecated (only used for the asynchronous mode)

asyncDefaultSkip (default True)

Behavior of a pure function (like CMSIS-DSP) in asynchronous mode. When True, the execution is skipped if the function can't be executed. If False, an error is raised.

If another error recovery is needed, the function must be packaged into a C++ class to implement a prepareForRun function.

bufferAllocation (default False)

The buffers used by the FIFO are dynamically allocated. CMSIS-Stream code generation will generate two APIs (with arguments like for the scheduler API):

extern int init_buffer_scheduler();
extern void free_buffer_scheduler();

Internally, those functions are using the macros CG_MALLOC and CG_FREE that can be redefined.

nodeIdentification (default False)

This setting implies heapAllocation. When it is true, a new API is generated to allow to identify and access a node from the outside of the scheduler.

A node named mynode will be identified with a number MYNODE_ID that is defined as a macro. The node can be accessed with :

  • CStreamNode get_scheduler_node(int32_t nodeID)

This get_scheduler_node function and its return type can be totally customized. The default implementation rely on file cstream_node.h and IdentifiedNode.h. See the documentation about node identification

schedulerCFileName is used to customize the name of the function (The scheduler part is replaced by what you have defined).

The prefix setting is used to change the name of the identification number in case you may use several schedulers.

Inside the CPP wrapper, you have access to the member function nodeID to know the ID of the currently executing node. A node may not identify itself to the outside world. In that case, the ID is set to UNIDENTIFIED_NODE and has value -1.

Most nodes are identifying themselves by default (except the duplicate nodes). Look at the documentation about node creation to know more.