OK,继续向操作系统迈进。由简入繁,先实现两个小功能。第一个是system tick,第二个是任务切换(PendSV)。一个是操作系统的心跳,一个是操作系统的并发处理的具体实现

System tick,在裸机程序里面,这个功能一直是用来做延时功能用的,用STM32做项目,基本都会用到。这里不准备再从头去实现这个功能,而是直接用ST官方的库文件。库文件版本为3.5.0。

主要用到两个函数,第一个为

static __INLINE uint32_t SysTick_Config(uint32_t ticks)

{

if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */

SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */

NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */

SysTick->VAL = 0; /* Load the SysTick Counter Value */

SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |

SysTick_CTRL_TICKINT_Msk |

SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */

return (0); /* Function successful */

}

下面来解读一下这个函数。

1,从函数的注释可以了解到,参数ticks就是Systick的重装值。成功返回1,失败返回0。

* @param ticks number of ticks between two interrupts

* @return 1 = failed, 0 = successful

2,第一句if (ticks > SysTick_LOAD_RELOAD_Msk) return (1);这一句的意思是若是重装值大于重装值的上限,那么就返回失败。Reload 是一个24bit的寄存器,所以最大值不能大于2^24。

3,设定重装值。

SysTick的结构体原型如下:

typedef struct

{

__IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register */

__IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */

__IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */

__I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register */

} SysTick_Type;

将SysTick_Type的地址指向0xE000E010,那么结构体中的四个成员的偏移地址刚好对应下图的四个表所指寄存器的地址。

4,设定中断优先级。

5,将当前计数的值清零。

6,使能SysTick和中断。

这个函数在core_cm3.h文件里面。

另外一个函数在misc.c里面,

void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)

{

/* Check the parameters */

assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));

if (SysTick_CLKSource == SysTick_CLKSource_HCLK)

{

SysTick->CTRL |= SysTick_CLKSource_HCLK;

}

else

{

SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;

}

}

用来指定时钟源是HCLK还是HCLK 8分频。在不调用该函数的情况下,默认为时钟源为HCLK。

有了这两个函数,再加上中断函数SysTick_Handler,我们就可以使用SysTick了,下面用一段LED闪烁的代码来测试一下。

第一步:建立一个新文件夹。

第二步:建立工程,添加启动代码,并将如下文件添加至工程。

项目视图:

文件夹视图:

Config中的头文件列表只保留

#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */

系统时钟选择

#define SYSCLK_FREQ_72MHz 72000000

Main文件中测试代码如下:

#include "stm32f10x_conf.h"

#define LED0 *((volatile unsigned long *)(0x422101a0)) //PA8 out

unsigned char flag=0;

void LEDInit(void)

{

RCC->APB2ENR|=1<<2;

GPIOA->CRH&=0XFFFFFFF0;

GPIOA->CRH|=0X00000003;

}

int main(void)

{

SysTick_Config(9000000);

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//72/8=9MHZ

LEDInit();

while(1);

}

void SysTick_Handler(void)

{

flag=~flag;

LED0=flag;

}

第三步:仿真测试。

测试的波形如下:

可以看到,刚好1秒闪烁一次。下载到开发板上测试也OK。

OK,System tick 算是搞定,接下来就是任务切换了。

