Script stubbing features

Overview

In addition to its detection capabilities, the HAL1 detection script provides a robust stubbing mechanism for HAL1 elements within user code. The stubbing feature supports a wide range of constructs, including:

  • Function calls (direct, nested, or conditional)

  • Structures (such as typedefs, function arguments, or initializations)

  • Enumerations (user-defined or used within function calls)

  • Constants (as arguments or in variable assignments)

  • Macros

The following sections provide a comprehensive overview of stubbing configuration, supported patterns, and corresponding resolution techniques.

Note

Stubbing refers to the isolation and exclusion of code segments related to the HAL1 API, such as function calls, variable declarations, and other associated components.

Example of stubbing

Original code

Stubbed code

HAL_ADC_Start();
#ifdef TO_DO_RESOLVE_STUB
HAL_ADC_Start();
#endif /* TO_DO_RESOLVE_STUB */

Stubbing and warning message configuration

Stubbing configuration

Users can customize the stubbing compilation flag to meet their specific requirements. This customization can be performed by overriding the default value of StubbingCompilationFlag in the hal1_detection_config.py file or by modifying it through the interactive menu.

stubbing configurability

Field

Default value

Description

StubbingCompilationFlag

TO_DO_RESOLVE_STUB

Flag used for HAL1 stubbing.

Warning message configuration

Users can customize the injected warning log messages based on their preferences. To do this, modify the hal1_detection_config.py file.

Note

The UseWarningMessage field must be set to True to enable the customization of the configuration; otherwise, the customized settings are ignored.

UseWarningMessage configuration

Field

Default value

Possible configuration

UseWarningMessage

True

True/False

The available field configurations are listed in the table below.

Warning message configuration values

Field

Default value

Possible configuration

StubbingWarningMessageSeparator

**

The user can override with their own defined separator

StubbingWarningMessageGenericMessage

STUB TO RESOLVE

The user can override with their own message

UseWarningMessageGenericMessage

True

True/False

UseWarningMessageLineNumber

True

True/False

UseWarningMessageAPIName

True

True/False

UseWarningMessageAPIType

True

True/False

UseWarningMessageAPILayer

True

True/False

UseWarningMessageAPIDriverFile

True

True/False

Examples

Custom warning

Example

Edit the hal1_detection_config.py file as follows (or use the interactive menu)

Screenshot of the ``hal1_detection_config.py`` source code

Configuration 1

Screenshot of the ``hal1_detection_config.py`` source code

Configuration 2

Screenshot of the ``hal1_detection_config.py`` source code

Configuration 3 (edit of configuration 2 by setting the UseWarningMessage field to False)

Screenshot of the ``hal1_detection_config.py`` source code

Using the stubbing feature

Detection and stubbing

script usage [stubbing mode]

Item

Description

Purpose

Analyze the source files and modify them by stubbing the selected modules. A detailed log file is generated.

Syntax

Use one of the following commands:

# Using the Python script
# Compatible with bash and Windows console
python hal1_detection.py -d stub -psrc PATH -m all|module1 module2 ...
# Using the executable on bash
./hal1_detection.exe -d stub -psrc PATH -m all|module1 module2 ...
# Using the executable on Windows console
hal1_detection.exe -d stub -psrc PATH -m all|module1 module2 ...

Mandatory arguments

  • -psrc PATH: path to the source file or directory.

  • -m: specify modules (all or space-separated list).

  • -d stub: detects, stubs, and may modify user source files, generating a log file.

Examples

Examples

# On windows console
# Detect and stub all HAL1 APIs in .\src
hal1_detection.exe -d stub  -psrc .\src -m all

# On bash env use
./hal1_detection.exe -d stub  -psrc ./src -m all
# On windows console
# Detect and stub only 'gpio' and 'uart' APIs in .\src
hal1_detection.exe -d stub -psrc .\src -m gpio uart

