你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

st-img
chrome
st-img
firefox
st-img
safari
st-img
ie8及以上
shequ.stmicroelectronics.cn
  • ST意法半导体官网
  • STM32中文官网
  • ST全球论坛
登录/注册
  • 首页
  • 技术问答
  • 话题
  • 资源
  • 创客秀
  • 视频
  • 标签
  • 积分商城
  • 每日签到
ssssss

ssssss

 

回答数 0 关注数 0
关注 私信
  • 动态99
  • 提问
  • 回答0
  • 创客秀 0
  • 分享 0
  • 关注0
6 回答

谁能帮忙下载csdn 的这个obd协议,并分享给大家学习

未设置标签
ssssss ssssss 回答时间: 2018-10-11 13:39

zjczm 发表于 2018-10-11 12:43 下载2次都失败。分也扣了2次。 别人都下载好了,有没有用不知道了

赞0
25 回答

下面是我读取汽车电脑模拟器和obd的通信数据,哪个可以...

汽车
骑着毛驴数星星 骑着毛驴数星星 回答时间: 2020-3-21 14:36

不同的ID都代表了什么啊?比如0fb是什么?

赞0
2 回答

谁能帮忙下载这个阿莫电子论坛的程序,非常感谢

未设置标签
ssssss ssssss 回答时间: 2018-9-14 11:37

ap0405209 发表于 2018-9-14 11:08 下了  搞掂 很给力哦

赞0
9 回答

canopen对象字典的理解

未设置标签
KEY1 KEY1 回答时间: 2019-1-29 20:30

最近正在搞这个

赞0
24 回答

关于gb2312字库的问题

未设置标签
ssssss ssssss 回答时间: 2018-8-31 16:11

wolfgang2015 发表于 2018-8-31 16:02 字库?看你能否找到UCDOS的字库,那里面很多。 国标库文件里面也能找到,很多寻址方法 ... 我看的只是gb2312而已

赞0
7 回答

关于stm32烧录文件和map文件的问题

未设置标签
ssssss ssssss 回答时间: 2018-8-28 08:01

feixiang20 发表于 2018-8-28 00:25 编码自动设置,你可以尝试修改几个参数看看效果 好我多观察一下

赞0
4 回答

调试ucos的时候怎么看这个表的变化?或者说看重点看哪几...

未设置标签
ssssss ssssss 回答时间: 2018-8-29 15:58