进入OS前的两步之System tick的更多相关文章

  1. 进入OS前的两步之PendSV(任务切换)

    先了解下如何使用PendSV异常.(为何要使用PendSV而不是其他的异常,请参考<cortex-M3权威指南>) 1,如何设定PendSV优先级? NVIC_SYSPRI14 EQU 0 ...

  2. 你知道怎么使用Google两步验证保护账户安全吗?

    目录 为什么我们需要使用它? 对有些人来说,盗取密码比您想象的更简单 什么是Google两步验证? 多一道安全防线 什么是Google Authenticator ? 使用Google两步验证的好处 ...

  3. 挑子学习笔记:两步聚类算法(TwoStep Cluster Algorithm)——改进的BIRCH算法

    转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/twostep_cluster_algorithm.html 两步聚类算法是在SPSS Modeler中使用的 ...

  4. 两步验证杀手锏:Java 接入 Google 身份验证器实战

    两步验证 大家应该对两步验证都熟悉吧?如苹果有自带的两步验证策略,防止用户账号密码被盗而锁定手机进行敲诈,这种例子屡见不鲜,所以苹果都建议大家开启两步验证的. Google 的身份验证器一般也是用于登 ...

  5. U3D教程宝典之两步实现超实用的XML存档

    两步实现超实用的XML存档 本套存档的优点:易使用,跨平台,防作弊(内容加密 + 防拷贝) 脚本下载地址 使用方法非常简单:把GameDataManager和XmlSaver两个脚本添加至工程后(1) ...

  6. 每次Xcode 升级之后 插件失效,两步解决

    以下内容来源:http://www.cocoachina.com/bbs/read.php?tid=296269 每次Xcode 升级之后 插件失效,两步解决 1.打开终端,输入以下代码获取到DVTP ...

  7. 两步验证Authy时间同步问题

    Authy是我常用的软件之一,通常用于Google的两步验证,或者是其他基于Google两步验证的原理的衍生程序.比如Namesilo.印象笔记等均有使用. 先说说什么是两步验证. 两步验证 两步验证 ...

  8. Github两步认证

    获取密钥:ssh-keygen -t rsa  切换到公钥所在路径:cd .ssh 查看该路径下的所有文件:ls 查看公钥:cat id_rsa.pub 获取密钥之后,去https://github. ...

  9. Google 推出全新的两步验证机制

    近日 Google 在官方的 Apps Updates 博客公布了全新的两步验证功能--Google 提示,新的功能通过与 Google App 联动,进一步将验证确认工作缩减到仅有两步,同时支持 A ...

随机推荐

  1. android break 与 return 的区别

    break 的含义是中断,return 的含义是结束整个方法的执行. 区别. public static void main(String agrs[]){ int i; for(i=0;i<1 ...

  2. centos 6.x安装rvm 配置 Ruby开发环境

    rvm是ruby的版本管理工具  还可对ruby进行 安装 卸载 等 1.安装 curl #  sudo yum install  curl #  curl -L  get.rvm.io | bash ...

  3. 关于ScheduledExecutorService执行一段时间之后就不执行的问题

    在项目中使用java的定时任务时,有的时候执行一段时间后没任何反应了.这里有篇文章说了这个问题.猛击下面的链接. http://blog.163.com/scuqifuguang@126/blog/s ...

  4. shell中export理解误区

    一直以来,以为shell脚本中经过export后的变量会影响到执行这个shell的终端中的环境变量.环境变量这个概念不是shell所独有的,而是linux里面进程所拥有的,shell解释器运行起来就是 ...

  5. 报表软件FineReport如何连接SAP HANA

    1. 环境搭建 1.1 环境准备 首先确认HANA Studio的环境是否允许工程进行NewFile的操作,不行的话要考虑更新Studio的版本. HANAStudio需要依赖Java jdk1.6或 ...

  6. 【原】移动web页面兼容处理的思考

    本月收到一份关爱里程碑的邮件,入职满3周年了,从一个懵懂的新人到从容淡定的小油条,在外辛苦打工不容易,能收到一封简单的关怀邮件也是有感欣慰,这里祝愿公司越发展越好. 进入主题,移动网页设计中,很多同学 ...

  7. 第39课 Qt中的事件处理(下)

    1. 事件的传递过程 (1)操作系统检测到用户动作时,会产生一条系统消息,该消息被发送到Qt应用程序 (2)Qt应用程序收到系统消息后,将其转化为一个对应的QEvent事件对象,并调用QObject: ...

  8. IEnumerable,IQueryable之前世今生

    来自于:http://www.cnblogs.com/chengxiaohui/articles/2088967.html IEnumerable<T>在.Net2.0中我们已经很熟悉了. ...

  9. C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 增加安全性增加内网的电脑才可以调用的限制

    大型业务应用系统很容易受到各种攻击,每加上一道防护就可以减少80%-90%的攻击.我们的核心接口组件里也做了一些限制,有些接口方法只有内网的用户才可以调用,防止外网的用户调用,这样安全性会有很大的提升 ...

  10. c语言考前最后一天

    明天就是考验这1个多月学习c语言的总结了,所以今天是个重要的日子,明天是个神圣的日子. 但是我还很多地方不明白,特别是函数,循环,这两个都是c语言最重要的,但我却没学好,上课还 时不时走神所以现在学的 ...