# On bash env use
./hal1_detection.exe -d stub -psrc ./src -m gpio uart
# On windows console
# Detect and stub specific HAL1 APIs in a single file
hal1_detection.exe -d stub -psrc .\src\main.c -m spi i2c

# On bash env use
./hal1_detection.exe -d stub -psrc ./src/main.c -m spi i2c

HAL1 API detection and stubbing feature

Stubbing patterns

Function and macro stubbing patterns

The script isolates every detected HAL1 function and macro using the stubbing flag.

The table below outlines the function and macro stubbing patterns implemented in the script.

Supported patterns for function and macro stubbing

General pattern

Example

HAL_PPP_Function(&hppp, param1, ...);
#ifdef TO_DO_RESOLVE_STUB
  HAL_PPP_Function(&hppp, param1, ...);
#endif /* TO_DO_RESOLVE_STUB */
if (HAL_PPP_Function(&hppp, param1,...) == Condition)
{
    HAL_PPP_Function2(&hppp, param1,...);
}
#ifdef TO_DO_RESOLVE_STUB
  if (HAL_PPP_Function(&hppp, param1,...) == Condition)
#endif /* TO_DO_RESOLVE_STUB */
{
#ifdef TO_DO_RESOLVE_STUB
  HAL_PPP_Function2(&hppp, param1,...);
#endif /* TO_DO_RESOLVE_STUB */
}
if (HAL_PPP_Function(&hppp, param1,...) == Condition)
{
    HAL_PPP_Function(&hppp, param1,...);
}
else
{
    HAL_PPP_OtherFunction(&hppp, param1,...);
}
#ifdef TO_DO_RESOLVE_STUB
if (HAL_PPP_Function(&hppp, param1,...) == Condition)
#endif /* TO_DO_RESOLVE_STUB */
{
#ifdef TO_DO_RESOLVE_STUB
  HAL_PPP_Function(&hppp, param1,...);
#endif /* TO_DO_RESOLVE_STUB */
}
#ifdef TO_DO_RESOLVE_STUB
else
#endif /* TO_DO_RESOLVE_STUB */
{
#ifdef TO_DO_RESOLVE_STUB
  HAL_PPP_OtherFunction(&hppp, param1,...);
#endif /* TO_DO_RESOLVE_STUB */
}
uint32_t value = HAL_PPP_Function(&hppp, param,...);
#ifdef TO_DO_RESOLVE_STUB
  uint32_t value = HAL_PPP_Function(&hppp, param,...);
#else
  uint32_t value ;