FreeRTOS任务相关的代码大约占总代码的一半左右,这些代码都在为一件事情而努力,即找到优先级最高的就绪任务,并使之获得CPU运行权。任务切换是这一过程的直接实施者,为了更快的找到优先级最高的就绪任务,任务切换的代码通常都是精心设计的,甚至会用到汇编指令或者与硬件相关的特性,比如Cortex-M3的CLZ指令。因此任务切换的大部分代码是由硬件移植层提供的,不同的平台,实现发方法也可能不同,这篇文章以Cortex-M3为例,讲述FreeRTOS任务切换的过程。 FreeRTOS有两种方法触发任务切换: 执行系统调用,比如普通任务可以使用taskYIELD()强制任务切换,中断服务程序中使用portYIELD_FROM_ISR()强制任务切换;系统节拍时钟中断       对于Cortex-M3平台,这两种方法的实质是一样的,都会使能一个PendSV中断,在PendSV中断服务程序中,找到最高优先级的就绪任务,然后让这个任务获得CPU运行权,从而完成任务切换。       对于第一种任务切换方法,不管是使用taskYIELD()还是portYIELD_FROM_ISR(),最终都会执行宏portYIELD(),这个宏的定义如下: #define portYIELD()                                                \ {                                                                \         /*产生PendSV中断*/                                        \         portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;                \ }       对于第二种任务切换方法,在系统节拍时钟中断服务函数中,首先会更新tick计数器的值、查看是否有任务解除阻塞,如果有任务解除阻塞的话,则使能PandSV中断,代码如下所示: void xPortSysTickHandler( void ) {         /* 设置中断掩码 */         vPortRaiseBASEPRI();         {                 /* 增加tick计数器值,并检查是否有任务解除阻塞 */                 if( xTaskIncrementTick() != pdFALSE )                 {                         /* 需要任务切换。产生PendSV中断 */                         portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;                 }         }         vPortClearBASEPRIFromISR(); }       从上面的代码中可以看出,PendSV中断的产生是通过代码:portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT实现的,它向中断状态寄存器bit28位写入1,将PendSV中断设置为挂起状态,等到优先级高于PendSV的中断执行完成后,PendSV中断服务程序将被执行,进行任务切换工作。       Cortex-M3架构下,PendSV中断服务程序源码如下所示,这篇文章重点分析这段代码。 __asm void xPortPendSVHandler( void ) {         extern uxCriticalNesting;         extern pxCurrentTCB;            /* 指向当前激活的任务 */         extern vTaskSwitchContext;               PRESERVE8         mrs r0, psp                   /* PSP内容存入R0 */            isb                           /* 指令同步隔离,清流水线 */         ldr        r3, =pxCurrentTCB     /* 当前激活的任务TCB指针存入R2 */         ldr        r2, [r3]         stmdb r0!, {r4-r11}          /* 保存剩余的寄存器,异常处理程序执行前,硬件自动将xPSR、PC、LR、R12、R0-R3入栈 */         str r0, [r2]                     /* 将新的栈顶保存到任务TCB的第一个成员中 */         stmdb sp!, {r3, r14}         /* 将R3和R14临时压入堆栈,因为即将调用函数vTaskSwitchContext,调用函数时,返回地址自动保存到R14中,所以一旦调用发生,R14的值会被覆盖,因此需要入栈保护; R3保存的当前激活的任务TCB指针(pxCurrentTCB)地址,函数调用后会用到,因此也要入栈保护*/         mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY   /* 进入临界区 */         msr basepri, r0         dsb                         /* 数据和指令同步隔离 */         isb         bl vTaskSwitchContext        /* 调用函数,寻找新的任务运行,通过使变量pxCurrentTCB指向新的任务来实现任务切换 */         mov r0, #0                   /* 退出临界区*/         msr basepri, r0         ldmia sp!, {r3, r14}         /* 恢复R3和R14*/         ldr r1, [r3]         ldr r0, [r1]                     /* 当前激活的任务TCB第一项保存了任务堆栈的栈顶,现在栈顶值存入R0*/         ldmia r0!, {r4-r11}             /* 出栈*/         msr psp, r0         isb         bx r14                      /* 异常发生时,R14中保存异常返回标志,包括返回后进入线程模式还是处理器模式、使用PSP堆栈指针还是MSP堆栈指针,当调用 bx r14指令后,硬件会知道要从异常返回,然后出栈,这个时候堆栈指针PSP已经指向了新任务堆栈的正确位置,当新任务的运行地址被出栈到PC寄存器后,新的任务也会被执行。*/         nop } 为了便于理解上面的代码,我们先用流程图的方式将整个过程画出来,然后再逐句分析代码。因为图形可以简化程序,并且信息更容易接受。 http://img-blog.csdn.net/20160515192425451?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast 图1-1:任务切换流程       先强调图1-1中的几个术语,首先是“主堆栈指针MSP”和“进程堆栈指针PSP”。对于Cortex-M3硬件,当系统复位后,默认使用MSP指针。MSP指针用于操作系统内核以及处理异常(也就是说中断服务程序中默认强制使用MSP指针,这是硬件自动设置的)。任务(进程)使用PSP指针,操作系统负责从MSP指针切换到PSP指针。这个过程在《FreeRTOS高级篇3---启动调度器》一文的最后部分中进行了讲解:在SVC中断服务程序中启动第一个任务,当从SVC中断服务退出前,通过向r14寄存器最后4位按位或上0x0D,使得硬件在退出时使用进程堆栈指针PSP完成出栈操作并返回后进入线程模式、返回Thumb状态。       其次,“堆栈”和“任务堆栈”也值得强调一下。每个任务都有自己的“任务堆栈”,在任务创建时会创建指定大小的任务堆栈,这是任务能够独立运行的前提条件之一。在任务中定义的局部变量,会优先使用寄存器,寄存器不够时就使用任务堆栈的空间。如果在任务中调用其它函数,则调用前的保存信息也存到任务堆栈中去。根据任务代码来估算任务堆栈的大小是件十分重要的技能。前面也说了,Cortex-M3硬件有两个堆栈指针,操作系统内核以及异常处理程序中使用MSP指针,所以它们也需要一个堆栈空间,我们称之为“堆栈”,这个堆栈空间和任务堆栈空间在物理上是绝对不可以重叠的,图1-2展示了一个编译好的程序可能的RAM分配情况(堆栈向下生长)。 http://img-blog.csdn.net/20160515192436885?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast 图1-2:RAM中的变量和堆栈分布示意图       有了上面的基础,接下来我们来分析PendSV中断服务程序。 mrs r0, psp       是将任务堆栈指针PSP的值保存到寄存器R0中,因为接下来我们会将寄存器R4~R11也保存到任务堆栈中,但是我们没有哪个汇编指令能直接操作PSP完成入栈,所以只能借助R0。 ldr        r3, =pxCurrentTCB                    /* 当前激活的任务TCB指针存入R2 */ ldr        r2, [r3]       这两句代码是获取当前激活的任务TCP指针,指针pxCurrentTCB前面文章已经提到过很多次了,它是位于tasks.c文件中定义的唯一一个全局指针型变量,指向当前激活的任务TCB。 stmdb r0!, {r4-r11}      这句代码用于将寄存器R4~R11保存到当前激活的程序任务堆栈中,并且同步更新寄存器R0的值。    str r0, [r2]      寄存器R2中保存当前激活的任务TCB指针,在《FreeRTOS高级篇2---FreeRTOS任务创建分析》中讲任务TCB数据结构时我们知道,任务TCB数据结构第一个成员一定是指向任务当前堆栈栈顶的指针变量pxTopOfStack。这句代码将R0的内容保存到任务TCB数据结构的第一个成员pxTopOfStack中,也就是将最新的任务堆栈指针保存到任务TCB的pxTopOfStack字段中。当任务被激活时,就是从这个字段中获取任务堆栈指针,然后完成数据出栈操作的。 stmdb sp!, {r3, r14}      将R3和R14临时压入堆栈,因为即将调用函数vTaskSwitchContext。调用函数时,返回地址自动保存到R14中,所以一旦调用发生,R14的值会被覆盖,因此需要入栈保护。R3保存的当前激活的任务TCB指针(pxCurrentTCB)地址,函数调用后会用到,因此也要入栈保护。 mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY    msr basepri, r0       这两句代码用来进入临界区,中断优先级大于等于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断都会被屏蔽。 bl vTaskSwitchContext      调用函数,选择下一个要执行的任务,也就是寻找处于就绪态的最高优先级任务。变量pxCurrentTCB指向找到的任务TCB。这个函数是核心中的核心,所有的其它代码都是为了保证这个函数能正确运行。       某些运行FreeRTOS的硬件有两种方法:通用方法和特定于硬件的方法(以下简称“特殊方法”)。       1.对于通用方法: configUSE_PORT_OPTIMISED_TASK_SELECTION设置为0或者硬件不支持这种特殊方法。可以用于所有FreeRTOS支持的硬件。完全用C实现,效率略低于特殊方法。不强制要求限制最大可用优先级数目       2.对于特殊方法: 并非所有硬件都支持。必须将configUSE_PORT_OPTIMISED_TASK_SELECTION设置为1。依赖一个或多个特定架构的汇编指令(一般是类似计算前导零[CLZ]指令)。比通用方法更高效。一般强制限定最大可用优先级数目为32(0~31)。       Cortex-M3即支持通用方法也支持特殊方法,默认的移植层使用特殊方法。我们先来看一下通用方法如何找到下一个要执行的任务。       在函数vTaskSwitchContext中使用宏taskSELECT_HIGHEST_PRIORITY_TASK()完成任务寻址工作,使用通用方法时,这个宏的代码如下所示。pxReadyTasksLists是定义在tasks.c中的静态列表数组,表示就绪任务列表数组。在《FreeRTOS高级篇2---FreeRTOS任务创建分析》中讲过这个变量:新创建任务的过程中,任务TCB中的状态列表项xStateListItem会挂接到就绪任务列表数组中。uxTopReadyPriority也是定义在tasks.c中的静态变量,在此之前,它已经代表处于就绪态任务的最高优先级值,在FreeRTOS任务创建与分析一文中,我们也讲到了这个变量:每次任务创建,都会判断新任务的优先级是否大于这个变量,如果大于,还会更新这个变量的值。       while()循环从优先级uxTopReadyPriority开始,从就绪列表数组pxReadyTasksLists中找出优先级最高的任务,然后调用宏listGET_OWNER_OF_NEXT_ENTRY获取最高优先级列表中的下一个列表项,并从该列表项中获取任务TCB指针赋给变量pxCurrentTCB。         #define taskSELECT_HIGHEST_PRIORITY_TASK()                                                                \         {                                                                                                                                        \                 /* 从就绪列表数组中找出最高优先级列表*/                                \                 while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )                \                 {                                                                                                                                \                         configASSERT( uxTopReadyPriority );                                                                \                         --uxTopReadyPriority;                                                                                        \                 }                                                                                                                                \                                                                                                                                                 \                 /* 相同优先级的任务使用时间片共享处理器就是通过这个宏实现*/          \                 listGET_OWNER_OF_NEXT_ENTRY(pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );   \         } /* taskSELECT_HIGHEST_PRIORITY_TASK */       对于Cortex-M3硬件,还支持特殊方法选择下一个要执行的任务,那就是利用硬件提供的计算前导零指令CLZ。特殊方法时,宏taskSELECT_HIGHEST_PRIORITY_TASK()的代码如下所示。         #define taskSELECT_HIGHEST_PRIORITY_TASK()                                                                \         {                                                                                                                                        \         UBaseType_t uxTopPriority;                                                                                                \                                                                                                                                                 \                 /* 从就绪列表数组中找出最高优先级列表*/                                          \                 portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority );                        \                 listGET_OWNER_OF_NEXT_ENTRY(pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \         } /* taskSELECT_HIGHEST_PRIORITY_TASK() */       与通用方法相比,可以发现从就绪列表数组中找出最高优先级列表代码不同了,特殊方法使用宏portGET_HIGHEST_PRIORITY来实现,将宏定义替换后,代码为: uxTopPriority = ( 31UL - ( uint32_t ) __clz( (uxTopReadyPriority) ) )      在此之前,静态变量uxTopReadyPriority同样已经包含处于就绪态任务的最高优先级的信息。与通用方法中使用任务优先级数值不同,在特殊方法中,uxTopReadyPriority使用每一位来表示任务,比如变量uxTopReadyPriority的bit0为1,则表示存在优先级为0的就绪任务,bit10为1则表示存在优先级为10的就绪任务。由于32位整形数最多只有32位,因此使用这种特殊方法限定最大可用优先级数目为32,即优先级0~31。       我们这来看看__clz( (uxTopReadyPriority)是什么意思,__clz()会被汇编指令CLZ替换掉,这个指令用来计算一个变量从最高位开始的连续零的个数。举个例子,假如变量uxTopReadyPriority为0x09(二进制为:0000 0000 0000 0000 0000 0000 0000 1001),即bit3和bit0为1,表示存在优先级为0和3的就绪任务。则__clz( (uxTopReadyPriority)的值为28,uxTopPriority =31-28=3,即优先级为3的任务是就绪态最高优先级任务。下面的代码跟通用方法一样,调用宏listGET_OWNER_OF_NEXT_ENTRY获取最高优先级列表中的下一个列表项,并从该列表项中获取任务TCB指针赋给变量pxCurrentTCB。 mov r0, #0                   /* 退出临界区*/ msr basepri, r0       这两句代码用来退出临界区,通过向寄存器BASEPRI写入数值0来实现。 ldmia sp!, {r3, r14}      这句代码将寄存器R3和R14从堆栈中恢复,现在R3保存变量pxCurrentTCB的地址,需要注意的是,变量pxCurrentTCB在函数vTaskSwitchContext中可能已被修改,指向新的最高优先级就绪任务;R14保存退出异常需要的信息。 ldr r1, [r3] ldr r0, [r1]              这两句代码获取变量pxCurrentTCB指向的任务TCB指针,并将TCB的第一个成员——当前堆栈栈顶的指针变量pxTopOfStack的值保存到寄存器R0中,也就是将即将运行的任务堆栈栈顶值存入R0。 ldmia r0!, {r4-r11}      将寄存器R4~R11出栈,并同时更新R0的值。 msr psp, r0      将最新的任务堆栈栈顶赋值给线程堆栈指针PSP。bx r14       从异常中断服务程序退出。异常发生时,R14中保存异常返回标志,包括返回后进入线程模式还是处理器模式、使用PSP堆栈指针还是MSP堆栈指针。当调用 bx r14指令后,硬件会知道要从异常返回,然后出栈,这个时候堆栈指针PSP已经指向了新任务堆栈的正确位置,当新任务的运行地址被出栈到PC寄存器后,新的任务也会被执行。       至此,任务切换完成。

