1.电脑怎样加载驱动程序
2.proteus怎么读取keil的源码文件?
3.m s ds是什么的简称
4.图解+源码讲解 Nacos 客户端动态监听配置机制
电脑怎样加载驱动程序
NT式驱动程序的加载
1. 用DriverMonitor工具加载NT式驱动
2. 在注册表中填写相应的字段,Windows对NT式驱动程序的加载,是基于服务的方式加载的,类似于Windows服务程序的加载。设备驱动程序的动态加载主要是基于服务控制程序(Service Control Manager,SCM)系统组件完成的。
SCM组件为Windows中运行的组件提供许多服务,例如,如何走读linux源码启动,停止,控制等服务。服务类似于Linux中的守护进程。编写加载驱动程序,主要是操作SCM组件。
WDM式驱动程序的加载
和NT是驱动程序的不同,WDM式驱动程序不能被当做服务程序进行加载,因此不能靠简单的修改注册表来进行加载。WDM式驱动程序的加载需要依靠一个以INF为后缀名的文本文件来描述驱动程序的加载过程。
WDM驱动程序相比较NT式驱动程序增加了即插即用的功能,因此在安装的时候需要一个INF文件来提供支持以提供必要的信息。
系统首先会定位INF文件,根据INF文件上的指示,系统会将驱动程序(sys文件)相关的文件拷贝到相应的系统目录下,修改相应的注册表。同时通知PnP管理器,源码1080iI/O管理器创建新设备,并执行驱动程序的入口函数DriverEntry,INF文件提供了WDM驱动程序所需要的所有信息,包括需要新建和修改的注册表和需要拷贝的文件等。
proteus怎么读取keil的源码文件?
怎么把keil里的文件加载到proteus
1、首先在电脑上用proteus软件打开目标文件。然后用鼠标左键双击单片机图标,如图所示。然后在出现的窗口中,点击下图中的文件夹图标。然后在电脑文件夹中找到编译好的HEX文件导入。2、keil里编译时,设置输出文件为.HEX文件格式。然后在proteus中打开CPU属性,在程序设定栏填入HEX文件路径及名称(也可以通过后面的浏览按钮找到该文件,选中即可)。然后运行即可。
3、proteus里,双击单片机,跳出一对话框,点击programFile边上的文件夹按钮,找到你的山寨币简单源码那个HEX文件,就可以加载。
4、先在keil中把程序编好,在PROTEUS中双击单片机,之后出现这个页面在对话框中找到你keil编写的程序的文件即可。
5、,用keil生成.hex文件,在isis中右击atc,再左击,出现相应元件的属性对话框“ProgramFile”一项中选择要加入的.hex文件。
6、工具/原料windowsXPPROTEUS生成的HEX文件方法/步骤PROTEUS安装好后,默认不会在桌面上产生快捷方式。
c单片机学习求助! 第一步:基础理论知识学习。单片机编程用C语言或汇编语言都可以,但是我建议用C语言比较好,模块化管理编程方便,移植性强,适合编写大程序。,楼主,java 源码gbk编码你首先要学习C语言基础,就相当于%会单片机了,因为现在所有8//位(系列,MSP系列,ARM系列)都是使用C语言。
搞单片机是很枯燥的工作,如果没兴趣很难坚持下来,更不要说出成绩。
我认为这个操作是循环移位,就是将P2的最高位放到最低位,其余位向前移动一位。
uintledout[1],i;//这里应该是ledout[2]我在proteus上进行了仿真,但是不知道什么原因,只对共阳极LED数码管好使。我就把程序稍微做了改动,仿真结果可以正确计时。
voiddisplay(ucharshi,ucharge){ uintledout[1],i;//这里应该是ledout[2]我在proteus上进行了仿真,但是不知道什么原因,只对共阳极LED数码管好使。手机pcapp论坛源码我就把程序稍微做了改动,仿真结果可以正确计时。
keil的代码怎么导入proteus8 在电脑上用proteus软件打开目标文件。用鼠标左键双击单片机图标。在出现的窗口中,点击下图中的文件夹图标。在电脑文件夹中找到编译好的HEX文件导入即可。proteus里,双击单片机,跳出一对话框,点击programFile边上的文件夹按钮,找到你的那个HEX文件,就可以加载。
你要下载到电路板吗?proteus不支持这种功能。
以下一为例,1。用keil4生成hex文件。2。在proteus中找出对应的单片机,放在图里面。3。双击单片机,选之前的hex文件的路径,点击仿真按钮。
如何让KEIL和PROTEUS联调连接 用记事本打开Keil根目录下的TOOLS.INI文件,在[C]栏目下加入TDRVx=BIN\VDM5DLL(ProteusVSMMonitor-Driver),其中“TDRVx”中的“x”要根据实际情况写,不要和已有的号重复,比如TDRV6。运行keil程序,建立一个新的工程。点击工具栏的optionfortarget按钮,在出现的对话框里点击Debug,在右栏上部的下拉菜单里选中ProteusVSMMonitor-Driver,还要点击一下Use前面的小圆点。
进入Proteus的ISIS,鼠标左键点击菜单“Debug”,选中“useromotedebugermonitor”。此后,便可实现KeilC与Proteus连接调试。
修改Keil安装目录的\C\BIN目录下Tools.ini文件,在C字段加入TDRV9=BIN\VDM5DLL(ProteusVSMMonitor-Driver),保存。
m s ds是什么的简称
m s d s 是英文 DriverMonitorSystem 的缩写,即驾驶员监控系统。这个系统致力于对驾驶过程中的潜在风险进行监测与预警。通过一系列高科技手段,m s d s 能够实时检测驾驶员的驾驶状态,包括驾驶疲劳、分心、以及其他危险行为,如打电话、吃东西等。
在驾驶过程中,驾驶员的注意力和反应速度直接影响着行车安全。当驾驶员出现疲劳驾驶、注意力分散等情况时,不仅降低了对路况的判断能力,还可能无法及时应对突发情况。针对这些问题,m s d s 能够通过内置的传感器和摄像头,捕捉驾驶员的行为和面部表情,分析其是否处于安全驾驶状态。
一旦系统检测到驾驶员的注意力无法集中,或有分心行为发生,m s d s 将及时对驾驶员发出警告。这种预警机制能够有效提醒驾驶员注意驾驶安全,防止因注意力不集中导致的交通事故。此外,m s d s 还能通过数据分析,为驾驶员提供个性化的驾驶建议,帮助其提升驾驶技能,增强驾驶安全性。
随着科技的发展,m s d s 不仅在技术上不断进步,其应用场景也在不断拓展。从普通家用汽车到商用货车,再到公共交通工具,m s d s 的应用越来越广泛。通过集成于车辆之中,m s d s 能够为驾驶员提供全方位的安全保障,减少交通事故发生,为公众安全出行提供有力支持。
图解+源码讲解 Nacos 客户端动态监听配置机制
图解+源码讲解 Nacos 客户端动态监听配置机制
在人生中第一要紧的是发现自己。为了这个目的,各位时常需要孤独和深思 —— 南森 Nacos 源码分析系列相关文章
从零开始看 Nacos 源码环境搭建
图解+源码讲解 Nacos 客户端发起注册流程
图解+源码讲解 Nacos 服务端处理注册请求逻辑
图解+源码讲解 Nacos 客户端下线流程
图解+源码讲解 Nacos 服务端处理下线请求
图解+源码讲解 Nacos 客户端发起心跳请求
图解+源码讲解 Nacos 服务端处理心跳请求
图解+源码讲解 Nacos 服务端处理配置获取请求
图解+源码讲解 Nacos 客户端动态监听配置机制
NacosConfigAutoConfiguration我们看到这里面其实注入了一个 Nacos 配置刷新的关键 NacosContextRefresherBean
@Configuration@ConditionalOnProperty(name?=?"spring.cloud.nacos.config.enabled",?matchIfMissing?=?true)public?class?NacosConfigAutoConfiguration?{ //?Nacos?配置属性@Beanpublic?NacosConfigProperties?nacosConfigProperties(ApplicationContext?context)?{ if?(context.getParent()?!=?null&&?BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context.getParent(),?NacosConfigProperties.class).length?>?0)?{ return?BeanFactoryUtils.beanOfTypeIncludingAncestors(context.getParent(),NacosConfigProperties.class);}return?new?NacosConfigProperties();}//?Nacos?配置刷新属性@Beanpublic?NacosRefreshProperties?nacosRefreshProperties()?{ return?new?NacosRefreshProperties();}//?Nacos?刷新历史@Beanpublic?NacosRefreshHistory?nacosRefreshHistory()?{ return?new?NacosRefreshHistory();}//?Nacos?配置管理@Beanpublic?NacosConfigManager?nacosConfigManager(NacosConfigProperties?nacosConfigProperties)?{ return?new?NacosConfigManager(nacosConfigProperties);}//?Nacos?配置刷新@Beanpublic?NacosContextRefresher?nacosContextRefresher(NacosConfigManager?nacosConfigManager,NacosRefreshHistory?nacosRefreshHistory)?{ return?new?NacosContextRefresher(nacosConfigManager,?nacosRefreshHistory);}}NacosContextRefresher 配置中心刷新public?NacosContextRefresher(NacosConfigManager?nacosConfigManager,NacosRefreshHistory?refreshHistory)?{ //?获取配置属性信息this.nacosConfigProperties?=?nacosConfigManager.getNacosConfigProperties();//?刷新历史this.nacosRefreshHistory?=?refreshHistory;//?获取配置服务this.configService?=?nacosConfigManager.getConfigService();//?是否开启刷新,是truethis.isRefreshEnabled?=?this.nacosConfigProperties.isRefreshEnabled();}获取配置服务 getConfigServicenacosConfigManager.getConfigService(),这行代码其实就是为了创建 NcaosConfigService 对象,我们看看你是怎么创建的,其实核心代码就是通过 NacosFactory 反射创建的 NcaosConfigService 对象,这个对象是一个核心对象后续会讲到的
public?static?ConfigService?createConfigService(Properties?properties)?throws?NacosException?{ try?{ //?加载?NacosConfigService?类Class<?>?driverImplClass?=?Class.forName("com.alibaba.nacos.client.config.NacosConfigService");//?获取构造器Constructor?constructor?=?driverImplClass.getConstructor(Properties.class);//?创建实例ConfigService?vendorImpl?=?(ConfigService)?constructor.newInstance(properties);return?vendorImpl;}?catch?(Throwable?e)?{ throw?new?NacosException(NacosException.CLIENT_INVALID_PARAM,?e);}}监听器NacosContextRefresher 实现了 ApplicationListener ,一看这就是一个监听器了,我们看看这个在监听器里面做了什么操作
@Overridepublic?void?onApplicationEvent(ApplicationReadyEvent?event)?{ //?这是一个?CAS?操作,只设置一次if?(this.ready.compareAndSet(false,?true))?{ //?注册?Nacos?监听器对于应用this.registerNacosListenersForApplications();}}注册 Nacos 监听/**register Nacos Listeners. 注册Nacos监听器 */ private void registerNacosListenersForApplications() { // 默认是 true if (isRefreshEnabled()) { // 遍历Nacos属性资源中心 for (NacosPropertySource propertySource : NacosPropertySourceRepository .getAll()) { if (!propertySource.isRefreshable()) { continue; } // 获取资源ID ?String dataId = propertySource.getDataId(); // 通过组和 dataId 注册 Nacos 监听器 registerNacosListener(propertySource.getGroup(), dataId); } } }
private void registerNacosListener(final String groupKey, final String dataKey) { // 构建 Key 信息 String key = NacosPropertySourceRepository.getMapKey(dataKey, groupKey); // 在 listenerMap中放入了 key 对应 AbstractSharedListener 响应的方法 Listener listener = listenerMap.computeIfAbsent(key, lst -> new AbstractSharedListener() { @Override public void innerReceive(String dataId, String group, String configInfo) { // 刷新次数 refreshCountIncrement(); // 记录刷新历史,就是改变历史 nacosRefreshHistory.addRefreshRecord(dataId, group, configInfo); // 发布刷新事件 applicationContext.publishEvent( new RefreshEvent(this, null, "Refresh Nacos config")); } }); // 向配置服务中添加监听器 configService.addListener(dataKey, groupKey, listener);
}
####?向配置服务中添加监听器 此时调用的是?NacosConfigService?中的?addListener?方法,但是最终执行的还是?ClientWorker?中的?addTenantListeners?方法,后面会进行分析?ClientWorker?这个类的```java@Overridepublic?void?addListener(String?dataId,?String?group,?Listener?listener)?throws?NacosException?{ //?这个?ClientWorker?worker?也是一个核心类worker.addTenantListeners(dataId,?group,?Arrays.asList(listener));}构建 CacheData 信息此时向 ClientWorker 中的 CacheData 中添加数据,之后遍历监听器添加到 CacheData 中
创建 CacheData 对象public?CacheData(ConfigFilterChainManager?configFilterChainManager,?String?name,?String?dataId,?String?group,String?tenant)?{ //?dataId?不能为空if?(null?==?dataId?||?null?==?group)?{ throw?new?IllegalArgumentException("dataId="?+?dataId?+?",?group="?+?group);}this.name?=?name;this.configFilterChainManager?=?configFilterChainManager;this.dataId?=?dataId;?//?设置dataIdthis.group?=?group;?//?设置组信息this.tenant?=?tenant;?//?设置租户listeners?=?new?CopyOnWriteArrayList<ManagerListenerWrap>();?//?装饰器集合this.isInitializing?=?true;//?加载缓存数据从本地磁盘this.content?=?loadCacheContentFromDiskLocal(name,?dataId,?group,?tenant);//?计算本地缓存信息的MD5this.md5?=?getMd5String(content);}向 CacheData 中添加数据public?void?addTenantListeners(String?dataId,?String?group,List<?extends?Listener>?listeners)throws?NacosException?{ //?DefaultGroupgroup?=?null2defaultGroup(group);String?tenant?=?agent.getTenant();?//?是?""//?向缓存数据中添加监听器CacheData?cache?=?addCacheDataIfAbsent(dataId,?group,?tenant);for?(Listener?listener?:?listeners)?{ cache.addListener(listener);}}public?CacheData?addCacheDataIfAbsent(String?dataId,?String?group,?String?tenant)throws?NacosException?{ //?获取Key信息String?key?=?GroupKey.getKeyTenant(dataId,?group,?tenant);//?在缓存?Map?中获取缓存数据CacheData?cacheData?=?cacheMap.get(key);//?如果不为空的情况下那么就返回,如果为空那么就创建一个?CacheDataif?(cacheData?!=?null)?{ return?cacheData;}//?创建一个?CacheData?cacheData?=?new?CacheData(configFilterChainManager,?agent.getName(),dataId,?group,?tenant);//?将创建好的?cacheData?放入缓存?Map?中CacheData?lastCacheData?=?cacheMap.putIfAbsent(key,?cacheData);//?如果缓存数据为空的话那么从配置中心拉取,不过此时不为空if?(lastCacheData?==?null)?{ //fix?issue?#?if?(enableRemoteSyncConfig)?{ String[]?ct?=?getServerConfig(dataId,?group,?tenant,?L);cacheData.setContent(ct[0]);}//?计算任务IDint?taskId?=?cacheMap.size()?/?(int)?ParamUtil.getPerTaskConfigSize();//?设置任务IDcacheData.setTaskId(taskId);lastCacheData?=?cacheData;}//?缓存数据初始化完成//?reset?so?that?server?not?hang?this?checklastCacheData.setInitializing(true);LOGGER.info("[{ }]?[subscribe]?{ }",?agent.getName(),?key);MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.size());//?返回最新的缓存数据return?lastCacheData;}到这里 CacheData 对象 和 cacheMap 集合已经构建完成了,后续会用到这个数据的
NacosConfigService 分析NacosConfigService这个类在创建的时候主要做了什么事情,这这里面创建了一个 ClientWorker对象,这个对象是一个核心的类,有关于配置的一些操作都是归功于 ClientWorker类
public?NacosConfigService(Properties?properties)?throws?NacosException?{ ......this.agent?=?new?MetricsHttpAgent(new?ServerHttpAgent(properties));this.agent.start();//?核心工作类this.worker?=?new?ClientWorker(this.agent,this.configFilterChainManager,?properties);}核心配置类 ClientWorker分析一下这个类都在做什么事情,都有哪些核心方法 其实能看到里面有一个构造函数、添加缓存数据、添加监听器、检查配置中心相关方法、获取服务配置、解析数据响应、移除缓存数据、删除监听器以及 shutdown方法
构造函数看到这里其实看到了定义了两个调度线程池,一个是用于配置检测的,一个是用于执行长轮询服务的
@SuppressWarnings("PMD.ThreadPoolCreationRule")public?ClientWorker(final?HttpAgent?agent,final?ConfigFilterChainManager?configFilterChainManager,?final?Properties?properties){ this.agent?=?agent;this.configFilterChainManager?=?configFilterChainManager;//?初始化操作init(properties);//?定义一个调度线程池,只有一个线程还是守护线程this.executor?=?Executors.newScheduledThreadPool(1,?new?ThreadFactory()?{ @Overridepublic?Thread?newThread(Runnable?r)?{ Thread?t?=?new?Thread(r);t.setName("com.alibaba.nacos.client.Worker."?+?agent.getName());t.setDaemon(true);return?t;}});//?定义一个多个线程的调度线程池,线程个数和CPU?核心数有关,也是守护线程,是一个长轮询this.executorService?=?Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(),?new?ThreadFactory()?{ @Overridepublic?Thread?newThread(Runnable?r)?{ Thread?t?=?new?Thread(r);t.setName("com.alibaba.nacos.client.Worker.longPolling."?+agent.getName());t.setDaemon(true);return?t;}});//?定义一个定时的调度任务,第一次执行的时候延时1毫秒,后续毫秒调度一次this.executor.scheduleWithFixedDelay(new?Runnable()?{ @Overridepublic?void?run()?{ try?{ //?检查配置信息方法checkConfigInfo();}?catch?(Throwable?e)?{ LOGGER.error("["?+?agent.getName()?+?"]?"+?"[sub-check]?rotate?check?error",?e);}}},?1L,?L,?TimeUnit.MILLISECONDS);}检查配置服务方法这个 cacheMap 包含了一些任务信息,这里面的任务是怎么来的呢,他是在添加监听器的时候添加的,上面已经分析过了
public?NacosContextRefresher(NacosConfigManager?nacosConfigManager,NacosRefreshHistory?refreshHistory)?{ //?获取配置属性信息this.nacosConfigProperties?=?nacosConfigManager.getNacosConfigProperties();//?刷新历史this.nacosRefreshHistory?=?refreshHistory;//?获取配置服务this.configService?=?nacosConfigManager.getConfigService();//?是否开启刷新,是truethis.isRefreshEnabled?=?this.nacosConfigProperties.isRefreshEnabled();}0长轮询任务 LongPollingRunnable