259 views
in System Integration by

Hi EW team,

I understand that the only way to access values from a C-application is through native code. However, in our project, we plan to keep all the enums and defines exclusively on the device side.

For example:
    // Define device states using enums
    enum DeviceState {
        DEVICE_OFF,
        DEVICE_IDLE,
        DEVICE_RUNNING,
        DEVICE_ERROR
    };

    // Macros for device configurations and limits
    #define DEVICE_MAX_ID 100
    #define DEVICE_MIN_ID 1
    #define DEVICE_DEFAULT_ID 50
    #define DEVICE_ERROR_CODE -1

    // Define a struct for the device instance
    struct Device {
        int id;
        enum DeviceState state;
    };

Now, I would like to refer to these enums and macro values from the device side and use them in the Embedded Wizard GUI without declaring any enums or macros on the GUI side. The goal is for the GUI to display string values based on these enums or macros.

Could you please suggest a generic way to achieve this? I'd appreciate any advice on the best approach to implement this cleanly and efficiently.

Thank you for your support!

1 Answer

0 votes
by

Hello,

Now, I would like to refer to these enums and macro values from the device side and use them in the Embedded Wizard GUI without declaring any enums or macros on the GUI side.

Embedded Wizard can't use enums or macros defined outside Embedded Wizard e.g. in native code. What can you do?

Option 1: Use the enums in the opposite direction. That means, define the enums in Embedded Wizard and use them in native code.

Option 2: Implement an import script to parse the C files containing the enums and generate an Embedded Wizard EWU file. In this case let me recommend the section Chora syntax of an enum describing the format how enums are stored in EWU files. EWU files are text files.

Best regards

Paul Banach

by

Hi Paul,

Thank you for your reply.

I would like to go with option 2 because we do not depend on GUI for anything.  Also, How to load the input ewu file into EW before compilation?

Below is my sample script to create a ew file you suggested above. Could you tell me how to load this script via ew before start compilation.

Script:

import re
import os

def parse_enum_and_macros(c_file_path):
    """
    Parses the given C file to extract enum definitions and #define macros.

    :param c_file_path: The path to the C file.
    :return: A dictionary with enum names and their values, and a dictionary of macros.
    """
    enums = {}
    macros = {}

    # Define regex patterns for detecting enum declarations and #define macros
    enum_pattern = r'enum\s+(\w+)\s*\{([^}]*)\}'
    define_pattern = r'#define\s+(\w+)\s+([^/]+)'

    try:
        with open(c_file_path, 'r') as file:
            content = file.read()

            # Find all enum definitions using regex
            enum_matches = re.findall(enum_pattern, content)
            for enum_name, enum_values in enum_matches:
                values = [value.strip() for value in enum_values.split(',') if value.strip()]
                enum_dict = {}
                for value in values:
                    # Handle the case where values like `DEVICE_OFF` are present
                    value_parts = value.split('=')
                    if len(value_parts) == 2:
                        enum_dict[value_parts[0].strip()] = int(value_parts[1].strip())
                    else:
                        enum_dict[value_parts[0].strip()] = None  # Assign None if no value is specified
                enums[enum_name] = enum_dict

            # Find all #define macros using regex
            define_matches = re.findall(define_pattern, content)
            for macro_name, macro_value in define_matches:
                macros[macro_name] = macro_value.strip()

    except FileNotFoundError:
        print(f"Error: File '{c_file_path}' not found.")
    except Exception as e:
        print(f"Error: {e}")

    return enums, macros

def generate_embedded_file(enums, macros, output_file_path):
    """
    Generates an embedded C header file from the extracted enums and macros.

    :param enums: The dictionary containing enums to write to file.
    :param macros: The dictionary containing macros to write to file.
    :param output_file_path: Path to the output embedded file (header or source file).
    """
    with open(output_file_path, 'w') as file:
        file.write("#ifndef DEVICE_CONFIG_H\n")
        file.write("#define DEVICE_CONFIG_H\n\n")
        
        # Generate enum data as embedded C structures
        for enum_name, values in enums.items():
            file.write(f"typedef enum {{\n")
            for enum_value, enum_int in values.items():
                if enum_int is not None:
                    file.write(f"    {enum_value} = {enum_int},\n")
                else:
                    file.write(f"    {enum_value},\n")
            file.write(f"}} {enum_name};\n\n")
        
        # Generate #define macros
        for macro_name, macro_value in macros.items():
            file.write(f"#define {macro_name} {macro_value}\n")
        
        file.write("\n#endif // DEVICE_CONFIG_H\n")

    print(f"Embedded file generated at: {output_file_path}")