#endif /* TO_DO_RESOLVE_STUB */
while (Condition = HAL1_func_return_value)
{
    HAL_PPP_Function1(&hppp,...);
    HAL_PPP_Function2(&hppp,...);
}
#ifdef TO_DO_RESOLVE_STUB
while (Condition = HAL1_func_return_value)
#endif /* TO_DO_RESOLVE_STUB */
{
#ifdef TO_DO_RESOLVE_STUB
  HAL_PPP_Function1(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
#ifdef TO_DO_RESOLVE_STUB
   HAL_PPP_Function2(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
}
while ( Condition = user code defined condition )
{
    HAL_PPP_Function1(&hppp,...);
    HAL_PPP_Function2(&hppp,...);
}
while (Condition = user code defined condition)
{
#ifdef TO_DO_RESOLVE_STUB
   HAL_PPP_Function1(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
#ifdef TO_DO_RESOLVE_STUB
   HAL_PPP_Function2(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
}
for (Condition = HAL1_func_return_value)
{
    HAL_PPP_Function1(&hppp,...);
    HAL_PPP_Function2(&hppp,...);
    ...
}
#ifdef TO_DO_RESOLVE_STUB
for (Condition = HAL1_func_return_value)
#endif /* TO_DO_RESOLVE_STUB */
{
#ifdef TO_DO_RESOLVE_STUB
  HAL_PPP_Function1(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
#ifdef TO_DO_RESOLVE_STUB
  HAL_PPP_Function2(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
  ...
}
for (Condition = user code defined condition)
{
    HAL_PPP_Function1(&hppp,...);
    HAL_PPP_Function2(&hppp,...);
    ...
}
for (Condition = user code defined condition)
{
#ifdef TO_DO_RESOLVE_STUB
  HAL_PPP_Function1(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
#ifdef TO_DO_RESOLVE_STUB
  HAL_PPP_Function2(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
  ...
}
do
{
  HAL_PPP_Function1(&hppp, ...);
  HAL_PPP_Function2(&hppp, ...);
} while (Condition = user code defined condition);
do
{
#ifdef TO_DO_RESOLVE_STUB
  HAL_PPP_Function1(&hppp, ...);
#endif /* TO_DO_RESOLVE_STUB */

#ifdef TO_DO_RESOLVE_STUB
  HAL_PPP_Function2(&hppp, ...);
#endif /* TO_DO_RESOLVE_STUB */
} while (Condition = user code defined condition);
do
{
  HAL_PPP_Function1(&hppp, ...);
  HAL_PPP_Function2(&hppp, ...);
} while (Condition = HAL1_func_return_value);
#ifdef TO_DO_RESOLVE_STUB
do
#endif /* TO_DO_RESOLVE_STUB */
{
#ifdef TO_DO_RESOLVE_STUB
  HAL_PPP_Function1(&hppp, ...);
#endif /* TO_DO_RESOLVE_STUB */

#ifdef  TO_DO_RESOLVE_STUB
  HAL_PPP_Function2(&hppp, ...);
#endif /* TO_DO_RESOLVE_STUB */
}
#ifdef  TO_DO_RESOLVE_STUB
while (Condition = HAL1_func_return_value);
#endif /* TO_DO_RESOLVE_STUB */
switch (Selector = user defined selector)
{
    case X:
        HAL_PPP_Function1(&hppp,...);
        HAL_PPP_Function2(&hppp,...);
        break;
    case Y:
        HAL_PPP_Function3(&hppp,...);
        HAL_PPP_Function4(&hppp,...);
        break;
    default:
        HAL_PPP_Other_Function3();
        break;
}
switch (Selector = user defined selector)
{
   case X:
#ifdef TO_DO_RESOLVE_STUB
     HAL_PPP_Function1(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
#ifdef TO_DO_RESOLVE_STUB
     HAL_PPP_Function2(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
     break;
   case Y:
#ifdef TO_DO_RESOLVE_STUB
     HAL_PPP_Function3(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
#ifdef TO_DO_RESOLVE_STUB
     HAL_PPP_Function4(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
     break;
   default:
#ifdef TO_DO_RESOLVE_STUB
     HAL_PPP_Other_Function3();
#endif /* TO_DO_RESOLVE_STUB */
     break;
}
switch (Selector = HAL1_func_return_value)
{
    case X:
        HAL_PPP_Function1(&hppp,...);
        HAL_PPP_Function2(&hppp,...);
        break;
    case Y:
        HAL_PPP_Function3(&hppp,...);
        HAL_PPP_Function4(&hppp,...);
        break;
    default:
        HAL_PPP_Other_Function3();
        break;
}
#ifdef TO_DO_RESOLVE_STUB
switch (Selector = HAL1_func_return_value)
#endif /* TO_DO_RESOLVE_STUB */
{
#ifdef TO_DO_RESOLVE_STUB
  case X:
#ifdef TO_DO_RESOLVE_STUB
     HAL_PPP_Function1(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
#ifdef TO_DO_RESOLVE_STUB
     HAL_PPP_Function2(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
     break;
   case Y:
#ifdef TO_DO_RESOLVE_STUB
     HAL_PPP_Function3(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
#ifdef TO_DO_RESOLVE_STUB
     HAL_PPP_Function4(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
     break;
   default:
#ifdef TO_DO_RESOLVE_STUB
     HAL_PPP_Other_Function3();
#endif /* TO_DO_RESOLVE_STUB */
     break;
#endif /* TO_DO_RESOLVE_STUB */
}

Note

Macros are stubbed by following the same methodology applied to functions.

Constant and enumerator stubbing patterns

The table below outlines the constant and enumerator stubbing patterns implemented in the script.

Supported patterns for constant and enumerator stubbing

General pattern

Example

var = PPP_CONSTANT;
#ifdef TO_DO_RESOLVE_STUB
  var = PPP_CONSTANT;
#endif /* TO_DO_RESOLVE_STUB */
var = PPP_CONSTANT_1 | PPP_CONSTANT_2
      PPP_CONSTANT_3;
#ifdef TO_DO_RESOLVE_STUB
  var = PPP_CONSTANT_1 | PPP_CONSTANT_2
        PPP_CONSTANT_3;
#endif /* TO_DO_RESOLVE_STUB */
User_Function(&hppp, HAL_PPP_CONSTANT) ;
#ifdef TO_DO_RESOLVE_STUB
  User_Function(&hppp, HAL_PPP_CONSTANT) ;
#endif /* TO_DO_RESOLVE_STUB */

Note

Enumerators are stubbed by following the same methodology applied to constants.

Structure and enumeration type stubbing patterns

The table below outlines the structure and enumeration stubbing patterns implemented in the script.

Supported patterns for structure and enumeration stubbing

General Pattern

Example

PPP_StructTypeDef struct;
#ifdef TO_DO_RESOLVE_STUB
  PPP_StructTypeDef struct;
#endif /* TO_DO_RESOLVE_STUB */
User_Function(&HAL_struct, ...);
#ifdef TO_DO_RESOLVE_STUB
  User_Function(&HAL_struct, ...);
#endif /* TO_DO_RESOLVE_STUB */
struct.Instance = PPPx;
struct.Init.field1 = value1;
struct.Init.field2 = value2;
...
struct.Init.field_n = value_n;
#ifdef TO_DO_RESOLVE_STUB
  struct.Instance = PPPx;
  struct.Init.field1 = value1;
  struct.Init.field2 = value2;
  ...
  struct.Init.field_n = value_n;
#endif /* TO_DO_RESOLVE_STUB */

Resolving stubbing patterns

When the HAL1 code has been stubbed, following these steps to resolve pattern:

  1. Replace the HAL1 API by the HAL2 equivalent based on the log links in the file.

  2. Comment the #warning, #ifdef, and #endif compilation directives.

  3. Repeat the first two steps until the entire application file is resolved.

  4. Delete the commented compilation directives.

Special cases

do..while

Initial user code:

do
{
  HAL1_PPP_Function1(&hppp, ...);
  HAL1_PPP_Function2(&hppp, ...);
} while (Condition = HAL1_func_return_value);

Stubbed user code :

#ifdef TO_DO_RESOLVE_STUB
do
#endif /* TO_DO_RESOLVE_STUB */
{
#ifdef TO_DO_RESOLVE_STUB
  HAL1_PPP_Function1(&hppp, ...);
#endif /* TO_DO_RESOLVE_STUB */
#ifdef TO_DO_RESOLVE_STUB
  HAL1_PPP_Function2(&hppp, ...);
#endif /* TO_DO_RESOLVE_STUB */
}
#ifdef TO_DO_RESOLVE_STUB
while (Condition = HAL1_func_return_value);
#endif /* TO_DO_RESOLVE_STUB */

Resolve the do..while statement and comment #ifdef TO_DO_RESOLVE_STUB and #endif TO_DO_RESOLVE_STUB.

//#ifdef TO_DO_RESOLVE_STUB
do
//#endif /* TO_DO_RESOLVE_STUB */
{
 ....
}
//#ifdef TO_DO_RESOLVE_STUB
while (Condition = HAL2_func_return_value);
//#endif /* TO_DO_RESOLVE_STUB */

Proceed with solving the APIs inside the do..while loop.

{
//#ifdef TO_DO_RESOLVE_STUB
  HAL2_PPP_Function1(&hppp, ...);
//#endif /* TO_DO_RESOLVE_STUB */
//#ifdef TO_DO_RESOLVE_STUB
  HAL2_PPP_Function2(&hppp, ...);
//#endif /* TO_DO_RESOLVE_STUB */
}

Finally, remove the comments after completing the entire application file.

do
{
  HAL2_PPP_Function1(&hppp, ...);
  HAL2_PPP_Function2(&hppp, ...);
}
while (Condition = HAL2_func_return_value);
switch..case

Initial user code:

switch (Selector = HAL1 func ret value)
{
    case X:
        HAL_PPP_Function1(&hppp, ...);
        HAL_PPP_Function2(&hppp, ...);
        break;
    case Y:
        HAL_PPP_Function3(&hppp, ...);
        HAL_PPP_Function4(&hppp, ...);
        break;
    default:
        HAL_PPP_Other_Function3();
        break;
}

Stubbed user code:

#ifdef TO_DO_RESOLVE_STUB
switch (Selector = HAL1 func ret value)
#endif /* TO_DO_RESOLVE_STUB */
{
#ifdef TO_DO_RESOLVE_STUB
   case X:
#ifdef TO_DO_RESOLVE_STUB
       HAL_PPP_Function1(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
#ifdef TO_DO_RESOLVE_STUB
       HAL_PPP_Function2(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
       break;
   case Y:
#ifdef TO_DO_RESOLVE_STUB
       HAL_PPP_Function3(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
#ifdef TO_DO_RESOLVE_STUB
       HAL_PPP_Function4(&hppp,...);
#endif /* TO_DO_RESOLVE_STUB */
       break;
   default:
#ifdef TO_DO_RESOLVE_STUB
       HAL_PPP_Other_Function3();
#endif /* TO_DO_RESOLVE_STUB */
       break;
#endif /* TO_DO_RESOLVE_STUB */
}

Resolve the switch statement and comment #ifdef TO_DO_RESOLVE_STUB and #endif TO_DO_RESOLVE_STUB.

//#ifdef TO_DO_RESOLVE_STUB
switch (Selector = HAL2_func_return_value)
//#endif /* TO_DO_RESOLVE_STUB */

Proceed with solving the APIs inside the switch..case structure.

{
 //#ifdef TO_DO_RESOLVE_STUB
   case X:
 //#ifdef TO_DO_RESOLVE_STUB
     HAL2_PPP_Function1(&hppp,...);
 //#endif /* TO_DO_RESOLVE_STUB */
 //#ifdef TO_DO_RESOLVE_STUB
     HAL2_PPP_Function2(&hppp,...);
 //#endif /* TO_DO_RESOLVE_STUB */
     break;
   case Y:
 //#ifdef TO_DO_RESOLVE_STUB
     HAL2_PPP_Function3(&hppp,...);
 //#endif /* TO_DO_RESOLVE_STUB */
 //#ifdef TO_DO_RESOLVE_STUB
     HAL2_PPP_Function4(&hppp,...);
 //#endif /* TO_DO_RESOLVE_STUB */
     break;
   default:
 //#ifdef TO_DO_RESOLVE_STUB
     HAL2_PPP_Other_Function3();
 //#endif /* TO_DO_RESOLVE_STUB */
     break;
 //#endif /* TO_DO_RESOLVE_STUB */
 }

Finally, remove the comments after completing the entire application file.

switch (Selector = HAL2_func_return_value)
{
    case X:
        HAL2_PPP_Function1(&hppp, ...);
        HAL2_PPP_Function2(&hppp, ...);
        break;
    case Y:
        HAL2_PPP_Function3(&hppp, ...);
        HAL2_PPP_Function4(&hppp, ...);
        break;
    default:
        HAL2_PPP_Other_Function3();
        break;
}