大学生
最后登录1970-1-1
在线时间 小时
注册时间2017-3-12
|
原帖地址:https://blog.csdn.net/sinat_27066063/article/details/86567125
硬件环境:秉火STM32F103
官方例程:Huawei LiteOS + (NB-IoT / WIFI / 2G ) + OceanConnect平台的端云Demo
基础例程:https://download.csdn.net/download/sinat_27066063/10809185
之前移植好的可以在stm32f103运行的Huawei_LiteOS,OS移植过程可参考Huawei_LiteOS——STM32F103移植
移植代码分享:稍后审核通过给出。
0.备注- Wifi模块使用esp8266
- 基础例程中断接管方式为系统接管:
​
1.添加文件第一步
复制官方例程..\Huawei_LiteOS_DemoSDK_v10\components文件夹(全部文件)替换到基础例程中的文件夹..\User\components(官方例程中有些文件改动较大,有些额外添加的文件)。
需要添加到工程中的文件目录如下,目录下所有的源文件都需要添加至工程中:
mbedtls接口:..\User\components\security\mbedtls\mbedtls_port
mbedtls源码:..\User\components\security\mbedtls\mbedtls-2.6.0\library
coap文件:..\User\components\connectivity\lwm2m\core\er-coap-13
lwm2m文件:..\User\components\connectivity\lwm2m\core
atiny适配文件:..\User\components\connectivity\agent_tiny\osadapter
agent_tiny文件:..\User\components\connectivity\agent_tiny\lwm2m_client
agent_demo文件:..\User\components\connectivity\agent_tiny\examples
at适配文件:..\User\components\connectivity\at_frame
第二步
复制官方例程..\Huawei_LiteOS_DemoSDK_v10\drivers\devices\wifi文件夹(里面有esp8266的驱动)粘贴到基础例程..\User\bsp文件夹下。
复制官方例程..\Huawei_LiteOS_DemoSDK_v10\targets\NB-IoT_STM32L431RxTx_IoTClub\Src\dwt.c文件和..\Huawei_LiteOS_DemoSDK_v10\targets\NB-IoT_STM32L431RxTx_IoTClub\Inc\dwt.h文件粘贴到基础例程..\User\bsp\dwt文件夹下。
将上面的源文件添加到工程中。
第三步
复制gpio和usart驱动文件至基础例程..\User\bsp文件夹下,并将源文件添加到工程中。
其根据系统的需要进行编写,gpio用于控制WiFi使能信号,usart.c与at_hal.c文件进行适配。
全部bsp文件下载地址:https://pan.baidu.com/s/1kz0H9U3thFOifTWyC-10sQ
提取码:8zrg
​
第四步
添加头文件路径:
..\Libraries\inc;..\User;..\User\bsp\dwt;..\User\bsp\gpio;..\User\bsp\led;..\User\bsp\usart;..\User\bsp\wifi;..\User\arch\arm\arm-m\include;..\User\components\cmsis;..\User\components\cmsis\1.0;..\User\components\cmsis\2.0;..\User\kernel\include;..\User\kernel\base\include;..\User\kernel\extended\include;..\User\OS_CONFIG;..\User\components\connectivity\lwm2m\core\er-coap-13;..\User\components\connectivity\lwm2m\core;..\User\components\connectivity\agent_tiny\comm\include;..\User\components\connectivity\agent_tiny\lwm2m_client;..\User\components\connectivity\agent_tiny\examples;..\User\components\connectivity\agent_tiny\osadapter;..\User\components\connectivity\at_frame;..\User\components\security\mbedtls\mbedtls_port;..\User\components\security\mbedtls\mbedtls-2.6.0\include\mbedtls;..\User\components\security\mbedtls\mbedtls-2.6.0\include
补充以下宏定义:USE_MBED_TLS,MBEDTLS_CONFIG_FILE=<los_mbedtls_config.h>,LWM2M_LITTLE_ENDIAN,LWM2M_CLIENT_MODE,NDEBUG,WITH_AT_FRAMEWORK,USE_ESP8266
​
2.修改错误在main.c中添加头文件:
#include "stdio.h"#include "stdlib.h"#include "string.h"#include "los_config.h"#include "los_base.h"#include "los_sys.h"#include "los_typedef.h"#include "los_hwi.h"#include "los_task.ph"#include "los_sem.h"#include "los_event.h"#include "los_memory.h"#include "los_queue.ph"#include "stm32f10x.h"#include "bsp_led.h"#include "bsp_usart.h"#include "dwt.h"#include "bsp_gpio.h"#include "agent_tiny_demo.h"#if defined WITH_AT_FRAMEWORK#include "at_api_interface.h"#endif
编译后会出现很多个错误,逐个更改。
- at_api_interface.h:#include "stm32l4xx_hal.h" 改为 #include "stm32f10x_conf.h"和#include <stdio.h>。
- atiny_adapter.c:#include "stm32f4xx.h"改为#include "stm32f10x.h";#include "stm32f4xx_hal_rng.h"注释掉。
- at_hal.h:#include "stm32l4xx_hal.h"改为"stm32f10x_conf.h"。
- dwt.h:"stm32l4xx.h"修改为 "stm32f10x.h"。
- at_hal.c:at框架与hal层的接口,需要大面积修改,包括修改思路是将原usart的设置替换成自己的库。代码在最后贴出。
- atiny_adapter.c:删除extern RNG_HandleTypeDef hrng; STM32F4有一个RNG随机数发生器的功能,在移植的时候为了方便,直接简单带过了哈哈哈,好像也没什么影响:int atiny_random(unsigned char* output, size_t len){ size_t i; uint32_t random_number; for (i = 0; i < len; i += sizeof(uint32_t)) { random_number = 0xffffffff; memcpy(output + i, &random_number, sizeof(uint32_t) > len - i ? len - i : sizeof(uint32_t)); } return 0;}
3.修改main.c重新改写main.c文件。
main.c文件中定义全局变量UINT32 g_TskHandle,供创建任务时使用。
main()函数如下,使用creat_main_task()函数创建了主任务,create_task1()函数创建了运行灯任务task1:
int main(void){ UINT32 uwRet = LOS_OK; HardWare_Init(); uwRet = LOS_KernelInit(); if (uwRet != LOS_OK) { return LOS_NOK; } uwRet = create_task1(); if (uwRet != LOS_OK) { return LOS_NOK; } uwRet = creat_main_task(); if (uwRet != LOS_OK) { return LOS_NOK; } LOS_Start();}
其中硬件初始化Hardware_Init()函数代码如下,包括dwt、LED、USART、GPIO:
VOID HardWare_Init(VOID){ /* Initialize all configured peripherals */ dwt_delay_init(SystemCoreClock); LED_Init(); USART1_Config(); GPIO_Config(); printf("Welcome to IoT-Club, This is STM32F103 Board.\r\n");}
creat_main_task()函数创建了main_task任务。main_task()函数先进行了AT框架初始化at_api_init()函数。at_api_init()函数分别对at frame和WiFi模块esp8266初始化(分别对应adapter.c文件和esp8266.c文件)。最后agent_tiny_entry()函数进入demo入口:
VOID main_task(VOID){#if defined(WITH_LINUX) || defined(WITH_LWIP) hieth_hw_init(); net_init();#elif defined(WITH_AT_FRAMEWORK) && defined(USE_ESP8266) extern at_adaptor_api at_interface; at_api_register(&at_interface); at_api_init();#else#endif //user_hw_init(); agent_tiny_entry();}
4.修改esp8266.hesp8266.h设置了WiFi连接的SSID和密码,需要自行需改。因为移植例程与官方历程都是用usart3进行通信,所以这里不做其他部分修改。另外,如需使用其他的串口或指令不同可进行修改。
5.修改agent_tiny_cmd_ioctl.c在agent_tiny_cmd_ioctl.c文件中添加头文件"bsp_led.h"。
atiny_write_app_write()函数用于对下发命令做出判断,可对其做出如下修改,控制LED2的开关:
int atiny_write_app_write(void* user_data, int len){ int i; char cmd_data[len]; memcpy(cmd_data,user_data,len); printf("################## %s",cmd_data); if(strstr(cmd_data,"L_ON")>0) //开补光灯 { LED2_ON(); // 输出高电平 } if(strstr(cmd_data,"L_OFF")>0) //关补光灯 { LED2_OFF(); // 输出低电平 } return ATINY_OK;}
6.对接数据
​
​
7.总结移植的一个难点在于cotex-M4的库函数到cotex-M3的库函数之间的转化,M4的库添加了很多功能,在移植的时候很多功能只能进行简化改写,因此可能并不像源码那么完善。另外一个难点在于与官方的at_frame相结合,我一直在尝试尽量少的去改写官方源码的代码,最后完成只改动了at_hal.c文件,其余改动均添加在了各个bsp文件中。官方给出的at_frame可以说相当精妙了,很方便,有很高的适配性,只需要移植一遍,便可了解整体框架。后面的协议层也挺给力的,试验一次就成功了。
最后贴出自己改写的at_hal.c文件:
#if defined(WITH_AT_FRAMEWORK)#include "atadapter.h"#include "bsp_usart.h"extern at_task at;extern at_config at_user_conf;USART_HandleTypeDef at_usart;//uint32_t list_mux;uint32_t wi = 0;uint32_t wi_bak= 0;uint32_t ri = 0;void at_irq_handler(void){ if(USART_GetITStatus(at_usart.Instance, USART_IT_RXNE) != RESET) { at.recv_buf[wi++] = (uint8_t)(at_usart.Instance->DR & (uint16_t)0x00FF); if (wi >= at_user_conf.user_buf_len)wi = 0; } if (USART_GetITStatus(at_usart.Instance,USART_IT_IDLE) != RESET) { at.recv_buf[wi++] = (uint8_t)(at_usart.Instance->DR & 0x00FF); wi_bak = wi; LOS_SemPost(at.recv_sem); }}void at_usart_config(void){ USART_HandleTypeDef * usart = &at_usart; usart->Instance = at_user_conf.usart; usart->Init.USART_BaudRate = at_user_conf.buardrate; usart->Init.USART_WordLength = USART_WordLength_8b; usart->Init.USART_StopBits = USART_StopBits_1; usart->Init.USART_Parity = USART_Parity_No; usart->Init.USART_HardwareFlowControl = USART_HardwareFlowControl_None; usart->Init.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_GpioInit(usart); USART_Init(usart->Instance,&usart->Init); USART_ClearFlag(usart->Instance,USART_FLAG_TC); LOS_HwiCreate(at_user_conf.irqn, 0, 0, at_irq_handler, 0); USART_ITConfig(usart->Instance, USART_IT_IDLE, ENABLE); USART_ITConfig(usart->Instance, USART_IT_RXNE, ENABLE); USART_Cmd(usart->Instance, ENABLE);}void at_transmit(uint8_t * cmd, int32_t len,int flag){ uint8_t t; char * line_end = at_user_conf.line_end;// (void)HAL_UART_Transmit(&at_usart, (uint8_t*)cmd, len, 0xffff);// if(flag == 1)// (void)HAL_UART_Transmit(&at_usart, (uint8_t*)line_end, strlen(at_user_conf.line_end), 0xffff); for(t=0;t<len;t++) { USART_SendData(at_usart.Instance,cmd[t]); while(USART_GetFlagStatus(at_usart.Instance, USART_FLAG_TXE) == RESET); } if(flag == 1) { for(t=0;t<strlen(line_end);t++) { USART_SendData(at_usart.Instance,line_end[t]); while(USART_GetFlagStatus(at_usart.Instance, USART_FLAG_TXE) == RESET); } }}int read_resp(uint8_t * buf){ uint32_t len = 0; uint32_t wi = wi_bak; uint32_t tmp_len = 0; if (NULL == buf){ return -1; } if (wi == ri){ return 0; } if (wi > ri){ len = wi - ri; memcpy(buf, &at.recv_buf[ri], len); } else { tmp_len = at_user_conf.user_buf_len - ri; memcpy(buf, &at.recv_buf[ri], tmp_len); memcpy(buf + tmp_len, at.recv_buf, wi); len = wi + tmp_len; } ri = wi; return len;}#endif
|
|