参考学习大神博客: http://blog.csdn.net/feilusia/article/details/51083953

        : http://blog.csdn.net/xiaoleiacmer/article/details/41723583

1、TI 的 CC2540跑了一个  OSAL   (Operating System Abstraction Layer)

    心得:大概 就是 一个循环查看任务 是否 产生事件,产生就 处理事件,每个任务有16个事件,其实就是一个16位的宏定义,每一位代表一个事件,其中0x8000 是固定 的代表 SYS_EVENT_MSG。(这句话看不懂,可以往下看)

    (sdk的安装请百度,工程路径:C:\Texas Instruments\BLE-CC254x-1.4.1.43908\Projects\ble\SimpleBLEObserver\CC2540DB)

2、在 TI 提供 的 SDK  中 ,打开 一个 观察者工程,找到任务初始化的地方。(可通过 菜单->Edit->Find and Replace->Find in Files 这个全局查找 功能 进行找到这个函数osalInitTasks)

    这里 有很多任务 的初始化 ,按顺序执行,每个任务 有一个 对应 一个 事件处理函数(任务产任务生事件,就去执行这个事件处理函数),这句话很重要哦,一定要理解,记住。

 任务列表:

任务对应的 事件处理 函数 :如下

3、前面的任务 都不管 ,现在我 们值关心 最后一个任务(因为这个任务 是  应用任务 ,TI 就是做这个任务 就是供我们使用的。)

/* Application */
SimpleBLEObserver_Init( taskID );

对应 的事件处理函数是:

SimpleBLEObserver_ProcessEvent( uint8 task_id, uint16 events );

4、先看看这个任务SimpleBLEObserver_Init的初始化都做了什么。

5、看看这个任务的 事件处理函数SimpleBLEObserver_ProcessEvent 都 做了什么。

6、我们要在这个应用任务中添加一个事件(定时处理某些事情,比如LED灯 比如定时检测传感器数据等等)做法如下。

    第一步:在这个任务中,添加一个事件,名称叫:(其实就是添加一个宏定义)

    (因为事件 的变量(16位) 每一位代表一个事件,因此事件的可能值 只能是2^16,2^15,2^14,2^13,2^12,2^11,2048,1024,512,256, 128,64,32,16,8,4,2,1)

    #define SBO_PERIODIC_EVT                                  0x0004//至于为啥是 0x0004 而不是0x0002 因为0x0002 已经存在了

    添加结果如下:

    

    第二步:在事件处理函数中,添加这个事件的处理:结果如下。

    

    

具体的 处理函数 如下:

/*********************************************************************
* @fn performPeriodicTask 执行 周期 任务
*
* @brief 输出一个任务正在执行的语句。
*
* 2017年4月17日13:57:35,GXP
*
* @param none
*
* @return none
*/
static void performPeriodicTask( void )
{
printf("定时器任务正在运行。\r\n");
}

事件添加好了:怎么启动这个事件 ,或者意思 是说怎么让系统执行这个事件那。下面就讲两种方法:(我也就会这两种目前,2017年4月17日20:24:25)

第一种方法:

  把这个事件设置为就绪状态,这样下次轮询任务时就会看这个应用任务 产生了一个 事件,具体调用的API 是

  
  osal_set_event( task_id, SBO_PERIODIC_EVT);//第一个 参数是任务ID ,第二个参数是事件名称。

  

因为我们这个事件 就是定时处理某些事情,因此要使用到系统的软件定时器,第二个办法就是使用系统软件定时来启动这个事件。

// Set timer for first periodic event
osal_start_timerEx( task_id, SBO_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );

  

下面 我 们 要 打开  CC2540 的 串口 ,进行收发数据: 参考博客:  http://blog.csdn.net/feilusia/article/details/47431659

    1、第一步  在 工程 的 属性 里 ,添加  HAL_UART=TRUE,进行 使能 串口

      

    2、添加头文件(npi.c中), #include "OSAL.h"

      

     3、新增两个串口发送函数(npi.c中)

       

/*********************************************************************
* @fn NPI_PrintString
*
* @brief 打印字符串
*
* 2017年4月20日16:22:27,GXP
*
* @param str:字符串
*
* @return none
*/ void NPI_PrintString(uint8 *str)
{
NPI_WriteTransport(str, osal_strlen((char*)str));
} /*********************************************************************
* @fn NPI_PrintValue 打印指定的格式的数值
*
* @brief 打印指定的格式的数值
*
* 2017年4月20日16:22:27,GXP
*
* @param title:前缀字符串
* value:需要显示的数值
* format:需要显示的进制,10或16
*
* @return none
*/ void NPI_PrintValue(char *title, uint16 value, uint8 format)
{
uint8 tmpLen;
uint8 buf[];
uint32 err; tmpLen = (uint8)osal_strlen( (char*)title );
osal_memcpy( buf, title, tmpLen );
buf[tmpLen] = ' ';
err = (uint32)(value);
_ltoa( err, &buf[tmpLen+], format );
NPI_PrintString(buf);
}

     4、函数声明(npi.h中) 

