diff --git a/LinSensorTasks.c b/Lin_4_5_SensorTasks.c similarity index 50% rename from LinSensorTasks.c rename to Lin_4_5_SensorTasks.c index 93a7295..98caef2 100644 --- a/LinSensorTasks.c +++ b/Lin_4_5_SensorTasks.c @@ -2,7 +2,7 @@ // Created by cfif on 12.02.2026. // #include -#include "LinSensorTasks.h" +#include "Lin_4_5_SensorTasks.h" #include "CmsisRtosThreadUtils.h" #include "CanPorts.h" #include "LoggerInterface.h" @@ -13,6 +13,9 @@ #define LOG_SIGN5 "Ln5" #define LOGGER env->logger +extern uint64_t StatLIN4[LIN4_SENSOR_COUNT]; +extern tDRS_Stat StatLIN5[LIN5_SENSOR_COUNT]; + const uint8_t DRS_SENSON_ADR_Stat[LIN5_SENSOR_COUNT] = {DRS_DL_Stat, DRS_DR_Stat, DRS_FPL_Stat, @@ -22,12 +25,30 @@ const uint8_t DRS_SENSON_ADR_Stat[LIN5_SENSOR_COUNT] = {DRS_DL_Stat, DRS_FCL_Stat, DRS_FCR_Stat}; +const uint8_t LIN4_SENSON_ADR_Stat[LIN4_SENSOR_COUNT] = {AirQS_Stat, + Aroma_Stat, + Ionizer_Stat, + eTXV_fHVAC_Stat, + eTXV_rHVAC_Stat, + eTXV_batChiller_Stat, + eTXV_eeChiller_Stat}; + +const uint8_t LIN4_SENSON_LEN_Stat[LIN4_SENSOR_COUNT] = {sizeof(tAirQS_Stat), + sizeof(tAroma_Stat), + sizeof(tIonizer_Stat), + sizeof(teTXV_fHVAC_Stat), + sizeof(teTXV_rHVAC_Stat), + sizeof(teTXV_batChiller_Stat), + sizeof(teTXV_eeChiller_Stat)}; + + static lin_event_id_t SEND_SENSOR_COM_x(tSerialPortLinIO *linIo, tLinData *linData, uint8_t COM_ADR) { lin_event_id_t res = linIo->transmitCommand(linIo->env, linData, COM_ADR, 30); // SystemDelayMs(40); return res; } + static lin_event_id_t Set_CCU_Req(tSerialPortLinIO *linIo, tLinData *linData, tCCU_Req *p_CCU_Req) { lin_event_id_t res; @@ -54,11 +75,12 @@ static lin_event_id_t Set_CCU_Req(tSerialPortLinIO *linIo, tLinData *linData, tC return res; } -/* -static lin_event_id_t Get_AirQS_Stat(tLinIO *linIo, tLinData *linData, tAirQS_Stat *p_AirQS_Stat) { + +static lin_event_id_t +Get_Sensor4_Stat(tSerialPortLinIO *linIo, tLinData *linData, void *p_Stat, uint8_t p_Stat_Len, uint8_t ADR_stat) { lin_event_id_t res; - tAirQS_Stat *tAirQS_Stat_ = (tAirQS_Stat *) linData->g_aRxBuffer; + void *pStat_ = (void *) linData->g_aRxBuffer; uint8_t retry = 1; @@ -67,12 +89,12 @@ static lin_event_id_t Get_AirQS_Stat(tLinIO *linIo, tLinData *linData, tAirQS_St linData->direction = LIN_DIRECTION_GET; linData->g_aTxBufferLen = 0; - linData->g_aRxBufferLen = sizeof(tAirQS_Stat); + linData->g_aRxBufferLen = p_Stat_Len; - res = SEND_SENSOR_COM_x(linIo, AirQS_Stat); + res = SEND_SENSOR_COM_x(linIo, linData, ADR_stat); if (res == LIN_RX_COMPLETED) { - memcpy(p_AirQS_Stat, tAirQS_Stat_, sizeof(tAirQS_Stat)); + memcpy(p_Stat, pStat_, p_Stat_Len); break; } @@ -84,56 +106,210 @@ static lin_event_id_t Get_AirQS_Stat(tLinIO *linIo, tLinData *linData, tAirQS_St + //начало----------------------------------------- LIN 4 ---------------------------------------------------------------- //начало----------------------------------------- LIN 4 ---------------------------------------------------------------- //начало----------------------------------------- LIN 4 ---------------------------------------------------------------- //начало----------------------------------------- LIN 4 --------------------------------------------------------------- -static lin_event_id_t Lin4_Scheduler(tLin4TaskSensor *env) { - lin_event_id_t ret = LIN_NO_EVENT; +static lin_event_id_t +Set_Lin4_Stat(tSerialPortLinIO *linIo, tLinData *linData, void *p_Stat, uint8_t p_Stat_Len, uint8_t ADR_stat) { + lin_event_id_t res; - env->d_CCU_Req.CCU_AirQS_Req = 1; - ret = Set_CCU_Req(env->linIo, env->linData, &env->d_CCU_Req); + void *pStat_ = (void *) linData->g_aTxBuffer; -#if (LOG_LIN4_ACTUATOR == 1) - if (ret == LIN_TX_COMPLETED) { - LoggerFormatInfo(LOGGER, LOG_SIGN4, "OK Set_CCU_Req = %d", ret) - } else { - LoggerFormatInfo(LOGGER, LOG_SIGN4, "ERROR Set_CCU_Req = %d", ret) + uint8_t retry = 1; + + while (retry) { + + linData->direction = LIN_DIRECTION_SET; + + linData->g_aTxBufferLen = p_Stat_Len; + linData->g_aRxBufferLen = 0; + + memcpy(pStat_, p_Stat, p_Stat_Len); + + res = SEND_SENSOR_COM_x(linIo, linData, ADR_stat); + + if (res == LIN_TX_COMPLETED) { + break; + } + + --retry; } -#endif + return res; - ret = Get_AirQS_Stat(env->linIo, env->linData, &env->d_AirQS_Stat); +} -#if (LOG_LIN4_ACTUATOR == 1) +static lin_event_id_t Lin4_Scheduler(tLin4TaskSensor *env) { + uint8_t ADR_COM; + + lin_event_id_t ret = env->linIo->receivedCommand(env->linIo->env, &env->linData, &ADR_COM, 1000); if (ret == LIN_RX_COMPLETED) { - LoggerFormatInfo(LOGGER, LOG_SIGN4, - "AirQS_LinRespErr_Stat = %d AirQS_Sens_Stat = %d AirQS_Combined_Stat = %d AirQS_Err_Stat = %d AirQS_COLvl_Stat = %d AirQS_NOxLvl_Stat = %d AirQS_NH3Lvl_Stat = %d", - env->d_AirQS_Stat.AirQS_LinRespErr_Stat, - env->d_AirQS_Stat.AirQS_Sens_Stat, - env->d_AirQS_Stat.AirQS_Combined_Stat, - env->d_AirQS_Stat.AirQS_Err_Stat, - env->d_AirQS_Stat.AirQS_COLvl_Stat, - env->d_AirQS_Stat.AirQS_NOxLvl_Stat, - env->d_AirQS_Stat.AirQS_NH3Lvl_Stat) - } else { - LoggerFormatInfo(LOGGER, LOG_SIGN4, "ERROR Get_AirQS_Stat = %d", ret) - } + + memcpy(&env->Stat[0], &StatLIN4[0], 8 * LIN4_SENSOR_COUNT); + + if (ADR_COM == CCU_Req) { + asm("nop"); +/* + tAirQS_Stat *pAirQS_Stat = (tAirQS_Stat *) &env->Stat[0]; + tAroma_Stat *pAroma_Stat = (tAroma_Stat *) &env->Stat[1]; + tIonizer_Stat *pIonizer_Stat = (tIonizer_Stat *) &env->Stat[2]; + teTXV_fHVAC_Stat *p_teTXV_fHVAC_Stat = (teTXV_fHVAC_Stat *) &env->Stat[3]; + teTXV_rHVAC_Stat *p_teTXV_rHVAC_Stat = (teTXV_rHVAC_Stat *) &env->Stat[4]; + teTXV_batChiller_Stat *p_teTXV_batChiller_Stat = (teTXV_batChiller_Stat *) &env->Stat[5]; + teTXV_eeChiller_Stat *p_teTXV_eeChiller_Stat = (teTXV_eeChiller_Stat *) &env->Stat[6]; + + tCCU_Req *pCCU_Req = (tCCU_Req *) &env->linData.g_aRxBuffer[0]; + + pIonizer_Stat->Ionizer_Ionization_Stat = pCCU_Req->CCU_Ionization_Req; + pAroma_Stat->Aroma_Intens_Stat = pCCU_Req->CCU_AromaIntens_Req; + pAirQS_Stat->AirQS_Sens_Stat = pCCU_Req->CCU_AirQS_Req; + p_teTXV_fHVAC_Stat->eTXV_fHVAC_Pos_Stat = pCCU_Req->CCU_fHVAC_Pos_Val; + p_teTXV_rHVAC_Stat->eTXV_rHVAC_Pos_Stat = pCCU_Req->CCU_rHVAC_Pos_Val; + p_teTXV_batChiller_Stat->eTXV_batChiller_Pos_Stat = pCCU_Req->CCU_batChiller_Pos_Val; + p_teTXV_eeChiller_Stat->eTXV_eeChiller_Pos_Stat = pCCU_Req->CCU_eeChiller_Pos_Val; +*/ + } else { + + for (uint8_t i = 0; i < LIN4_SENSOR_COUNT; ++i) { + + if (ADR_COM == LIN4_SENSON_ADR_Stat[i]) { + + + switch (i) { + + case eeAirQS_Stat: { + tAirQS_Stat *pAirQS_Stat = (tAirQS_Stat *) &env->Stat[i]; + + +#if (LOG_LIN4_SENSOR == 1) + + LoggerFormatInfo(LOGGER, LOG_SIGN4, + "AirQS_LinRespErr_Stat = %d AirQS_Sens_Stat = %d AirQS_Combined_Stat = %d AirQS_Err_Stat = %d AirQS_COLvl_Stat = %d AirQS_NOxLvl_Stat = %d AirQS_NH3Lvl_Stat = %d", + pAirQS_Stat->AirQS_LinRespErr_Stat, + pAirQS_Stat->AirQS_Sens_Stat, + pAirQS_Stat->AirQS_Combined_Stat, + pAirQS_Stat->AirQS_Err_Stat, + pAirQS_Stat->AirQS_COLvl_Stat, + pAirQS_Stat->AirQS_NOxLvl_Stat, + pAirQS_Stat->AirQS_NH3Lvl_Stat) #endif + break; + } + case eeAroma_Stat: { + tAroma_Stat *pAroma_Stat = (tAroma_Stat *) &env->Stat[i]; + + LoggerFormatInfo(LOGGER, LOG_SIGN4, + "Aroma_LinRespErr_Stat = %d Aroma_CartridgeSw_Stat = %d Aroma_Err_Stat = %d Aroma_Intens_Stat = %d Aroma_CartridgeFlavor_Stat = %d Aroma_CartridgeCapacity_Stat = %d", + pAroma_Stat->Aroma_LinRespErr_Stat, + pAroma_Stat->Aroma_CartridgeSw_Stat, + pAroma_Stat->Aroma_Err_Stat, + pAroma_Stat->Aroma_Intens_Stat, + pAroma_Stat->Aroma_CartridgeFlavor_Stat, + pAroma_Stat->Aroma_CartridgeCapacity_Stat) + + break; + } + + case eeIonizer_Stat: { + tIonizer_Stat *pIonizer_Stat = (tIonizer_Stat *) &env->Stat[i]; + + LoggerFormatInfo(LOGGER, LOG_SIGN4, + "Ionizer_LinRespErr_Stat = %d Ionizer_Err_Stat = %d Ionizer_Ionization_Stat = %d", + pIonizer_Stat->Ionizer_LinRespErr_Stat, + pIonizer_Stat->Ionizer_Err_Stat, + pIonizer_Stat->Ionizer_Ionization_Stat) + + break; + } + case eeTXV_fHVAC_Stat: { + teTXV_fHVAC_Stat *p_teTXV_fHVAC_Stat = (teTXV_fHVAC_Stat *) &env->Stat[i]; + + LoggerFormatInfo(LOGGER, LOG_SIGN4, + "eTXV_fHVAC_Pos_Stat = %d eTXV_fHVAC_LinRespErr_Stat = %d eTXV_fHVAC_Err_Stat = %d eTXV_fHVAC_Pressure_Val = %d eTXV_fHVAC_Temp_Val = %d", + p_teTXV_fHVAC_Stat->eTXV_fHVAC_Pos_Stat, + p_teTXV_fHVAC_Stat->eTXV_fHVAC_LinRespErr_Stat, + p_teTXV_fHVAC_Stat->eTXV_fHVAC_Err_Stat, + p_teTXV_fHVAC_Stat->eTXV_fHVAC_Pressure_Val, + p_teTXV_fHVAC_Stat->eTXV_fHVAC_Temp_Val) + + break; + } + + case eeTXV_rHVAC_Stat: { + teTXV_rHVAC_Stat *p_teTXV_rHVAC_Stat = (teTXV_rHVAC_Stat *) &env->Stat[i]; + + LoggerFormatInfo(LOGGER, LOG_SIGN4, + "eTXV_rHVAC_Pos_Stat = %d eTXV_rHVAC_LinRespErr_Stat = %d eTXV_rHVAC_Err_Stat = %d eTXV_fHVAC_Pressure_Val = %d eTXV_rHVAC_Temp_Val = %d", + p_teTXV_rHVAC_Stat->eTXV_rHVAC_Pos_Stat, + p_teTXV_rHVAC_Stat->eTXV_rHVAC_LinRespErr_Stat, + p_teTXV_rHVAC_Stat->eTXV_rHVAC_Err_Stat, + p_teTXV_rHVAC_Stat->eTXV_rHVAC_Pressure_Val, + p_teTXV_rHVAC_Stat->eTXV_rHVAC_Temp_Val) + + break; + } + + case eeTXV_batChiller_Stat: { + teTXV_batChiller_Stat *p_teTXV_batChiller_Stat = (teTXV_batChiller_Stat *) &env->Stat[i]; + + LoggerFormatInfo(LOGGER, LOG_SIGN4, + "eTXV_batChiller_Pos_Stat = %d eTXV_batChiller_LinRespErr_Stat = %d eTXV_batChiller_Err_Stat = %d eTXV_batChiller_Pressure_Val = %d eTXV_batChiller_Temp_Val = %d", + p_teTXV_batChiller_Stat->eTXV_batChiller_Pos_Stat, + p_teTXV_batChiller_Stat->eTXV_batChiller_LinRespErr_Stat, + p_teTXV_batChiller_Stat->eTXV_batChiller_Err_Stat, + p_teTXV_batChiller_Stat->eTXV_batChiller_Pressure_Val, + p_teTXV_batChiller_Stat->eTXV_batChiller_Temp_Val) + + break; + } + + case eeTXV_eeChiller_Stat: { + teTXV_eeChiller_Stat *p_teTXV_eeChiller_Stat = (teTXV_eeChiller_Stat *) &env->Stat[i]; + + LoggerFormatInfo(LOGGER, LOG_SIGN4, + "eTXV_eeChiller_Pos_Stat = %d eTXV_eeChiller_LinRespErr_Stat = %d eTXV_eeChiller_Err_Stat = %d eTXV_eeChiller_Pressure_Val = %d eTXV_eeChiller_Temp_Val = %d", + p_teTXV_eeChiller_Stat->eTXV_eeChiller_Pos_Stat, + p_teTXV_eeChiller_Stat->eTXV_eeChiller_LinRespErr_Stat, + p_teTXV_eeChiller_Stat->eTXV_eeChiller_Err_Stat, + p_teTXV_eeChiller_Stat->eTXV_eeChiller_Pressure_Val, + p_teTXV_eeChiller_Stat->eTXV_eeChiller_Temp_Val) + + break; + } + } + + + ret = Set_Lin4_Stat(env->linIo, &env->linData, &env->Stat[i], LIN4_SENSON_LEN_Stat[i], + LIN4_SENSON_ADR_Stat[i]); + + if (ret == LIN_TX_COMPLETED) { + asm("nop"); + } + + break; + } + } + + } + + } + + return LIN_NO_EVENT; + } void Lin_4_Init(tLin4TaskSensor *env, - tLinData *linData, - tLinIO *linIO, + tSerialPortLinIO *linIO, tLoggerInterface *logger) { env->linIo = linIO; - env->linData = linData; env->logger = logger; env->access = osMutexNew(NULL); @@ -149,11 +325,10 @@ static _Noreturn void Lin4_Thread(tLin4TaskSensor *env) { lin_event_id_t res = Lin4_Scheduler(env); - osMutexRelease(env->access); } - SystemDelayMs(1000); +// SystemDelayMs(1000); } } @@ -168,7 +343,7 @@ void Lin4_StartThread(tLin4TaskSensor *env) { //конец----------------------------------------- LIN 4 ---------------------------------------------------------------- //конец----------------------------------------- LIN 4 ---------------------------------------------------------------- //конец----------------------------------------- LIN 4 ---------------------------------------------------------------- -*/ + //начало----------------------------------------- LIN 5 ---------------------------------------------------------------- //начало----------------------------------------- LIN 5 ---------------------------------------------------------------- @@ -335,8 +510,6 @@ static void set_led_group(tCCU_DRS_Req *req, uint8_t led_group, uint8_t count) { } -bool isNowData; - static lin_event_id_t Lin5_Scheduler(tLin5TaskSensor *env) { uint8_t ADR_COM; @@ -345,23 +518,16 @@ static lin_event_id_t Lin5_Scheduler(tLin5TaskSensor *env) { if (ret == LIN_RX_COMPLETED) { + memcpy(&env->DRS_Stat[0], &StatLIN5[0], sizeof(tDRS_Stat) * LIN5_SENSOR_COUNT); + if (ADR_COM == CCU_DRS_Req) { asm("nop"); } else { - tDRS_Stat DRS_Stat; - if (isNowData) { - isNowData = false; - DRS_Stat.DRS_Btn_Stat = 1; - } else { - isNowData = true; - DRS_Stat.DRS_Btn_Stat = 0; - } - - for (uint8_t i = 0; i < 8; ++i) { + for (uint8_t i = 0; i < LIN5_SENSOR_COUNT; ++i) { if (ADR_COM == DRS_SENSON_ADR_Stat[i]) { - ret = Set_DRS_Stat(env->linIo, &env->linData, &DRS_Stat, DRS_SENSON_ADR_Stat[i]); + ret = Set_DRS_Stat(env->linIo, &env->linData, &env->DRS_Stat[i], DRS_SENSON_ADR_Stat[i]); if (ret == LIN_TX_COMPLETED) { asm("nop"); } @@ -379,6 +545,17 @@ static lin_event_id_t Lin5_Scheduler(tLin5TaskSensor *env) { } +void Lin_5_Set_CCU_DRS_Req(tLin5TaskSensor *env, uint32_t data) { + if (osMutexAcquire(env->access, 1000) == osOK) { + + (*(uint32_t *) &env->d_CCU_DRS_Req) = data; + + osMutexRelease(env->access); + } else { + LoggerErrorStatic(LOGGER, LOG_SIGN5, "Lin_5_Set_CCU_DRS_Req"); + } +} + void Lin_5_Init(tLin5TaskSensor *env, tSerialPortLinIO *linIo, tLoggerInterface *logger) { @@ -441,10 +618,12 @@ void Lin5_StartThread(tLin5TaskSensor *env) { -void Lin_Timeouts_Init(tLinTimeoutsTask *env, tSerialPortLinIO *lin1Io, tLoggerInterface *logger) { +void +Lin_Timeouts_Init(tLinTimeoutsTask *env, tSerialPortLinIO *lin1Io, tSerialPortLinIO *lin2Io, tLoggerInterface *logger) { env->logger = logger; env->lin1Io = lin1Io; + env->lin2Io = lin2Io; InitThreadAtrStatic(&env->threadLin.attr, "LinTimeouts", env->threadLin.controlBlock, env->threadLin.stack, osPriorityNormal); @@ -454,6 +633,7 @@ void Lin_Timeouts_Init(tLinTimeoutsTask *env, tSerialPortLinIO *lin1Io, tLoggerI static _Noreturn void LinTimeouts_Thread(tLinTimeoutsTask *env) { for (;;) { LIN_CheckTimeout(env->lin1Io->env); + LIN_CheckTimeout(env->lin2Io->env); SystemDelayMs(1); } } diff --git a/LinSensorTasks.h b/Lin_4_5_SensorTasks.h similarity index 93% rename from LinSensorTasks.h rename to Lin_4_5_SensorTasks.h index 00595c5..af597cc 100644 --- a/LinSensorTasks.h +++ b/Lin_4_5_SensorTasks.h @@ -12,9 +12,19 @@ #include "SerialPortIO.h" #define LOG_LIN4_SENSOR 1 -#define LOG_LIN5_SENSOR 1 +#define LOG_LIN5_SENSOR 0 -#define LIN5_SENSOR_COUNT 8 +#define LIN4_SENSOR_COUNT 7 + +typedef enum { + eeAirQS_Stat = 0, + eeAroma_Stat = 1, + eeIonizer_Stat = 2, + eeTXV_fHVAC_Stat = 3, + eeTXV_rHVAC_Stat = 4, + eeTXV_batChiller_Stat = 5, + eeTXV_eeChiller_Stat = 6 +} eSensorStat4; #define AirQS_Stat 0x14 #define Aroma_Stat 0x5 @@ -25,6 +35,8 @@ #define eTXV_batChiller_Stat 0x22 #define eTXV_eeChiller_Stat 0x24 +#define LIN5_SENSOR_COUNT 8 + #define CCU_DRS_Req 0x1 #define DRS_DL_Stat 0xD #define DRS_DR_Stat 0x12 @@ -111,7 +123,7 @@ typedef struct __attribute__ ((packed)) { } teTXV_batChiller_Stat; typedef struct __attribute__ ((packed)) { - uint8_t eTXV_eeChiller_Stat_: 7; // 0 + uint8_t eTXV_eeChiller_Pos_Stat: 7; // 0 uint8_t eTXV_eeChiller_LinRespErr_Stat: 1; // 7 uint8_t eTXV_eeChiller_Err_Stat: 2; // 8 uint8_t eTXV_eeChiller_Pressure_Val: 6; // 10 @@ -119,6 +131,7 @@ typedef struct __attribute__ ((packed)) { } teTXV_eeChiller_Stat; + typedef struct __attribute__ ((packed)) { uint8_t CCU_DLLed1_Req: 1; // 0 uint8_t CCU_DLLed2_Req: 1; // 1 @@ -216,12 +229,13 @@ typedef struct { tSerialPortLinIO *linIo; osMutexId_t access; - tLinData *linData; + tLinData linData; tLoggerInterface *logger; tCCU_Req d_CCU_Req; - tAirQS_Stat d_AirQS_Stat; + uint64_t Stat[LIN4_SENSOR_COUNT]; + struct { osThreadId_t id; @@ -242,6 +256,8 @@ typedef struct { uint8_t Error_Connect; // Ошибка LIN шины (не одно устройство не отвечает) } SensorButtonCmdBusInput; */ + + typedef struct { osMutexId_t access; @@ -268,8 +284,8 @@ typedef struct { uint8_t error_connect; tCCU_DRS_Req d_CCU_DRS_Req; - tCCU_DRS_Req d_old_CCU_DRS_Req; + tDRS_Stat DRS_Stat[LIN5_SENSOR_COUNT]; struct { osThreadId_t id; @@ -281,14 +297,12 @@ typedef struct { } tLin5TaskSensor; -/* void Lin_4_Init(tLin4TaskSensor *env, - tLinData *linData, - tLinIO *linIO, + tSerialPortLinIO *linIO, tLoggerInterface *logger); void Lin4_StartThread(tLin4TaskSensor *env); -*/ + void Lin_5_Init(tLin5TaskSensor *env, tSerialPortLinIO *linIo, @@ -296,11 +310,13 @@ void Lin_5_Init(tLin5TaskSensor *env, void Lin5_StartThread(tLin5TaskSensor *env); +void Lin_5_Set_CCU_DRS_Req(tLin5TaskSensor *env, uint32_t data); typedef struct { tLoggerInterface *logger; tSerialPortLinIO *lin1Io; + tSerialPortLinIO *lin2Io; struct { osThreadId_t id; @@ -311,7 +327,7 @@ typedef struct { } tLinTimeoutsTask; -void Lin_Timeouts_Init(tLinTimeoutsTask *env, tSerialPortLinIO *lin1Io, tLoggerInterface *logger); +void Lin_Timeouts_Init(tLinTimeoutsTask *env, tSerialPortLinIO *lin1Io, tSerialPortLinIO *lin2Io, tLoggerInterface *logger); void LinTimeouts_StartThread(tLinTimeoutsTask *env);