赞0
22 回答

谁知道keil .c 和.h 文件的大概的编译过程,我们都知道...

未设置标签
ho ho 回答时间: 2018-8-19 10:12

wwwheihei 发表于 2018-8-17 11:16 编译打印不是你说的这样 .s文件就是BootLoader,汇编文件中里面会有一句话指向main()。

赞0
9 回答

stm32f030 iap中配置ram起始地址为ox200000c0是怎么算出来的?

未设置标签
feixiang20 feixiang20 回答时间: 2018-8-15 23:21

这个主要看你的官方资料的限定,不用那么纠结

赞0
22 回答

我想实现串口1和串口2数据转发功能,有没有相关的方案或...

未设置标签
x5y4z3 x5y4z3 回答时间: 2018-8-16 09:19

wwwheihei 发表于 2018-8-15 09:45 您倒是启发到我了,谢谢 没事的,将需求更详细描述,如此大家才好能理解您的虚情并给予些许帮助。 多学多交流,也是一般普遍的认知。有心得后别忘记要来与大家同分享啊!

赞0
23 回答

现在想做一个后台实时监控视频的功能,好像单片机无法...

未设置标签
Dandjinh Dandjinh 回答时间: 2018-8-27 12:54

你先把你的需求说一下,例如摄像头的分辨率,颜色位深,fps等,这样才好告诉你可行性。

