当前位置:网站首页>[detailed explanation of AUTOSAR 14 startup process]
[detailed explanation of AUTOSAR 14 startup process]
2022-07-05 18:43:00 【Ke Yuqian】
Autosar fourteen Start up process details
Link to the file :
1. vLinkGen_Template.lsl
It is noted here that the starting function is :brsStartupEntry function ;
"StartupEntry" = "brsStartupEntry";
"_start_tc0_asr" = "brsStartupEntry";
"_start_tc1_asr" = "brsStartupEntry";
"_start_tc2_asr" = "brsStartupEntry";
"_start_tc3_asr" = "brsStartupEntry";
"_start_tc4_asr" = "brsStartupEntry";
"_start_tc5_asr" = "brsStartupEntry";
2. BrsHwStartup.c
brsStartupEntry Function as follows , Next, let's talk about what this function does :
2.1 The configured memory area belongs to 0
#if defined (VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS)
# if (VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS>1uL)
/* Loop over all entries of vLinkGen_ZeroInit_Early_Groups and zero the configured memory areas. */
volatile uint32 *memPtr2;
uint8 areaNum;
for(areaNum = 0; areaNum < vLinkGen_ZeroInit_Early_GroupsSet.Num; areaNum++)
{
if(vLinkGen_ZeroInit_Early_GroupsSet.Areas[areaNum].Core == CurrentCoreId &&
(vLinkGen_ZeroInit_Early_GroupsSet.Areas[areaNum].End - vLinkGen_ZeroInit_Early_GroupsSet.Areas[areaNum].Start) > 0)
{
memPtr2 = (volatile uint32 *)vLinkGen_ZeroInit_Early_GroupsSet.Areas[areaNum].Start;
while((uint32)memPtr2 < vLinkGen_ZeroInit_Early_GroupsSet.Areas[areaNum].End)
{
*memPtr2 = 0x0;
memPtr2++;
}
}
}
# endif /*VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS>1uL*/
#else
#error "Mandatory define VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS missing within vLinkGen configuration!"
#endif /*VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS*/
The code is simple , The most important thing is vLinkGen_ZeroInit_Early_GroupsSet This structure , It's defined in :
vLinkGen_Lcfg.c
vLinkGen_Cfg.h
typedef struct
{
/*! Start address of the memory area. */
uint32 Start;
/*! End address of the memory area. */
uint32 End;
/*! Core ID to perform the initialization. */
uint32 Core;
/*! ECC alignment of memory area in bytes. */
uint32 Alignment;
} vLinkGen_MemArea;
typedef struct
{
/*! Number of memory areas in this set. */
uint32 Num;
/*! Table of generic memory areas. */
const vLinkGen_MemArea *Areas;
} vLinkGen_MemAreaSet;
# define VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS 2uL
const vLinkGen_MemArea vLinkGen_ZeroInit_Early_Groups[VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS] =
{
{
/* Brs_Shared_Var */
/* .Start */ (uint32)_Brs_Shared_Var_START,
/* .End */ (uint32)_lc_ge_Brs_Shared_Var,
/* .Core */ 0uL,
/* .Alignment */ 0uL
},
{
0uL,
0uL,
0uL,
0uL
}
};
const vLinkGen_MemAreaSet vLinkGen_ZeroInit_Early_GroupsSet =
{
VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS,
vLinkGen_ZeroInit_Early_Groups
};
It can be seen from here that the starting process starts , Define only Core0 Start and end addresses of memory , And send this memory area to 0:
Start address and end address of memory
- /* .Start */ (uint32)_Brs_Shared_Var_START,
- /* .End */ (uint32)_lc_ge_Brs_Shared_Var,
vLinkGen_Template.lsl
group Brs_Shared_Var_PAD (align = 4)
{
reserved "Brs_Shared_Var_PAD" (size = 0);
}
"_Brs_Shared_Var_START" = "_lc_gb_Brs_Shared_Var";
"_Brs_Shared_Var_END" = ("_lc_ge_Brs_Shared_Var" == 0) ? 0 : "_lc_ge_Brs_Shared_Var" - 1;
"_Brs_Shared_Var_LIMIT" = "_lc_ge_Brs_Shared_Var";
"_Brs_Shared_Var_ALL_START" = "_Brs_Shared_Var_START";
"_Brs_Shared_Var_ALL_END" = "_Brs_Shared_Var_END";
"_Brs_Shared_Var_ALL_LIMIT" = "_Brs_Shared_Var_LIMIT";
}
xxx.mapxml
<row>0x7002f920;_lc_gb_Brs_Shared_Var_GROUP;mpe:vtc:linear</row>
<row>0x7002f920;_lc_gb_Brs_Shared_Var;mpe:vtc:linear</row>
...
<row>0x7002f922;_lc_ge_Brs_Shared_Var;mpe:vtc:linear</row>
<row>0x7002f922;_lc_ge_Brs_Shared_Var_GROUP;mpe:vtc:linear</row>
2.2 Set the stack pointer
uint32 CurrentCoreConfig = 0;
uint32 i;
for (i=0; i<BrsMain_CoreConfig_Size; i++)
{
if (BrsMain_CoreConfig[i].PhysicalCoreId == CurrentCoreId)
{
CurrentCoreConfig = i;
i=BrsMain_CoreConfig_Size+1;
}
}
/* Check, if no valid core config was found */
if (i==BrsMain_CoreConfig_Size)
BrsMainExceptionStartup();
BRS_SET_SP(BrsMain_CoreConfig[CurrentCoreConfig].StartupStackEndLabel);
typedef struct
{
/* Logical Id of configured core. */
uint32 LogicalCoreId;
/* Phyiscal Id of configured core. */
uint32 PhysicalCoreId;
/* End label of the startup stack. */
Brs_AddressOfConstType StartupStackEndLabel;
/* startup stack size */
uint32 StartupStackSize;
/* Reflects if core is an AUTOSAR core. */
brsCoreAsrType CoreIsAsr;
/* Start label of the exception vector table. */
Brs_AddressOfConstType ExcVecLabel;
/* Start label of the interrupt vector table. */
Brs_AddressOfConstType IntVecLabel;
}brsMain_CoreType;
const brsMain_CoreType BrsMain_CoreConfig[6u] =
{
{
/* .LogicalCoreId = */ 0u,
/* .PhysicalCoreId = */ 0u,
/* .StartupStackEndLabel = */ (Brs_AddressOfConstType)(&BRSHW_DEFINE_STARTUP_STACK(0)),
/* .StartupStackSize = */ 10240u,
/* .CoreIsAsr = */ ASR,
/* .ExcVecLabel = */ (Brs_AddressOfConstType)(&BRSHW_DEFINE_EXCVEC(0)),
/* .IntVecLabel = */ (Brs_AddressOfConstType)(&BRSHW_DEFINE_INTVEC(0))
},
...
}
stay
Os_Link_Core0.lsl
You can also find the memory address allocation of each core
#if defined ( OS_LINK_EXCVEC_CODE )
if (exists(".text.OS_EXCVEC_CORE0_CODE"))
{
group OS_EXCVEC_CORE0_CODE_GROUP(align=256)
{
select "[.]text.OS_EXCVEC_CORE0_CODE";
}
"_OS_EXCVEC_CORE0_CODE_START" = "_lc_gb_OS_EXCVEC_CORE0_CODE_GROUP";
"_OS_EXCVEC_CORE0_CODE_END" = "_lc_ge_OS_EXCVEC_CORE0_CODE_GROUP" - 1;
"_OS_EXCVEC_CORE0_CODE_LIMIT" = "_lc_ge_OS_EXCVEC_CORE0_CODE_GROUP";
}
else
{
"_OS_EXCVEC_CORE0_CODE_START" = 0;
"_OS_EXCVEC_CORE0_CODE_END" = 0;
"_OS_EXCVEC_CORE0_CODE_LIMIT" = 0;
}
#endif
2.3 Set up PSW
Program Status Word(PSW)
BRS_MOVE_TO_CSFR(BRS_PSW_OFFSET, 0x00000B80UL);
2.4 To configure PCIX
CPUx Previous Context Information Register(PCIX)
AuxVariable = BRS_MOVE_FROM_CSFR(BRS_PCXI_OFFSET);
AuxVariable &= 0xfff00000UL;
BRS_MOVE_TO_CSFR(BRS_PCXI_OFFSET, AuxVariable);
2.5 To configure CSA
The Context Save Areas (CSA)
/* =========================================================================== */
/* initialize the CSAs (inlined function) */
/* aftwerwards function calls are possible */
/* =========================================================================== */
BRS_CSA_Element* CSA;
uint32 NumberOfCSA;
uint32 pcxi_val = 0; /* the last PCXI has to point to 0 */
uint32 CSAReserve = 20; /* the LCX will be initalized to point to 20 CSAs before the very last CSA */
uint32 seg_nr, seg_idx; /* auxiliary variables to assemble the PCXI value */
BRS_CSA_Element* CSAAddress = (BRS_CSA_Element*)((uint32)BrsMain_CoreConfig[CurrentCoreConfig].StartupStackEndLabel - (uint32)BrsMain_CoreConfig[CurrentCoreConfig].StartupStackSize);
uint32 CSA_Numbers = ((uint32)BrsMain_CoreConfig[CurrentCoreConfig].StartupStackEndLabel - 1024 - (uint32)CSAAddress) / 64;
if (CSA_Numbers<512)
{
/* The configured stack size is smaller than the recommended one! * Beginning with vBaseEnv 2.17, the startup stack setup was harmonized and the stack sizes are configured automatically via the vBRS generator * (vBRS/vBRSGeneral/vBRSEnableCoreSpecificVLinkGenConfig). * The recommended default for the Aurix platforms is 33792 Byte, listed in vBaseEnv/vBaseEnvGeneral/vBaseEnvStartupStackSettings/vBaseEnvStackSize. * This means, 1024 Byte for the startup stack and 512 CSA list entries (64 Byte each). There is no separated section for the CSAs anymory, * they are placed in STACK_Cx, together with the startup stack. Be aware, that the CSAs are shared across all execution instances * (vBRS/vBRSGeneral/vBRSExecutionInstance). All instances inherit it from the first execution instance (vBRS/vBRSGeneral/vBRSFirstInstance). * Uncomment this loop, if you intentionally reduced the size of STACK_Cx and ensure it is suitable for your project. * Otherwise, please increase the size of STACK_Cx to at least 33792 (vLinkGenVarSectionGroup/vLinkGenVarSectionGroupSize). */
// while (1);
}
if(CSAAddress != 0)
{
CSA = CSAAddress;
for (NumberOfCSA=0; NumberOfCSA < CSA_Numbers; NumberOfCSA++) /* loop over all CSA elements */
{
*CSA[0] = pcxi_val; /* *CSA is equal to CSA[0] is equal to CSA.PCXI (it holds the PCXI value and has to point to the next PCXI) */
/* now translate the current CSA address to a valid PCXI value which is used within the AURIX registers */
seg_nr = (((unsigned int)CSA >> 28) & 0xf) << 16;
seg_idx = (((unsigned int)CSA >> 6) & 0xffff);
pcxi_val = seg_nr | seg_idx;
if (NumberOfCSA == CSAReserve) /* reserve CSAs for exception handling */
{
BRS_MOVE_TO_CSFR(BRS_LCX_OFFSET, pcxi_val);
}
CSA++; /* point to the next CSA */
}
BRS_MOVE_TO_CSFR(BRS_FCX_OFFSET, pcxi_val);
}
2.6 Interrupt vector table settings
/* Program the brs default vector table base addresses to handle exceptions during startup */
BrsHw_ExceptionTable_Init((Brs_AddressOfConstType)&_Brs_ExcVect_START, BRS_DEFINE_ADDRESS_UNUSED);
3.BrsMainStartup.c
Brs_ApplicationEntry();
The main function of this function is to operate on the memory area ( Clear and assign )
Then enter main(); Function
4.BrsMain.c
stay main() Function, first initialize the interrupt vector table of each core
/* Search for valid Exception- and Interrupt Table in BrsMain_CoreConfig[] (vBRS generated into vBrs_Lcfg.c) */
for (i=0; i<BrsMain_CoreConfig_Size; i++)
{
if (BrsMain_CoreConfig[i].PhysicalCoreId == coreID)
{
BrsHw_ExceptionTable_Init(BrsMain_CoreConfig[i].ExcVecLabel, BrsMain_CoreConfig[i].IntVecLabel);
i=BrsMain_CoreConfig_Size+1;
}
}
/* Check, if no valid core config was found */
if (i==BrsMain_CoreConfig_Size)
BrsMainExceptionHandler(kBrsInvalidCoreConfig, BRSERROR_MODULE_BRSMAIN, (uint16)(__LINE__));
And then initialization RTE
Os_InitMemory();
Os_Init();
then EcuM The module takes over the system
5.EcuM.c
5.1 Set up ECU Boot mode
/* Set the current state of the EcuM to STARTUP */
EcuM_SetModuleState(ECUM_STATE_STARTUP); /* SBSW_ECUM_CSL_VAR_ACCESS */
5.2 To interrupt
/* #30 Set the interrupts on ECUs with programmable interrupts (EcuM_AL_SetProgrammableInterrupts). */
EcuM_AL_SetProgrammableInterrupts();
5.3 Drive list reset
/* #31 Initialize BSW that do not use PostBuild parameters (DriverInitListZero). */
ECUM_DRIVERINITLIST_ZERO();
5.4 Clear the wake-up interrupt source
/* Clear wakeups from all sources */
EcuM_InternalClearWakeupEvent( ECUM_WKSOURCE_ALL_SOURCES);
5.5 Reset timeout wake
/* Reset all wakeup validation timeouts */
for (loopCount = 0u; loopCount < EcuM_GetSizeOfWakeupSourceList(); loopCount++) /* PRQA S 2812 */ /* MD_EcuM_2812 */
{
EcuM_SetValidationTimeoutTable(loopCount, ECUM_NO_VALIDATION_TIMEOUT); /* SBSW_ECUM_ACCESSVALTABLE */
}
5.6 Set up EcuM Pattern
/* Set the current state of the EcuM */
EcuM_SetModuleState(ECUM_STATE_STARTUP_ONE); /* SBSW_ECUM_CSL_VAR_ACCESS */
5.7 start-up OS
/* #51 Start the AUTOSAR OS with the corresponding default appMode. */
EcuM_StartOS( EcuM_GetDefaultAppMode());
6.EcuM_Callout_Stubs.c
EcuM To take over OS After starting According to the nuclear ID Start the cores other than the startup core in turn .
StartCore(coreId, &status);
Last start-up OS
StartOS(appMode);
7.Os_Trap.c
StartCore(coreId, &status);
FUNC(void, OS_CODE) StartCore /* COV_OS_HALPLATFORMTESTEDASMULTICORE */
(
CoreIdType CoreID,
StatusType *Status
)
{
/* #10 If the given status pointer is valid: */
if(OS_UNLIKELY(Os_ErrCheckPointerIsNotNull(Status) != OS_CHECK_FAILED)) /* PRQA S 0315 */ /* MD_Os_Dir1.1_0315 */ /* SBSW_OS_TRAP_ERRCHECKPOINTERISNOTNULL_001 */
{
/* #20 Caller (startup code) is privileged. Call API directly. */
Os_TrapCallStartCore(CoreID, Status); /* SBSW_OS_TRAP_API_USERPOINTER_001 */
}
/* else * Do NOT write the error code to the Status pointer, as it is a NULL_PTR! */
}
OS_FUNC_ATTRIBUTE_DEFINITION(OS_LOCAL_INLINE void, OS_CODE, /* COV_OS_HALPLATFORMTESTEDASMULTICORE */
OS_ALWAYS_INLINE, Os_TrapCallStartCore,
(
CoreIdType CoreID,
StatusType *Status
)) /* COV_OS_HALPLATFORMTESTEDASMULTICORE */
{
/* #10 Inform the trace module on service function entry. */
Os_TraceOrtiApiEntry(OsOrtiApiIdStartCore);
/* #20 Call the API. */
Os_Api_StartCore(CoreID, Status); /* SBSW_OS_FC_PRECONDITION */
/* #30 Inform the trace module on service function exit. */
Os_TraceOrtiApiExit(OsOrtiApiIdStartCore);
}
FUNC(void, OS_CODE) Os_Api_StartCore /* COV_OS_HALPLATFORMMULTICOREUNSUPPORTED */
(
CoreIdType CoreID,
StatusType *Status
)
{
*Status = E_OK; /* PRQA S 2982 */ /* MD_Os_Rule2.2_2982_Config */ /* SBSW_OS_PWA_PRECONDITION */
/* #10 Perform error checks. */
if(Os_CoreIsSingleCoreOs() != 0u) /* COV_OS_TESTSUITERESTRICTIONCORECOUNT */ /* PRQA S 2991, 2992, 2995, 2996 */ /* MD_Os_Rule14.3_2991, MD_Os_Rule14.3_2992, MD_Os_Rule2.2_2995, MD_Os_Rule2.2_2996 */
{
*Status = E_OS_ID; /* SBSW_OS_PWA_PRECONDITION */
}
else if(OS_UNLIKELY(Os_CoreCheckId(CoreID) == OS_CHECK_FAILED ))
{
*Status = E_OS_ID; /* SBSW_OS_PWA_PRECONDITION */
}
else
{
P2CONST(Os_CoreConfigType, AUTOMATIC, OS_CONST) core;
P2CONST(Os_CoreConfigType, AUTOMATIC, OS_CONST) currentCore;
core = Os_CoreId2Core(CoreID);
currentCore = Os_CoreGetCurrentCore();
if(OS_UNLIKELY(Os_CoreCheckIsAsrCore(core) == OS_CHECK_FAILED)) /* SBSW_OS_CORE_CORECHECKISASRCORE_001 */
{
*Status = E_OS_ID; /* SBSW_OS_PWA_PRECONDITION */
}
else
{
if(OS_UNLIKELY(Os_CoreCheckCoreIsInactive(core) == OS_CHECK_FAILED)) /* SBSW_OS_CORE_CORECHECKCOREISINACTIVE_001 */
{
*Status = E_OS_STATE; /* SBSW_OS_PWA_PRECONDITION */
}
else
{
if(Os_CoreIsAsrCore(currentCore) != 0u) /* SBSW_OS_CORE_COREISASRCORE_002 */
{
P2CONST(Os_CoreAsrConfigType, AUTOMATIC, OS_CONST) currentCoreAsr;
currentCoreAsr = Os_Core2AsrCore(currentCore); /* SBSW_OS_CORE_CORE2ASRCORE_002 */
if(OS_UNLIKELY(Os_CoreCheckOsIsNotStarted(currentCoreAsr) == OS_CHECK_FAILED)) /* SBSW_OS_CORE_CORECHECKOSISNOTSTARTED_001 */
{
*Status = E_OS_ACCESS; /* SBSW_OS_PWA_PRECONDITION */
}
}
}
if(OS_LIKELY(*Status == E_OK))
{
P2CONST(Os_CoreAsrConfigType, AUTOMATIC, OS_CONST) coreAsr;
/* #20 Set the core activation request. */
Os_CoreGetStatus(currentCore)->CoreStartRequests[CoreID] = OS_CORESTATE_ACTIVATED_ASR; /* PRQA S 2842 */ /* MD_Os_Rule18.1_2842_Check */ /* SBSW_OS_CORE_COREGETSTATUS_003 */ /* SBSW_OS_CORE_CORESTARTREQUESTS_001 */
coreAsr = Os_Core2AsrCore(core); /* SBSW_OS_CORE_CORE2ASRCORE_001 */
/* #30 Attach to synchronization barrier. */
Os_BarrierAttach(coreAsr->Barrier); /* SBSW_OS_CORE_BARRIERATTACH_001 */
if(core->IsAutostart == TRUE) /* COV_OS_HALPLATFORMNONAUTOSTARTCORE */
{
/* #40 If the core is an auto-start core (already booted), just set the waiting signal. */
OsCfg_CoreBootBarrierRefs[CoreID]->WaitingSign = OS_CORE_BOOTBARRIER_STARTCORE; /* SBSW_OS_CORE_COREBOOTBARRIERREFS_001 */
}
else
{
/* #50 Otherwise start the core through hardware registers. */
Os_Hal_CoreStart(core->HwConfig); /* SBSW_OS_CORE_HAL_CORESTART_001 */
}
}
}
}
}
StartOS(appMode);
FUNC(void, OS_CODE) StartOS
(
AppModeType Mode
)
{
/* #10 Caller (startup code) is privileged. Call API directly. */
Os_TrapCallStartOS(Mode);
}
FUNC(void, OS_CODE) Os_Api_StartOS(AppModeType Mode)
{
/* #10 If the OS is not configured for the interrupt only use case: */
if(Os_CoreIsInterruptOnlyOs() == 0u ) /* PRQA S 2991, 2992, 2995, 2996 */ /* MD_Os_Rule14.3_2991, MD_Os_Rule14.3_2992, MD_Os_Rule2.2_2995, MD_Os_Rule2.2_2996 */
{
P2CONST(Os_CoreConfigType, AUTOMATIC, OS_CONST) core;
core = Os_CoreGetCurrentCore();
/* #10 Check that the core has been started as an AUTOSAR core. */
if(OS_UNLIKELY(Os_CoreCheckStartedAsAsr(core) == OS_CHECK_FAILED)) /* SBSW_OS_CORE_CORECHECKSTARTEDASASR_001 */ /* COV_OS_INVSTATE */
{
Os_ErrKernelPanic();
}
else
{
P2CONST(Os_CoreAsrConfigType, AUTOMATIC, OS_CONST) coreAsr;
coreAsr = Os_Core2AsrCore(core); /* SBSW_OS_CORE_CORE2ASRCORE_002 */
/* #20 Check that StartOS() was not called before. */
if(OS_UNLIKELY(Os_CoreCheckOsIsNotStarted(coreAsr) == OS_CHECK_FAILED)) /* SBSW_OS_CORE_CORECHECKOSISNOTSTARTED_001 */ /* COV_OS_INVSTATE */
{
Os_ErrKernelPanic();
}
else
{
/* #30 Enter the core's Init Hook. */
Os_HookCallOs_CoreInitHook(Os_CoreGetInitHook(coreAsr), Mode); /* SBSW_OS_CORE_COREGETINITHOOK_001 */ /* SBSW_OS_CORE_HOOKCALLOS_COREINITHOOK_001 */
}
}
}
/* #50 Else ignore the call. */
}
边栏推荐
- Is it safe for Apple mobile phone to speculate in stocks? Is it a fraud to get new debts?
- websocket 工具的使用
- How to obtain the coordinates of the aircraft passing through both ends of the radar
- U-Net: Convolutional Networks for Biomedical Images Segmentation
- The 11th China cloud computing standards and Applications Conference | cloud computing national standards and white paper series release, and Huayun data fully participated in the preparation
- AI open2022 | overview of recommendation systems based on heterogeneous information networks: concepts, methods, applications and resources
- 2022年阿里Android高级面试题分享,2022阿里手淘Android面试题目
- 7-2 保持链表有序
- MYSQL中 find_in_set() 函数用法详解
- Powerful tool for collection processing
猜你喜欢
vulnhub之darkhole_2
一朵云开启智慧交通新未来
How to automatically install pythn third-party libraries
2022年阿里Android高级面试题分享,2022阿里手淘Android面试题目
如何写出好代码 - 防御式编程
LeetCode 6111. Spiral matrix IV
Idea configuring NPM startup
AI金榜题名时,MLPerf榜单的份量究竟有多重?
使用JMeter录制脚本并调试
The main thread anr exception is caused by too many binder development threads
随机推荐
MySQL数据库索引教程(超详细)
Find in MySQL_ in_ Detailed explanation of set() function usage
小程序 修改样式 ( placeholder、checkbox的样式)
项目中遇到的问题 u-parse 组件渲染问题
@Extension, @spi annotation principle
让更多港澳青年了解南沙特色文创产品!“南沙麒麟”正式亮相
[use electron to develop desktop on youqilin]
Icml2022 | partial and asymmetric comparative learning of out of distribution detection in long tail recognition
开户注册股票炒股安全吗?有没有风险的?靠谱吗?
Is it safe for golden sun to open an account? Can I open an account free of 5 in case?
音视频包的pts,dts,duration的由来.
2022最新中高级Android面试题目,【原理+实战+视频+源码】
Einstein sum einsum
Record eval() and no in pytoch_ grad()
Is it safe for Apple mobile phone to speculate in stocks? Is it a fraud to get new debts?
Vulnhub's darkhole_ two
c期末复习
Idea configuring NPM startup
vulnhub之darkhole_2
Linear table - abstract data type