extern void NPI_PrintValue(char *title, uint16 value, uint8 format);
extern void NPI_PrintString(uint8 *str);

     5、关闭低功耗模式,顺便关掉 LCD,2017年4月20日16:39:44

      

     6、因为要在simpleBLEObserver.c中调用 上面添加 的 两个串口打印函数,因此 需要 在 simpleBLEObserver.c中 添加#include "npi.h"

#include "npi.h" //SuoZhang,ADD,2017年4月20日16:42:58

     7、定义并声明一个串口回调函数,在 simpleBLEObserver.c中,这个回调函数什么时候进入那?

答:

1)正常串口端无发送、无接收时,是不会进回调函数的。如果这种情况会进回调函数,TX、RX端外接上拉电阻稳定电平。

2)如果接收端有数据,立马就会进回调。事件是“接收超时事件”。

3)2541 or 2540 发送端发送完数据,会进回调函数。事件是“发送缓冲区空事件”。

/*********************************************************************
* @fn NPI_SerialCallback
*
* @brief 串口回调函数,2016年12月15日08:59:13,GXP
*
* 1、如果接收端有数据,立马就会进回调。事件是“接收超时事件”。
* 2、2541 or 2540 发送端发送完数据,会进回调函数。事件是“发送缓冲区空事件”。
*
* @param port: 串口1 还是串口2
* events: 事件类型(“接收超时事件”,“发送缓冲区空事件”)
*
* @return none
*/
static void NPI_SerialCallback( uint8 port, uint8 events )
{
(void)port;//加个 (void),是未了避免编译告警,明确告诉缓冲区不用理会这个变量 if (events & (HAL_UART_RX_TIMEOUT | HAL_UART_RX_FULL)) //串口有数据
{
uint8 numBytes = ; numBytes = NPI_RxBufLen(); //读出串口缓冲区有多少字节 if(numBytes == )
{
return;
}
else
{
//申请缓冲区buffer
uint8 *buffer = osal_mem_alloc(numBytes);
if(buffer)
{
//读取读取串口缓冲区数据,释放串口数据
NPI_ReadTransport(buffer,numBytes); //把收到的数据发送到串口-实现回环
NPI_WriteTransport(buffer, numBytes); //释放申请的缓冲区
osal_mem_free(buffer);
}
}
}
}

    8、添加上面 串口回调函数的声明,simpleBLEObserver.c中

static void NPI_SerialCallback( uint8 port, uint8 events );//SuoZhang,ADD,2017年4月20日16:55:25

    9、新增初始化代码simpleBLEObserver.c的SimpleBLEObserver_Init中

/*********************************************************************
* @fn SimpleBLEObserver_Init
*
* @brief Initialization function for the Simple BLE Observer App Task.
* This is called during initialization and should contain
* any application specific initialization (ie. hardware
* initialization/setup, table initialization, power up
* notification).
*
* @param task_id - the ID assigned by OSAL. This ID should be
* used to send messages and set timers.
*
* @return none
*/
void SimpleBLEObserver_Init( uint8 task_id )
{
simpleBLETaskId = task_id; //初始化串口0,作为串口打印数据使用,2017年4月20日16:57:31
{
//注册串口回调函数
NPI_InitTransport(NPI_SerialCallback); // 按长度输出测试
//NPI_WriteTransport("SimpleBLETest_Init\r\n", 20); // 按字符串输出
NPI_PrintString("SimpleBLEObserver_Init.\r\n"); // 可以输出一个值,用10进制表示
NPI_PrintValue("测试10进制输出 = ", , );
NPI_PrintString("\r\n"); // 可以输出一个值,用16进制表示
NPI_PrintValue("测试16进制输出 = 0x", 0x88, );
NPI_PrintString("\r\n");
} // Setup Observer Profile
{
uint8 scanRes = DEFAULT_MAX_SCAN_RES;
GAPObserverRole_SetParameter ( GAPOBSERVERROLE_MAX_SCAN_RES, sizeof( uint8 ), &scanRes );
} // Setup GAP
GAP_SetParamValue( TGAP_GEN_DISC_SCAN, DEFAULT_SCAN_DURATION );
GAP_SetParamValue( TGAP_LIM_DISC_SCAN, DEFAULT_SCAN_DURATION ); // Register for all key events - This app will handle all key events
RegisterForKeys( simpleBLETaskId ); // makes sure LEDs are off
HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF ); // Setup a delayed profile startup
osal_set_event( simpleBLETaskId, START_DEVICE_EVT );
}

    10、关闭流控(流控是用于防止串口阻塞的,需要多两根线用于流控。),通常串口只使用三根线 TX,RX,GND, (npi.h中)

#if !defined( NPI_UART_FC )
#define NPI_UART_FC FALSE //TRUE
#endif // !NPI_UART_FC

    11、编译并且接上串口0,波特率115200,结果如下:(不清楚问什么 汉子乱码)