赞0
11 回答

求一个mma8653驱动程序

未设置标签
ssssss ssssss 回答时间: 2018-8-8 13:40

freeelectron 发表于 2018-8-8 11:49 嗯,我到时候写个帖子吧 记得把链接放在本帖

赞0
13 回答

求逻辑分析仪采集的stm32硬件iic的时序图

未设置标签
废鱼 废鱼 回答时间: 2018-8-7 09:47

wwwheihei 发表于 2018-8-7 09:43 是不是主要是输入电压和采样频率上不一样,二十几块的好像只有24m的采样频率 ... 楼主可以网上搜一下,对比一下参数。

赞0
20 回答

keil有没有这种很高端的功能?

未设置标签
andey andey 回答时间: 2018-8-27 09:07

jiekechoo 发表于 2018-8-25 17:31 这个也是eclipse变种而已。 恩 风格还是很一致的

赞0
4 回答

在调试stm32f030c8t6的停止模式

未设置标签
ssssss ssssss 回答时间: 2018-9-7 10:33

TP416775364 发表于 2018-9-7 09:40 请问如何解决的,有参考码可以发下么? PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);就这一句

赞0
7 回答

stm32f0待机模式用rtc闹钟唤醒问题,急

未设置标签
大_树 大_树 回答时间: 2018-8-3 19:46

