【Android】Android Framework系列---CarPower电源管理
Android Framework系列—CarPower电源管理
智能座舱通常包括中控系统、仪表系统、IVI系统 、后排娱乐、HUD、车联网等。这些系统需要由汽车电源进行供电。由于汽车自身的特殊供电环境(相比手机方便的充电环境,汽车的蓄电池如果没有电是需要专业人士操作的),其电源状态会比较复杂,既要满足车内的座舱系统启动足够快,又要保证汽车蓄电池的可考性,所以出了开机(on)、关机(off)外,会多出来一些电源状态(Suspend、STR、SLEEP等等)
所以,一般来说软件系统是需要一个专门的电源管理模块的。
CarPower电源管理
Android Automotive(基于Android平台的车载信息娱乐系统)提供了CarPower模块用于管理电源状态。CarPower Service属于CarService,在SystemSever的startOtherService阶段启动。
CarPower Service根据来自于 Vehicle HAL(Hal层服务)的电源状态通知,进行相关的逻辑判断后,应用电源策略(简单理解成告知某些服务Enable 或者Disable)、发送状态通知给它自身的监听者、回复(Report)VehcileHAL处理结果。
Vehicle HAL的电源状态一般来讲是来自于MCU的(can通信 或者以太网通信,具体形式由Vehicle HAL和相关供应商决定)。电源状态变化时,MCU一般会拉低或者拉高某个引脚,然后通知事件给VehicleHAL,VehicleHAL再通过PropertyEvent通知给CarPower Service。Android系统处理完电源状态后(有超时要求),再由VehiclHAL告知MCU,MCU在对某个引脚进行相关操作。
CarPower电源管理的开机流程
下面以Android车载系统开机为例。说明一下CarPower模块的开机时序。代码基于Android12.
- CarPower服务启动:Android系统开机上电,在systemServer中启动CarService。
// frameworks/base/services/java/com/android/server/SystemServer.java/*** Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized.*/
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {t.traceBegin("StartCarServiceHelperService");final SystemService cshs = mSystemServiceManager.startService(CAR_SERVICE_HELPER_SERVICE_CLASS);if (cshs instanceof Dumpable) {mDumper.addDumpable((Dumpable) cshs);}if (cshs instanceof DevicePolicySafetyChecker) {dpms.setDevicePolicySafetyChecker((DevicePolicySafetyChecker) cshs);}t.traceEnd();}}// frameworks/opt/car/services/src/com/android/internal/car/CarServiceHelperService.java
public void onStart() {EventLog.writeEvent(EventLogTags.CAR_HELPER_START, mHalEnabled ? 1 : 0);IntentFilter filter = new IntentFilter(Intent.ACTION_REBOOT);filter.addAction(Intent.ACTION_SHUTDOWN);mContext.registerReceiverForAllUsers(mShutdownEventReceiver, filter, null, null);mCarWatchdogDaemonHelper.addOnConnectionChangeListener(mConnectionListener);mCarWatchdogDaemonHelper.connect();// 启动了CarService------------------------------------------Intent intent = new Intent();intent.setPackage("com.android.car");intent.setAction(ICarConstants.CAR_SERVICE_INTERFACE);if (!mContext.bindServiceAsUser(intent, mCarServiceConnection, Context.BIND_AUTO_CREATE,UserHandle.SYSTEM)) {Slog.wtf(TAG, "cannot start car service");}loadNativeLibrary();
}
- CarService启动后会创建CarPower实例。
<!-- packages/services/Car/service/AndroidManifest.xml -->
<application android:label="@string/app_title"android:directBootAware="true"android:allowBackup="false"android:persistent="true"><service android:name=".CarService"android:singleUser="true"><intent-filter><action android:name="android.car.ICar" /></intent-filter></service>
// packages/services/Car/service/src/com/android/car/ICarImpl.java
public class ICarImpl extends ICar.Stub {public ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface,CanBusErrorNotifier errorNotifier, String vehicleInterfaceName) {this(serviceContext, vehicle, systemInterface, errorNotifier, vehicleInterfaceName,/* carUserService= */ null, /* carWatchdogService= */ null);}@VisibleForTestingICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface,CanBusErrorNotifier errorNotifier, String vehicleInterfaceName,@Nullable CarUserService carUserService,@Nullable CarWatchdogService carWatchdogService) {mContext = serviceContext;mSystemInterface = systemInterface;mHal = new VehicleHal(serviceContext, vehicle);// Do this before any other service components to allow feature check. It should work// even without init. For that, vhal get is retried as it can be too early.VehiclePropValue disabledOptionalFeatureValue = mHal.getIfAvailableOrFailForEarlyStage(VehicleProperty.DISABLED_OPTIONAL_FEATURES, INITIAL_VHAL_GET_RETRY);String[] disabledFeaturesFromVhal = null;if (disabledOptionalFeatureValue != null) {String disabledFeatures = disabledOptionalFeatureValue.value.stringValue;if (disabledFeatures != null && !disabledFeatures.isEmpty()) {disabledFeaturesFromVhal = disabledFeatures.split(",");}}if (disabledFeaturesFromVhal == null) {disabledFeaturesFromVhal = new String[0];}Resources res = mContext.getResources();String[] defaultEnabledFeatures = res.getStringArray(R.array.config_allowed_optional_car_features);mFeatureController = new CarFeatureController(serviceContext, defaultEnabledFeatures,disabledFeaturesFromVhal , mSystemInterface.getSystemCarDir());CarLocalServices.addService(CarFeatureController.class, mFeatureController);mVehicleInterfaceName = vehicleInterfaceName;mUserManagerHelper = new CarUserManagerHelper(serviceContext);if (carUserService != null) {mCarUserService = carUserService;} else {UserManager userManager =(UserManager) serviceContext.getSystemService(Context.USER_SERVICE);int maxRunningUsers = res.getInteger(com.android.internal.R.integer.config_multiuserMaxRunningUsers);mCarUserService = new CarUserService(serviceContext, mHal.getUserHal(),mUserManagerHelper, userManager, ActivityManager.getService(), maxRunningUsers);}mCarOccupantZoneService = new CarOccupantZoneService(serviceContext);mSystemActivityMonitoringService = new SystemActivityMonitoringService(serviceContext);// 这里创建了CarPower服务实例-----------------------------------------------------------mCarPowerManagementService = new CarPowerManagementService(mContext, mHal.getPowerHal(),systemInterface, mCarUserService);if (mFeatureController.isFeatureEnabled(CarFeatures.FEATURE_CAR_USER_NOTICE_SERVICE)) {mCarUserNoticeService = new CarUserNoticeService(serviceContext);} else {mCarUserNoticeService = null;}mCarPropertyService = new CarPropertyService(serviceContext, mHal.getPropertyHal());mCarDrivingStateService = new CarDrivingStateService(serviceContext, mCarPropertyService);mCarUXRestrictionsService = new CarUxRestrictionsManagerService(serviceContext,mCarDrivingStateService, mCarPropertyService);if (mFeatureController.isFeatureEnabled(Car.OCCUPANT_AWARENESS_SERVICE)) {mOccupantAwarenessService = new OccupantAwarenessService(serviceContext);} else {mOccupantAwarenessService = null;}mCarPackageManagerService = new CarPackageManagerService(serviceContext,mCarUXRestrictionsService,mSystemActivityMonitoringService,mCarUserService);mPerUserCarServiceHelper = new PerUserCarServiceHelper(serviceContext, mCarUserService);mCarBluetoothService = new CarBluetoothService(serviceContext, mPerUserCarServiceHelper);mCarInputService = new CarInputService(serviceContext, mHal.getInputHal(), mCarUserService);mCarProjectionService = new CarProjectionService(serviceContext, null /* handler */, mCarInputService, mCarBluetoothService);mGarageModeService = new GarageModeService(mContext);mAppFocusService = new AppFocusService(serviceContext, mSystemActivityMonitoringService);mCarAudioService = new CarAudioService(serviceContext);mCarNightService = new CarNightService(serviceContext, mCarPropertyService);mFixedActivityService = new FixedActivityService(serviceContext);mInstrumentClusterService = new InstrumentClusterService(serviceContext,mAppFocusService, mCarInputService);mSystemStateControllerService = new SystemStateControllerService(serviceContext, mCarAudioService, this);mCarStatsService = new CarStatsService(serviceContext);mCarStatsService.init();if (mFeatureController.isFeatureEnabled(Car.VEHICLE_MAP_SERVICE)) {mVmsBrokerService = new VmsBrokerService(mContext, mCarStatsService);} else {mVmsBrokerService = null;}if (mFeatureController.isFeatureEnabled(Car.DIAGNOSTIC_SERVICE)) {mCarDiagnosticService = new CarDiagnosticService(serviceContext,mHal.getDiagnosticHal());} else {mCarDiagnosticService = null;}if (mFeatureController.isFeatureEnabled(Car.STORAGE_MONITORING_SERVICE)) {mCarStorageMonitoringService = new CarStorageMonitoringService(serviceContext,systemInterface);} else {mCarStorageMonitoringService = null;}mCarConfigurationService =new CarConfigurationService(serviceContext, new JsonReaderImpl());mCarLocationService = new CarLocationService(serviceContext);mCarTrustedDeviceService = new CarTrustedDeviceService(serviceContext);mCarMediaService = new CarMediaService(serviceContext, mCarUserService);mCarBugreportManagerService = new CarBugreportManagerService(serviceContext);if (!Build.IS_USER) {mCarExperimentalFeatureServiceController = new CarExperimentalFeatureServiceController(serviceContext);} else {mCarExperimentalFeatureServiceController = null;}if (carWatchdogService == null) {mCarWatchdogService = new CarWatchdogService(serviceContext);} else {mCarWatchdogService = carWatchdogService;}// 将电源服务,添加到Car本地服务List中-----------------------------CarLocalServices.addService(CarPowerManagementService.class, mCarPowerManagementService);CarLocalServices.addService(CarPropertyService.class, mCarPropertyService);CarLocalServices.addService(CarUserService.class, mCarUserService);CarLocalServices.addService(CarTrustedDeviceService.class, mCarTrustedDeviceService);CarLocalServices.addService(CarUserNoticeService.class, mCarUserNoticeService);CarLocalServices.addService(SystemInterface.class, mSystemInterface);CarLocalServices.addService(CarDrivingStateService.class, mCarDrivingStateService);CarLocalServices.addService(PerUserCarServiceHelper.class, mPerUserCarServiceHelper);CarLocalServices.addService(FixedActivityService.class, mFixedActivityService);CarLocalServices.addService(VmsBrokerService.class, mVmsBrokerService);CarLocalServices.addService(CarOccupantZoneService.class, mCarOccupantZoneService);CarLocalServices.addService(AppFocusService.class, mAppFocusService);// Be careful with order. Service depending on other service should be inited later.List<CarServiceBase> allServices = new ArrayList<>();allServices.add(mFeatureController);allServices.add(mCarUserService);allServices.add(mSystemActivityMonitoringService);// 将电源服务,添加到Car服务List中-----------------------------allServices.add(mCarPowerManagementService);allServices.add(mCarPropertyService);allServices.add(mCarDrivingStateService);allServices.add(mCarOccupantZoneService);allServices.add(mCarUXRestrictionsService);addServiceIfNonNull(allServices, mOccupantAwarenessService);allServices.add(mCarPackageManagerService);allServices.add(mCarInputService);allServices.add(mGarageModeService);addServiceIfNonNull(allServices, mCarUserNoticeService);allServices.add(mAppFocusService);allServices.add(mCarAudioService);allServices.add(mCarNightService);allServices.add(mFixedActivityService);allServices.add(mInstrumentClusterService);allServices.add(mSystemStateControllerService);allServices.add(mPerUserCarServiceHelper);allServices.add(mCarBluetoothService);allServices.add(mCarProjectionService);addServiceIfNonNull(allServices, mCarDiagnosticService);addServiceIfNonNull(allServices, mCarStorageMonitoringService);allServices.add(mCarConfigurationService);addServiceIfNonNull(allServices, mVmsBrokerService);allServices.add(mCarTrustedDeviceService);allServices.add(mCarMediaService);allServices.add(mCarLocationService);allServices.add(mCarBugreportManagerService);allServices.add(mCarWatchdogService);// Always put mCarExperimentalFeatureServiceController in last.addServiceIfNonNull(allServices, mCarExperimentalFeatureServiceController);mAllServices = allServices.toArray(new CarServiceBase[allServices.size()]);}
}
- CarPower服务启动后,会注册成为PowerHalService的监听者。并主动发出WAIT_FOR_VHALL(初始状态)告知CarPower的监听者,并取一下当前的屏幕亮度发送给VHAL。并连接Native层的CarPowerPolicyService来初始化电源管理政策。
// packages/services/Car/service/src/com/android/car/CarPowerManagementService.java/*** Power Management service class for cars. Controls the power states and interacts with other* parts of the system to ensure its own state.*/
public class CarPowerManagementService extends ICarPower.Stub implementsCarServiceBase, PowerHalService.PowerEventListener {public CarPowerManagementService(Context context, PowerHalService powerHal,SystemInterface systemInterface, CarUserService carUserService) {this(context, context.getResources(), powerHal, systemInterface, UserManager.get(context),carUserService, new InitialUserSetter(context,(u) -> carUserService.setInitialUser(u),context.getString(R.string.default_guest_name)),IVoiceInteractionManagerService.Stub.asInterface(ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE)));}@VisibleForTestingpublic CarPowerManagementService(Context context, Resources resources, PowerHalService powerHal,SystemInterface systemInterface, UserManager userManager, CarUserService carUserService,InitialUserSetter initialUserSetter,IVoiceInteractionManagerService voiceInteractionService) {mContext = context;mHal = powerHal;mSystemInterface = systemInterface;mUserManager = userManager;mDisableUserSwitchDuringResume = resources.getBoolean(R.bool.config_disableUserSwitchDuringResume);mShutdownPrepareTimeMs = resources.getInteger(R.integer.maxGarageModeRunningDurationInSecs) * 1000;mSwitchGuestUserBeforeSleep = resources.getBoolean(R.bool.config_switchGuestUserBeforeGoingSleep);if (mShutdownPrepareTimeMs < MIN_MAX_GARAGE_MODE_DURATION_MS) {Slog.w(TAG,"maxGarageModeRunningDurationInSecs smaller than minimum required, resource:"+ mShutdownPrepareTimeMs + "(ms) while should exceed:"+ MIN_MAX_GARAGE_MODE_DURATION_MS + "(ms), Ignore resource.");mShutdownPrepareTimeMs = MIN_MAX_GARAGE_MODE_DURATION_MS;}mUserService = carUserService;mInitialUserSetter = initialUserSetter;mVoiceInteractionManagerService = voiceInteractionService;mWifiManager = context.getSystemService(WifiManager.class);mWifiStateFile = new AtomicFile(new File(mSystemInterface.getSystemCarDir(), WIFI_STATE_FILENAME));}
}@Override
public void init() {mPolicyReader.init();mPowerComponentHandler.init();mHal.setListener(this);if (mHal.isPowerStateSupported()) {// 发出初始化状态-------------------------------------------// Initialize CPMS in WAIT_FOR_VHAL stateonApPowerStateChange(CpmsState.WAIT_FOR_VHAL, CarPowerStateListener.WAIT_FOR_VHAL);} else {Slogf.w(TAG, "Vehicle hal does not support power state yet.");onApPowerStateChange(CpmsState.ON, CarPowerStateListener.ON);}// 监控屏幕状态,这个函数中会将屏幕亮度发给Vehicle HALmSystemInterface.startDisplayStateMonitoring(this);// 连接Car PowerPolicy服务,初始化电源政策connectToPowerPolicyDaemon();
}
- CarPower启动会立刻向监听者和VehicleHAL发出WAIT_FOR_VHAL这个状态
// packages/services/Car/service/src/com/android/car/power/CarPowerManagementService.java
private void doHandlePowerStateChange() {CpmsState state;synchronized (mLock) {state = mPendingPowerStates.peekFirst();mPendingPowerStates.clear();if (state == null) {Slogf.e(TAG, "Null power state was requested");return;}Slogf.i(TAG, "doHandlePowerStateChange: newState=%s", state.name());if (!needPowerStateChangeLocked(state)) {return;}// now real power change happens. Whatever was queued before should be all cancelled.releaseTimerLocked();mCurrentState = state;}mHandler.cancelProcessingComplete();Slogf.i(TAG, "setCurrentState %s", state);CarStatsLogHelper.logPowerState(state.mState);switch (state.mState) {case CpmsState.WAIT_FOR_VHAL:// 处理WAIT_FOR_VHAL状态----------------------------handleWaitForVhal(state);break;case CpmsState.ON:handleOn();break;case CpmsState.SHUTDOWN_PREPARE:handleShutdownPrepare(state);break;case CpmsState.SIMULATE_SLEEP:simulateShutdownPrepare();break;case CpmsState.WAIT_FOR_FINISH:handleWaitForFinish(state);break;case CpmsState.SUSPEND:// Received FINISH from VHALhandleFinish();break;default:// Illegal state// TODO: Throw exception?break;}
}private void handleWaitForVhal(CpmsState state) {int carPowerStateListenerState = state.mCarPowerStateListenerState;// TODO(b/177478420): Restore Wifi, Audio, Location, and Bluetooth, if they are artificially// modified for S2R.mSilentModeHandler.querySilentModeHwState();// 给CarPower服务的监听者发送状态sendPowerManagerEvent(carPowerStateListenerState);// Inspect CarPowerStateListenerState to decide which message to send via VHALswitch (carPowerStateListenerState) {case CarPowerStateListener.WAIT_FOR_VHAL:// 通过PowerHAlService向VehicleHAL发送状态mHal.sendWaitForVhal();break;case CarPowerStateListener.SHUTDOWN_CANCELLED:mShutdownOnNextSuspend = false; // This cancels the "NextSuspend"mHal.sendShutdownCancel();break;case CarPowerStateListener.SUSPEND_EXIT:mHal.sendSleepExit();break;}if (mWifiAdjustmentForSuspend) restoreWifi();
}
- 接下来,MCU会给VehicleHAL发送电源通知,VehicleHAL通知(AP_POWER_STATE_REQ= ON) 给CarPower服务。
@Override
public void onHalEvents(List<VehiclePropValue> values) {PowerEventListener listener;synchronized (mLock) {if (mListener == null) {if (mQueuedEvents == null) {mQueuedEvents = new LinkedList<>();}mQueuedEvents.addAll(values);return;}listener = mListener;}dispatchEvents(values, listener);
}private void dispatchEvents(List<VehiclePropValue> values, PowerEventListener listener) {for (VehiclePropValue v : values) {switch (v.prop) {case AP_POWER_STATE_REPORT:// Ignore this property event. It was generated inside of CarService.break;case AP_POWER_STATE_REQ:// 发送的是这个状态------ AP_POWER_STATE_REQ=ONint state = v.value.int32Values.get(VehicleApPowerStateReqIndex.STATE);int param = v.value.int32Values.get(VehicleApPowerStateReqIndex.ADDITIONAL);Slog.i(CarLog.TAG_POWER, "Received AP_POWER_STATE_REQ="+ powerStateReqName(state) + " param=" + param);listener.onApPowerStateChange(new PowerState(state, param));break;case DISPLAY_BRIGHTNESS:{int maxBrightness;synchronized (mLock) {maxBrightness = mMaxDisplayBrightness;}int brightness = v.value.int32Values.get(0) * MAX_BRIGHTNESS / maxBrightness;if (brightness < 0) {Slog.e(CarLog.TAG_POWER, "invalid brightness: " + brightness+ ", set to 0");brightness = 0;} else if (brightness > MAX_BRIGHTNESS) {Slog.e(CarLog.TAG_POWER, "invalid brightness: " + brightness + ", set to "+ MAX_BRIGHTNESS);brightness = MAX_BRIGHTNESS;}Slog.i(CarLog.TAG_POWER, "Received DISPLAY_BRIGHTNESS=" + brightness);listener.onDisplayBrightnessChange(brightness);}break;}}
}
- CarPowerService接收到 AP_POWER_STATE_REQ= ON,认为当前是电源ON的状态。应用电源策略(告知机能模块可以使能)、通知观察者电源状态为ON,然后向VehicleHAL进行回复(也叫report)
packages/services/Car/service/src/com/android/car/power/CarPowerManagementService.java@Override
public void onApPowerStateChange(PowerState state) {synchronized (mLock) {mPendingPowerStates.addFirst(new CpmsState(state));mLock.notify();}// 发给handler,在单独的线程中处理。最终调用的是自身的doHandlePowerStateChange函数mHandler.handlePowerStateChange();
}private void doHandlePowerStateChange() {CpmsState state;synchronized (mLock) {state = mPendingPowerStates.peekFirst();mPendingPowerStates.clear();if (state == null) {Slogf.e(TAG, "Null power state was requested");return;}Slogf.i(TAG, "doHandlePowerStateChange: newState=%s", state.name());if (!needPowerStateChangeLocked(state)) {return;}// now real power change happens. Whatever was queued before should be all cancelled.releaseTimerLocked();mCurrentState = state;}mHandler.cancelProcessingComplete();Slogf.i(TAG, "setCurrentState %s", state);CarStatsLogHelper.logPowerState(state.mState);switch (state.mState) {case CpmsState.WAIT_FOR_VHAL:handleWaitForVhal(state);break;case CpmsState.ON:// 处理电源ON----------------------------------------------------------------handleOn();break;case CpmsState.SHUTDOWN_PREPARE:handleShutdownPrepare(state);break;case CpmsState.SIMULATE_SLEEP:simulateShutdownPrepare();break;case CpmsState.WAIT_FOR_FINISH:handleWaitForFinish(state);break;case CpmsState.SUSPEND:// Received FINISH from VHALhandleFinish();break;default:// Illegal state// TODO: Throw exception?break;}
}@VisibleForTesting
void handleOn() {if (factoryResetIfNeeded()) return;// If current user is a Guest User, we want to inform CarUserNoticeService not to show// notice for current user, and show user notice only for the target user.if (!mSwitchGuestUserBeforeSleep) {updateCarUserNoticeServiceIfNecessary();}boolean isPreemptive;synchronized (mLock) {isPreemptive = mPolicyReader.isPreemptivePowerPolicy(mCurrentPowerPolicyId);}if (!mSilentModeHandler.isSilentMode() && isPreemptive) {cancelPreemptivePowerPolicy();} else {// 应用电源策略---------------------------------applyDefaultPowerPolicyForState(VehicleApPowerStateReport.ON,PolicyReader.POWER_POLICY_ID_ALL_ON);}// 通知观察者电源状态为ON------------------------sendPowerManagerEvent(CarPowerStateListener.ON);// 通过PowerHAlServicee,回复Vehicle HAL(VehicleApPowerStateReport.ON)mHal.sendOn();synchronized (mLock) {if (mIsBooting) {Slogf.d(TAG, "handleOn(): called on boot");mIsBooting = false;return;}}try {mUserService.onResume();} catch (Exception e) {Slogf.e(TAG, e, "Could not switch user on resume");}
}
- 到这里,CarPower主要的开机处理流程完毕。实际上可以看出来,主要是接收Vehicle HAl Event(包括回复VehicleHAL状态),告知监听者电源状态、应用电源政策使能相关机能。并且在启动阶段,取了一下当前的屏幕亮度,告知VehicleHAL(最终是告知MCU)。当然还有一些其他的处理,比如用户服务的恢复,有兴趣的可以读一下这部分代码。
- CarPowerService上电时序图。
相关文章:

【Android】Android Framework系列---CarPower电源管理
Android Framework系列—CarPower电源管理 智能座舱通常包括中控系统、仪表系统、IVI系统 、后排娱乐、HUD、车联网等。这些系统需要由汽车电源进行供电。由于汽车自身的特殊供电环境(相比手机方便的充电环境,汽车的蓄电池如果没有电是需要专业人士操作…...
io测试【FPGA】
按钮: 按钮是区分输入输出的, LED配置成输入,是不会亮的。 //timescale 1s/1ns // 【】是预编译,类似C语言的#include // 这是FPGA原语 //晶振时钟 1ns//类型声明 module LED //跟PLC的FB功能块一样,使用前需要实…...
vue项目中页面跳转传参的方法
在Vue项目中,你可以使用路由(vue-router)来实现页面跳转并传递参数。下面是一些常用的方法: 使用路由的params属性: 在目标页面的路由配置中,设置props: true来启用参数传递。在源页面中,使用th…...

论文速递 TMC 2023 | RoSeFi: 一种利用商用WiFi设备进行稳健的久坐行为监测系统
注1:本文系“最新论文速览”系列之一,致力于简洁清晰地介绍、解读最新的顶会/顶刊论文 TMC 2023 | RoSeFi: 一种利用商用WiFi设备进行稳健的久坐行为监测系统 原文链接:https://ieeexplore.ieee.org/abstract/document/10269067 本文提出了一种稳健的久坐行为监测系统RoSeFi。…...

Day 12 python学习笔记
模块 内置模块 sys模块 概述:Python 的 sys 模块提供访问解释器使用或维护的变量,和与解释器进行交互的函数。通俗来讲,sys 模块为程序与 Python 解释器的交互,提供了一系列的函数和变量,用于操控 Python 运行时的环境…...

DBA笔记(1)
目录 1、rpm yum 命令的使用,参数的含义 rpm命令: yum命令: 2、上传镜像至虚拟机搭建本地yum源 3、chown chomd 命令每一个参数的含义 chown命令: chmod命令: 4、fdisk partd 硬盘分区命令用法 fdisk命令&am…...

C++设计模式_15_Proxy 代理模式
Proxy 代理模式也是属于“接口隔离”模式,通过增加一层间接层来解决问题的模式。 文章目录 1. 动机( Motivation)2. 模式定义3. 结构( Structure )4. 代码演示Proxy 代理模式4.1 常规方法4.2 Proxy 代理模式 5. 要点总结6. 其他参考 1. 动机( Motivation) 在面向对…...

Go学习第十四章——Gin请求与响应
Go web框架——Gin请求与响应 1 响应1.1 String1.2 JSON(*)1.3 HTML(*)1.4 XML1.5 文件(*) 2 请求2.1 请求参数查询参数 (Query)动态参数 (Param)表单参数 (PostForm)原始参数 (GetRawData) 2.2 请求头2.3 …...

【多线程面试题十】、说一说notify()、notifyAll()的区别
文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 面试官:说一说notify()、notify…...
【Element UI】解决 el-button 禁用状态下,el-tooltip 提示不生效问题
文章目录 问题描述解决方法 问题描述 关键代码: <el-tooltipcontent"一段提示内容"placement"bottom"effect"light":disabled"count > 100" ><el-buttontype"text"class"dl-button":dis…...
C++单元测试GoogleTest和GoogleMock十分钟快速上手(gtestgmock)
C单元测试GoogleTest和GoogleMock(gtest&gmock) 环境准备 下载 git clone https://github.com/google/googletest.git # 或者 wget https://github.com/google/googletest/releases/tag/release-1.11.0安装 cd googletest cmake CMakeLists.txt make sudo make instal…...
Starknet的去中心化路线图
1. 引言 StarkWare正以2条路线在迈向去中心化: planningimplementation 以让Starknet协议 走向 去中心化proof-of-stake协议。 Starknet向以太坊发送STARK proofs来验证其状态变更。 一年前Starknet就在做去中心化规划,相关提案见: Sim…...
python基础语法(十二)
目录 标准库认识标准库使用 import 导入模块代码示例: 字符串操作剑指offer 58, 翻转单词顺序题目题目做法代码 leetcode 796, 旋转字符串题目题目做法 leetcode 2255, 统计是给定字符串前缀的字符串数目题目题目做法 代码示例: 文件查找工具 感谢各位大佬对我的支持,如果我的文…...

【开源】基于SpringBoot的农村物流配送系统的设计和实现
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统登录、注册界面2.2 系统功能2.2.1 快递信息管理:2.2.2 位置信息管理:2.2.3 配送人员分配:2.2.4 路线规划:2.2.5 个人中心:2.2.6 退换快递处理:…...
【2024秋招】2023-9-16 贝壳后端开发一面
1 秒杀系统 1.1 如何抗住高并发 1.2 数据一致性你是怎么处理,根据场景来说明你的设计思路 1.3 你们当时系统的架构是怎么样的 秒杀表做节点隔离, 1.4 为了保证数据一致性,引入了redission的锁,你是为了抗住高并发而去为了引入…...

BI是什么?想要了解BI需要从哪些方面入手?
企业为了执行数字化战略,实行数字化转型,实现数据价值,除了需要相关数字化技术及理念、人才等,还需要借助数字化相关应用,例如商业世界中广受企业欢迎的ERP、OA、CRM等业务信息系统,以及上升势头非常迅猛的…...

软件测试---等价类划分(功能测试)
能对穷举场景设计测试点-----等价类划分 等价类划分 说明:在所有测试数据中,具有某种共同特征的数据集合进行划分分类: 1)有效等价类 2)无效等价类步骤:1)明确需求 2)确定有效和无…...

javascript原生态xhr上传多个图片,可预览和修改上传图片为固定尺寸比例,防恶意代码,加后端php处理图片
//前端上传文件 <!DOCTYPE html> <html xmlns"http://www.w3.org/1999/xhtml" lang"UTF-8"></html> <html><head><meta http-equiv"Content-Type" content"text/html;charsetUTF-8;"/><title…...
【Java】Map集合中常用方法
Map集合的常用方法 方法名称作用V put(Key k,V value)添加元素V remove(K key, V value)根据键值删除对应的值void clear()清除所有键值元素boolean containsKey(Object key)判断集合中是否包含指定的键boolean containsValue(Object value)判断集合中是否包含指定的值boolean …...

方太描画未来厨房的模样
作者 | 辰纹 来源 | 洞见新研社 不知不觉中,iPhone已经更新到15代了,家里的电视变成了越来越轻薄的液晶屏,过去被称为“老三样”的富康,捷达、桑塔纳,如今也被以特斯拉为代表的新能源智能汽车们所取代…… 类似以上的…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...