def main():
    c_file_path = "example.c"  # Path to your C file
    output_file_path = "device_config.h"  # Path for the output header file
    
    enums, macros = parse_enum_and_macros(c_file_path)
    if enums or macros:
        generate_embedded_file(enums, macros, output_file_path)

if __name__ == "__main__":
    main()

 

by

Hello,

 Could you tell me how to load this script via ew before start compilation.

If you are working with EW 14, the new introduced Import Export functionality could be used. Nevertheless, you will need to start the Import operation manually. An automatism to start such script automatically before compilation is not available.

If you are working with EW <= 13 (or you don't prefer the above mentioned Import/Export functionality), the following approach could be used:

Step 1: Add to your project a new unit.

Step 2: Name the unit e.g. GlobalDefines, etc. When you save the project, the corresponding file e.g. GlobalDefines.ewu is created in your project directory.

Step 3: Start the script outside of Embedded Wizard. The script should overwrite the unit file.

Step 4: If Embedded Wizard was running, a message appears asking you to re-load the modified unit content.

Best regards

Paul Banach

by
Currently we are using EW-12.

At present, I follow the steps you provided here.

Thank you for your great help !!!
by

Hi Paul,

Is there any way to refer the enums like the below without explicitly define a unit in ew (or adding some dummy unit for these enums)? So that both device and EW will be having same names.

Because adding one new unit will add the unit names before this enums. i do not want to implement like this way. I would like to keep the same name in both EW and Device side.

Any help in this will reduce our big naming issues. Please help.

One more question: switch between ew to native and native to ew more frequently will create any issues like slowness in the system. because we have configured diff memory regions for ew and device. Could you lets us know what will happen if we are switching between ew and native?

    #define DEVICE_MAX_ID 100
    #define DEVICE_MIN_ID 1
    #define DEVICE_DEFAULT_ID 50
    #define DEVICE_ERROR_CODE -1

Regards,

Ayyappan R

by

Hello,

Is there any way to refer the enums like the below without explicitly define a unit in ew (or adding some dummy unit for these enums)? So that both device and EW will be having same names.

In order to be compiled, the enums have to be defined inside Embedded Wizard project. Therefore, there is no possibility to access externally existing enums.

Because adding one new unit will add the unit names before this enums. i do not want to implement like this way. I would like to keep the same name in both EW and Device side.

The usage of unit name as prefix is necessary to avoid name conflicts. From technical point of view, in Embedded Wizard each unit acts as a separate name space permitting equally named members to exist inside the units without conflicts.

Any help in this will reduce our big naming issues. Please help.

To avoid long names, you could eventually name the unit containing the enums with a short name, e.g. 'E' for enums. Nevertheless, in order to avoid name conflicts with other project members, it is always a good practice to prefix global members like enums with a prefix identifying its membership.

One more question: switch between ew to native and native to ew more frequently will create any issues like slowness in the system. because we have configured diff memory regions for ew and device. Could you lets us know what will happen if we are switching between ew and native?

You are probably referring the native statement. This statement just injects the native code in the generated code. There is no switch, context switch, etc. causing overhead. 

I hope it answers your questions.

Best regards

Paul Banach

by
Hi Paul,

Thank you for your reply.

I am asking is there any way to refer these defines directly in EW without creating any units? because with some script i can convert all my enums to #define XYZ...

 #define DEVICE_MAX_ID 100
 #define DEVICE_MIN_ID 1
 #define DEVICE_DEFAULT_ID 50
 #define DEVICE_ERROR_CODE -1

Regards,

Ayyappan R
by
No, in order to be compiled, the enums have to be defined inside Embedded Wizard project. Therefore, there is no possibility to access externally existing enums without using a unit.

Embedded Wizard Website | Privacy Policy | Imprint

...