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 an overview of stubbing configuration, supported patterns, and recommended resolution techniques.
In addition to the stubbing logic itself, the current script package also provides:
Include-aware file-scoped extraction scheduling through configuration.
Optional structured JSON reporting for automation flows.
Configurable online or local migration-documentation links inside generated reports.
Interactive HTML source workspaces with migration progress tracking and editable draft support.
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.
|
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 can be done by overriding the default value of
StubbingCompilationFlag
in
hal1_detection_config.py
or by modifying it through the interactive menu.
|
Field |
Default value |
Description |
|---|---|---|
|
StubbingCompilationFlag |
TO_DO_RESOLVE_STUB |
Flag used for HAL1 stubbing. |
Warning message configuration ¶
Users can customize the injected warning messages to match their preferences by modifying
hal1_detection_config.py.
Note
The
UseWarningMessage
field must be set to
True
to enable the customization of the configuration; otherwise, the customized settings are ignored.
|
Field |
Default value |
Possible configuration |
|---|---|---|
|
UseWarningMessage |
True |
True/False |
The available field configurations are listed in the table below.
|
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 ¶
|
Example |
|---|
|
Edit the
|
|
Configuration 1
|
|
Configuration 2
|
|
Configuration 3 (edit of configuration 2 by setting the
|
Using the stubbing feature ¶
Detection and stubbing ¶
The two execution modes are intended for different phases of the migration workflow:
dry-run: Analyze the application and generate reports without modifying user source files.stub: Analyze the application, inject stubbing guards and warnings, and regenerate the reports.
For a cautious migration flow, begin with
dry-run
so that you can review the generated reports before enabling source-file modifications through
stub
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 |
|
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.
|
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.
|
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.
|
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 HAL1 code has been stubbed, follow these steps to resolve the pattern:
Replace the HAL1 API with the HAL2 equivalent by following the log links in the file.
Comment the
#warning,#ifdef, and#endifcompilation directives.Repeat the first two steps until the entire application file is resolved.
Delete the commented compilation directives.
During this workflow, the generated per-file HTML report can be used as a companion view to:
Jump from each detected API to the migration documentation.
Mark resolved API occurrences as done.
Keep an editable draft of the target source during migration review.
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;
}