谢谢分享

赞0
20 回答

求助,如何在官网下载所需得资料

未设置标签
ssssss ssssss 回答时间: 2018-7-26 17:55

す疯Ⅱ恒す 发表于 2018-7-26 17:52 专门找RTC的代码在网站上是看不到的,你只能把标准固件库下载下来再找。网站上这里就几页,翻翻就找到了 ... 原来如此,我一直纠结这个,原来在固件库里面

赞0
14 回答

对于keil target界面的设置,一直以来都没有真正弄懂过!

未设置标签
生逝如花草 生逝如花草 回答时间: 2023-2-3 13:10

豁然开朗,学习了

赞0
14 回答

关于stm32keil编译器优化

未设置标签
ssssss ssssss 回答时间: 2018-7-16 08:26

MrJiu 发表于 2018-7-14 10:05 如果你能够保证分时复用,可以到处用,否则就搞单独。。。免得麻烦!!! ... 有没有什么地方可以看出优化了哪些地方?

赞0
1 回答

stm32f030做iap功能,跳转到app需要一分钟时间

未设置标签
ssssss ssssss 回答时间: 2018-7-11 15:20

已经解决,发现时间是我串口打印的时间间隔,不是很准确,把打印靠前放,秒进

赞0
ssssss ssssss


阅读作者更多的帖子

所在话题

参与活动

  • 滴滴押注社区团购,明确“投入不设上限,要做市场第一”

    线下 2020-10-16
  • 滴滴押注社区团购,明确“投入不设上限,要做市场第一”

    网络 2020-10-16
  • 滴滴押注社区团购,明确“投入不设上限,要做市场第一”

    网络 2020-10-16
  • 滴滴押注社区团购,明确“投入不设上限,要做市场第一”

    网络 2020-10-16
  • 滴滴押注社区团购,明确“投入不设上限,要做市场第一”

    线下 2020-10-16
  • 滴滴押注社区团购,明确“投入不设上限,要做市场第一”

    线下 2020-10-16