CC2540 OSAL 学习其中原理,以及 给任务 添加 一个事件(定时发送串口消息)的更多相关文章

  1. Qt 学习之路 2(19):事件的接受与忽略

    Home / Qt 学习之路 2 / Qt 学习之路 2(19):事件的接受与忽略 Qt 学习之路 2(19):事件的接受与忽略  豆子  2012年9月29日  Qt 学习之路 2  140条评论 ...

  2. Qt 学习之路 2(19):事件的接受与忽略(当重写事件回调函数时,时刻注意是否需要通过调用父类的同名函数来确保原有实现仍能进行!有好几个例子。为什么要这么做?而不是自己去手动调用这两个函数呢?因为我们无法确认父类中的这个处理函数有没有额外的操作)

    版本: 2012-09-29 2013-04-23 更新有关accept()和ignore()函数的相关内容. 2013-12-02 增加有关accept()和ignore()函数的示例. 上一章我们 ...

  3. 读Flask源代码学习Python--config原理

    读Flask源代码学习Python--config原理 个人学习笔记,水平有限.如果理解错误的地方,请大家指出来,谢谢!第一次写文章,发现好累--!. 起因   莫名其妙在第一份工作中使用了从来没有接 ...

  4. elasticsearch学习笔记--原理介绍

    前言:上一篇中我们对ES有了一个比较大概的概念,知道它是什么,干什么用的,今天给大家主要讲一下他的工作原理 介绍:ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户 ...

  5. 深入浅出深度学习:原理剖析与python实践_黄安埠(著) pdf

    深入浅出深度学习:原理剖析与python实践 目录: 第1 部分 概要 1 1 绪论 2 1.1 人工智能.机器学习与深度学习的关系 3 1.1.1 人工智能——机器推理 4 1.1.2 机器学习—— ...

  6. 深入学习Composer原理(二)

    本系列的第二篇文章,这次我们聊聊:spl_autoload_register()函数 PHP的SPL库作为扩展库,已经于5.3.0版本后默认保持开启,成为PHP的一组强大的核心扩展库.大家有时间可以多 ...

  7. 深入学习Composer原理(四)

    本系列第四篇文章,也是最后一篇 首先,我们先看看Composer的源码从哪里看起.当然,请您先准备好源码. composer init或者直接install之后,自动生成了一个vendor目录,这时您 ...

  8. 深入学习Composer原理(三)

    本系列第三篇文章,一起了解下PSR规范中的PSR4和PSR0规范 首先恭喜大家,包括我自己,坚持到了现在.这篇文章之后,Composer的基础原理就清晰明了咯.也就是说,Composer所利用的正是s ...

  9. 学习JVM-GC原理

    1. 前言 Java和C++之间显著的一个区别就是对内存的管理.和C++把内存管理的权利赋予给开发人员的方式不同,Java拥有一套自动的内存回收系统(Garbage Collection,GC)简称G ...

随机推荐

  1. OpenCV获取与设置像素点的值的几个方法

    Title: OpenCV OpenCV像素值的获取与设置 Fn 1 : 使用 Mat 中对矩阵元素的地址定位的知识 (参考博文:OpenCV中对Mat里面depth,dims,channels,st ...

  2. MySQL事务管理

    事务就是一组原子性的SQL查询,或者说一个独立的工作单元.如果数据库引擎能够成功地对数据库应用该组查询的全部语句,那么就执行该组的全部语句,如果其中有任何一条语句因为崩溃或者其他原因无法执行,那么所有 ...

  3. SQL点点滴滴_判断字段或者字符中是否包含有特殊字符

    SQL Server中,如果我们想判断一个字符串或者数据字段中是否包含有特殊字符.可以使用正则来实现.除了大小字母和数字之外全是特殊字符[^a-zA-Z0-9]

  4. html5\CSS3有哪些新特性、移除了哪些元素?如何处理HTML5新标签的浏览器兼容问题?如何区分HTML和HTML5?

    (1)HTML5现在已经不是SGML的子集,主要是关于图像,位置,存储,地理定位等功能的增加. 绘画canvas元素: 用于媒介回放的video和audio元素: 本地离线存储localStorage ...

  5. Python实例---游戏人生[类的学习]

    # -*- coding:utf-8 -*- # ##################### 定义实现功能的类 ##################### class Person: def __in ...

  6. 运维监控---企业级Zabbix详解_【all】

    基础LNMP环境搭建 Linux 下LNMP环境搭建 下载Zabbix 链接:https://pan.baidu.com/s/1n36esVyYAKstwnFopbV2sg 密码:izll 创建zab ...

  7. 1、Docker 架构详解

    本文来自clouldman ,有增删. Docker 的核心组件包括: Docker 客户端 - Client Docker 服务器 - Docker daemon Docker 镜像 - Image ...

  8. December 24th 2016 Week 52nd Saturday

    The first step is as good as half over. 第一步是最关键的一步. If one goes wrong at the first steps, what shoul ...

  9. Python2.7 - IMOOC - 1

    第一章 课程介绍 python 特点:优雅.明确.简单 python适合的领域:1.Web网站和各种网络服务:2.系统工具和脚本:3.作为"胶水"语言把其他语言开发的模块包装起来方 ...

  10. Salesforce平台支持多租户Multi tenant的核心设计思路

    Multitenancy is the fundamental technology that clouds use to share IT resources cost-efficiently an ...