
开放原子训练营(第四季)TobuOS——线下培训项目添加按钮检测逻辑
参加了 开放原子训练营后写的作业,希望能获得开发板继续学习 ,感谢!
·
开放原子训练营(第四季)活动介绍
此次训练营由开放原子开源基金会与TobudOS团队联合举办,主要是为广大开发者提供一个交流嵌入式、物联网操作系统等相关技术和应用的平台,推动IoT领域的人才交流和培养。
经过此次的活动,我也成功接入腾讯云,制作了一个简易的嵌入式物联网的小项目。
在线下操作感受
起始一开始在准备环境的时候花费了一些时间,然后成功跑通了TobudOS,但是在移植IOT工程的时候出现了点问题,后面跟着大佬的解答,修改了IO口配置即可。连上腾讯云的感觉不是很复杂,这也是基于工程原有的mqtt去完成的,后面值得去看一下实现的代码,总的来说现场的大佬还是很给力的,分析问题很专业。
内容
结束线下培训后添加按钮检测
主要逻辑如上所示,红色框框为需要添加的逻辑
需要熟悉的API
任务的创建
k_err_t tos_task_create(k_task_t *task,
char *name,
k_task_entry_t entry,
void *arg,
k_prio_t prio,
k_stack_t *stk_base,
size_t stk_size,
k_timeslice_t timeslice);
参数 | 功能 |
---|---|
task | 任务结构体描述符 |
name | 任务名称 |
entry | 任务入口函数 |
arg | 任务入口函数参数 |
prio | 任务优先级 |
stk_base | 任务栈空间首地址 |
stk_size | 任务栈空间的大小 |
timeslice | 时间片轮转调度侧策略中,时间片的大小设置,0 表示设置为系统默认值 |
消息队列相关
创建
k_err_t tos_msg_q_create_dyn(k_msg_q_t *msg_q, size_t msg_cnt);
参数 | 功能 |
---|---|
msg_q | 消息队列句柄 |
msg_cnt | 消息队列的最大消息数 |
写操作
k_err_t tos_msg_q_post(k_msg_q_t *msg_q, void *msg_ptr);
参数 | 功能 |
---|---|
msg_q | 消息队列句柄 |
msg_ptr | 消息地址 |
拿操作
k_err_t tos_msg_q_pend(k_msg_q_t *msg_q, void **msg_ptr, k_tick_t timeout);
参数 | 功能 |
---|---|
msg_q | 消息队列句柄 |
msg_ptr | 获取到的消息地址 |
timeout | 等待超时参数 |
具体细节
检测按钮任务
k_task_t task1;//任务句柄
k_stack_t task_stack1[1024];//创建栈空间
k_msg_q_t task1_msg_q;//队列句柄
void test_task1(void *Parameter)
{
unsigned int flag = 0;//状态
k_err_t err = tos_msg_q_create_dyn(&task1_msg_q, 10);//创建队列
if(err != K_ERR_NONE)
printf("TencentOS Create task1_msg_q fail! code : %d \r\n",err);
while(1)
{
#if 1
//检测按钮按下
if((HAL_GPIO_ReadPin( GPIOJ, KEY1_Pin) == GPIO_PIN_RESET) && flag == 0)
{
flag = 1;
err = tos_msg_q_post(&task1_msg_q, (void *)(&flag));
if (err != K_ERR_NONE)
printf("msg queue put fail! code : %d \r\n",err);
else
printf("msg queue put ok! value : %d \r\n",flag);
//发送事件 或者用全局变量
}
else if((HAL_GPIO_ReadPin( GPIOJ, KEY1_Pin) == GPIO_PIN_SET) && flag == 1)
{
flag = 0;
err = tos_msg_q_post(&task1_msg_q, (void *)(&flag));
if (err != K_ERR_NONE)
printf("msg queue put fail! code : %d \r\n",err);
else
printf("msg queue put ok! value : %d \r\n",flag);
//发送事件 或者全局变量
}
#else //测试代码
flag = flag ? 0 : 1;
err = tos_msg_q_post(&task1_msg_q, (void *)(&flag));
if (err != K_ERR_NONE)
printf("msg queue put fail! code : %d \r\n",err);
else
printf("msg queue put ok! value : %d \r\n",flag);
#endif
}
}
上传数据任务逻辑
我这边只添加我新的逻辑,原本的函数我就没添加出来了
void *p ;//获取数据
//创建任务
k_err_t err = tos_task_create(&task1,
"task1",
test_task1,
NULL, //任务参数
3,
task_stack1,
1024,
20);//时间片的大小设置
if(err != K_ERR_NONE)
printf("TencentOS Create task1 fail! code : %d \r\n",err);
while(1)
{
err = tos_msg_q_pend(&task1_msg_q, (&p), 0);
if(err == K_ERR_NONE)
{
//测试上传key数据
memset(&msg, 0, sizeof(msg));
memset(report_buf, 0, sizeof(report_buf));
snprintf(report_buf, sizeof(report_buf), KEY_STATUSE_DATA_TEMPLATE, *(unsigned int *)p);
msg.qos = QOS0;
msg.payload = (void *)report_buf;
error = mqtt_publish(client, MQTT_PUBLISH_TOPIC_UP, &msg);
MQTT_LOG_D("mqtt publish error is %#0x", error);
tos_event_pend(&report_result_event,
report_success | report_fail,
&match_flag,
TOS_TIME_FOREVER,
TOS_OPT_EVENT_PEND_ANY | TOS_OPT_EVENT_PEND_CLR);
if (match_flag == report_success) {
printf("report to Tencent IoT Explorer success\r\n");
} else if (match_flag == report_fail) {
printf("report to Tencent IoT Explorer fail\r\n");
}
printf("msg queue get ok! value : %d \r\n",*(unsigned int *)p);
}
else
{
printf("msg queue get fail! code : %d \r\n",err);
}
}
这里注意的是 KEY_STATUSE_DATA_TEMPLATE 宏 我是仿照灯控制逻辑的,我这里没贴出来
需要添加的服务器json解析
json
{
"id": "KEY",
"name": "检测逻辑",
"desc": "检测物体靠近",
"required": true,
"mode": "r",
"define": {
"type": "bool",
"mapping": {
"0": "关",
"1": "开"
}
上述代码的AtomGit地址
https://atomgit.com/he_jianbo/learning_library
总结调试中的bug
- 当需要调试查看log时需要将串口引脚拨码拨到MCU端
- 用例程序中的IO口配置错误,需要修改成原理图标识的
心得
由于时间问题我就在线上的工程上单纯的添加了这个按钮检测,后面可以再添加一个按钮计数功能,主要的还是json解析的格式和上传字符串的修改,具体mqtt的通信逻辑需要后面学习,这块还是比较重要的,希望后面再接再厉!加油吧。跟随开放原子社区的大佬脚步学习。

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)