• [技术干货] 华为IoT杭州黑客松作品分享:机车风压电压实时监测系统LiteOS+NBIoT+OceanConnec...
    华为IoT杭州黑客松作品分享机车风压电压实时监测系统LiteOS+NBIoT+OceanConnect方案项目介绍:机车总风风压及蓄电池电压实时监测系统用于实时监测机车运行使用过程的蓄电池电压及机车风压,对出现的异常和危险情况及时报警,将监测数据存储并分析,以增加机车运行管理过程中的安全性和稳定性。功能描述:1、机车蓄电池电压及风压实时监测及报警2、监测数据存储分析方案介绍:本方案以LiteOS为核心,监测机车电压及风压数据并进行报警。将数据通过NB模组上报至OceanConnect平台,再由地面分析软件从平台请求数据,对数据进行存储分析。通过数据分析蓄电池使用及老化情况,及时提醒对接近使用寿命周期的电池进行更换,显著提升机车在运行管理中的安全性和稳定性。
  • [技术干货] 华为IoT杭州黑客松作品分享:小微机房动环监测系统LiteOS+NBIoT+OceanConnect方案
    华为IoT杭州黑客松作品分享小微机房动环监测系统LiteOS+NBIoT+OceanConnect方案应用场景:各通信运营商的室内分布设备借用客户的弱电间、弱电井等用于提供通信服务或其他服务。存在电费管理困难、设备监控难、维护难等问题;项目采用中控方式帮助运营商提取设备的电量使用、环境状态数据,同时根据客户要求对动力执行开关动作。项目描述:针对微型机房环境开发一套实用的动环监测(控),对如下量的监测:1、动力(转供电)——含用电量、电压、电流等2、温度、湿度量3、烟感报警开关量4、其他开关量对如下量的控制:1、动力开关具备声光提示功能;在线、定时执行动力开关的功能。方案介绍:前期已通过GPRS+DTU+485透传的方式,形成了将小微机房内的电表、烟感、温湿度设备连接到云端的小微机房动环方案,帮助客户解决小微机房的能源管理的和环境监测的功能,并在部分地方进行了试点。但这种方案存在由于采购组件多,成本不可控;线缆多,可靠性差;无法解决在微型机房内信号质量变差时,动力开关无法控制;增加新设备困难,设备调试困难等等问题,无法满足客户需求。现方案采用NBIoT模块+STM32+DTH11+SP3485以及华为LiteOS的处理核心的方案,由本地STM32在LiteOS控制下,定时通过485使用MODBUS协议读取电源模块、烟感模块运行数据,汇总后再通过NBIoT以CoAP协议传递到华为ConnectOcean平台。华为云下发控制消息给本地模块,设置电力控制的时间点或实施操控。相较于原方案,此方案产品安装方便,布线少,美观,可靠性高;设备可以增加声光提示功能;并逐步实现智能化,能够提供平台满足客户的更多需求。华为LiteOS及OceanConnect成熟的组件和产品简化了产品的开发的过程,具有很高的稳定性和安全性。
  • [技术干货] 华为IoT杭州黑客松作品分享:工业缝纫机租赁服务:NB-IOT/OceanConnect/LiteOS方案
    huawei IoT prsentation.pptx背景:        杰克缝纫机股份有限公司专注于工业缝制机械的研发、生产和销售的国际化民营高新技术企业。经过多年的经营和发展,公司已成为行业领先的缝制机械制造商。公司于2017年收购意大利迈卡(自动衬衫工业缝纫机  http://chinabruce.cn/aboutus.aspx  )、2018年收购意大利意大利威比玛(自动牛仔工业缝纫机  引进中)厂商,进口设备销售成本高昂,服装厂难以承受;但是自动缝纫机有广阔的前景,随着中国人口红利消失,年轻人越来越不愿意从事机械化的工作,工厂招工难,人工成本上涨迅速,自动机的生产效率是人工的好几倍;针对以上问题,采取开展新商业模式,进行全自动设备的租赁服务,与国产化降低成本相互促进。现有特种缝纫机,(平、包、绷)三机等等机器物联网项目陆续开展。项目描述:        该产品主要应用于工业缝纫机租赁服务,主要功能为采集工业缝纫机的数据信息(计件信息、故障信息等等)进行上报,通过网页/微信小程序/APP显示,达到统计工厂生产进度功能,实现租赁计费,使工厂老板足不出户即可全方位的了解工厂的生产状况。现阶段主要适配价格较高(3万~50万/台)的全自动工业缝纫机。        物联网设备通过NB模块连接华为OceanConnect平台(南向),上报设备信息;通过WEB服务器连接华为OceanConnect平台(北向),获取数据,进行统计分析,并且可以下发锁机提醒等控制命令。        以下是项目架构框图:        产品技术实现: 软硬件:        硬件采用本次黑客松活动 南京厚德物联网有限公司 提供的EVB_L1开发板,搭载低功耗MCU和NB模块BC28。本次DEMO使用按键进行模拟采集缝纫机数据的过程,按键F1一道工序的起始信号,按键F2一道工序的结束信号,使用板载LED等作为锁机控制的执行机构。这次DEMO是结合开发板进行一种采集模式的定制,采集模式还有很多种,不同机种分为通讯和非通讯两大类。        单片机软件采用华为LiteOS进行任务的管理和调度,南向对接华为IOT平台,采用COAP协议的二进制流。LiteOS 便于快捷开发,中文资料丰富。制作了一个小的DEMO网页对接北向华为IOT平台。        开发板如下图所示:Profile 插件使用NB-IOT的数据上报和控制下发DEMO网页现有管理系统现有物联网设备商业应用:物联网设备应用于自己生产的工业缝纫机,缝纫机租赁新商业模式项目,已经商用;现有解决方案:FreeRTOS/ONENET/GPRS;由于使用免费和开源技术,缺少必要的技术支持和相关认证;作为缝纫机制造的领军企业,年出货量客观;物联网设备降低成本,提高稳定性后,可以作为卖点配备给所有出厂缝纫机;
  • ​Huawei LiteOS 编程问题
    Huawei LiteOS 编程,语法求指导?1、 UINT32 ulRet = LOS_OK;这句是设置32位无符号整数ulRet,而ulRet = LOS_OK,什么意思?2、TSK_INIT_PARAM_S stTask = {0};设置个stTask数组还是什么意思?TSK_INIT_PARAM_S什么意思?
  • [热门活动] 【开发者英雄大会】IoT赛道(老用户入口)-LiteOS打造智能设备,原来你也可以轻松设计
    附上LiteOS开源代码链接:https://github.com/LiteOS/LiteOS活动整体介绍总入口点我了解
  • [热门活动] 【开发者英雄大会】IoT赛道(新用户入口)-LiteOS打造智能设备,原来你也可以轻松设计
    附上LiteOS开源代码链接:https://github.com/LiteOS/LiteOS活动整体介绍总入口点我了解
  • [技术干货] 【深创客】跟我学NB-IoT之AT命令从入门到精通系列一:LiteOS及开发板入门
    总介绍NB476开发板是以STM32L476为主控,结合BC95-B5模块的低功耗窄带宽物联网开发板。除此之外,开发板还配备了丰富的外围模块,为了让开发者更快速的上手使用,这里将会连续更新一些列教程用以解释说明开发板适配的LiteOS例程。最终会在开发板上运行一个基于Liteos系统 ,使用BC95上报&接收的DEMO。一、本节教程目的实现小灯的闪烁实现以按键中断的方式切换小灯亮灭状态二、开发环境NB476开发板套件Keil&STM32CubeMX开发工具三、开发步骤(一)获取源码下载一份已经针对NB476开发板移植好的Liteos操作系统,源码下载。使用Keil打开./liteos/targets/STM32L476_NB476/MDK-ARM目录下的Huawei_LiteOS.uvprojx工程文件。如果你手里有自己的STM32开发板,可参考官方移植教程,尝试移植。(二)初始化要操作的硬件(关键步骤)1.引脚初始化(1)通过开发板原理图,得知小灯(USR_LED)使用的是PB2引脚,按键(SW_4)使用的是PC3引脚。(2)以上两个引脚功能的初始化,在main()->HardWare_Init()->MX_GPIO_Init();函数中。注意,初始化代码可通过STM32CubeMX工具自动生成,然后复制粘贴到LiteOS中进行使用,不用自己手动编写。(自动生成过程也需要占用一定的篇幅,可至文末下载或预览附件查看)。2.注册中断由于LiteOS操作系统并不接管硬件中断,所以,这里还需要注册SW_3按键所使用到的中断线,要注意的是,中断注册要放到内核初始化后,即LOS_KernelInit()后。 使用LOS_HwiCreate()函数进行中断注册,完整注册方式如下,LOS_HwiCreate(EXTI3_IRQn, 2,0,EXTI3_IRQHandler, NULL);代码如下int main(void) {     UINT32 uwRet = LOS_OK;     //引脚功能初始化     HardWare_Init();     uwRet = LOS_KernelInit();     if (uwRet != LOS_OK)     {         return LOS_NOK;     }     //对以下任务中要用到的中断号进行注册     LOS_HwiCreate(EXTI3_IRQn, 2,0,EXTI3_IRQHandler, NULL);     //任务注册     //...     LOS_Start(); } 3.创建任务在注册完中断后,创建一个任务用于执行小灯闪烁。例如:int main(void) {     UINT32 uwRet = LOS_OK;     //引脚功能初始化     HardWare_Init();     uwRet = LOS_KernelInit();     if (uwRet != LOS_OK)     {         return LOS_NOK;     }     //对以下任务中要用到的中断号进行注册     LOS_HwiCreate(EXTI3_IRQn, 2,0,EXTI3_IRQHandler, NULL);     //任务注册     uwRet = LOS_LEDExampleEntry();//小灯闪烁任务     if (uwRet != LOS_OK)     {         return LOS_NOK;     }     LOS_Start(); } UINT32 LOS_LEDExampleEntry(void)//小灯闪烁任务 {     UINT32 uwRet;     TSK_INIT_PARAM_S stTaskInitParam;     (VOID)memset((void *)(&stTaskInitParam), 0, sizeof(TSK_INIT_PARAM_S));     stTaskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)LOS_LEDExampleTskfunc;//入口函数     stTaskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE;     stTaskInitParam.pcName = "LEDDemo";     stTaskInitParam.usTaskPrio = 10;     uwRet = LOS_TaskCreate(&g_uwledTaskID, &stTaskInitParam);     if (uwRet != LOS_OK)     {         return LOS_NOK;     }     return LOS_OK; }其中LOS_LEDExampleTskfunc为任务的入口函数。(更多Liteos基础范例与介绍可参考基础范例与介绍)在入口函数中实现小灯的闪烁。代码如下//小灯闪烁 VOID LOS_LEDExampleTskfunc(VOID) { while (1) { LOS_LED_ON(); LOS_TaskDelay(1000); LOS_LED_OFF(); LOS_TaskDelay(1000); } }4.重载中断回调函数 在stm32l4xx_it.c中重载GPIO的中断回调函数。当按键中断被触发时,CPU会自动执行如下代码void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)//GPIO中断回调函数 { if(GPIO_Pin == SW4_Pin)//按键中断 { LOS_LED_Toggle();//USR_LED状态切换 } }(三)编译与烧录1.编译,如图  2.使用STLINK与NB476相连SWDIO接SWDIO,SWCLK接SWCLK,GND接GND,如图3.点击下载,如图四、最终效果USR_LED一秒闪烁一次,且可以通过SW4按键切换小灯亮灭状态 下一篇:【深创客】跟我学NB-IoT之AT命令从入门到精通系列二:传感器数据采集与显示代码生成例程操作指导简单代码生成例程.pdf( 预览 )
  • [热门活动] 【开发者英雄大会】LiteOS年底狂欢,赢取AI音响/Cherry键盘等更多好礼!——IoT赛道
            
  • [问题求助] 请问liteos系统怎样在程序里面设置永久ip
    本人用3516cv300开发  请问怎么给板子设置永久固定ip啊 内核里面有配置吗
  • [问题求助] liteos移植stm32f103vc遇到中断问题
    rt在移植rtc中断的过程中遇到问题。rtc的中断号是3号,            然后los_hwi.c的中断向量表中的3号向量是osHwiDeafultHandler,现在每次都会跳转到osHwiDefaultHandler里面来而按照官方的要求,说最好是不要修改这个向量表里面的内容,而是往后面添加向量,比如调用LOS_HwiCreate函数,就是往这个15个向量后面添加中断向量,如果这样的话,我就必须修改stm32f13x.h这个头文件把后面所有的向量都加15,会有些麻烦,想问下有没有两全的方法呢?
  • [技术干货] 【深创客】NB476Liteos例程
    简介    该例程以NB476开发板为硬件平台,结合华为Liteos操作系统,实现环境参数的采集,并使用NB网络进行数据上报。前置条件      NB476开发板:购买通道1  购买通道2    Keil&STM32CubeMX开发工具:下载链接 密码:7cws    OceanConnect账号:选择“OceanConnect”环境,单击“预约”按钮,进行试用申请步骤    1.下载一份已经针对NB476开发板移植好的Liteos操作系统          注:完整例程源码见文末附件1        注:云端配置文件见文末附件2        如果是要自己给自己的开发板移植Liteos,可参考如下官方移植教程          Liteos移植教程    2.初始化要用到的引脚,注册要用到的中断        在main函数中做如下添加int main(void) {     UINT32 uwRet = LOS_OK;     //引脚功能初始化     HardWare_Init();     uwRet = LOS_KernelInit();     if (uwRet != LOS_OK)     {         return LOS_NOK;     }     //对以下任务中要用到的中断号进行注册     LOS_HwiCreate(EXTI3_IRQn, 2,0,EXTI3_IRQHandler, NULL);     LOS_HwiCreate(LPUART1_IRQn, 0, 0, LPUART1_IRQHandler, NULL);     LOS_HwiCreate(DMA1_Channel1_IRQn, 3,0, DMA1_Channel1_IRQHandler, NULL);     LOS_HwiCreate(USART2_IRQn, 1, 0, USART2_IRQHandler, NULL);          LOS_Start();  }       3.创建任务,点亮板载小灯        在main函数中做如下添加int main(void) {     UINT32 uwRet = LOS_OK;     //引脚功能初始化     HardWare_Init();     uwRet = LOS_KernelInit();     if (uwRet != LOS_OK)     {         return LOS_NOK;     }     //对以下任务中要用到的中断号进行注册     LOS_HwiCreate(EXTI3_IRQn, 2,0,EXTI3_IRQHandler, NULL);     LOS_HwiCreate(LPUART1_IRQn, 0, 0, LPUART1_IRQHandler, NULL);     LOS_HwiCreate(DMA1_Channel1_IRQn, 3,0, DMA1_Channel1_IRQHandler, NULL);     LOS_HwiCreate(USART2_IRQn, 1, 0, USART2_IRQHandler, NULL);          //小灯闪烁任务     uwRet = LOS_LEDExampleEntry();     if (uwRet != LOS_OK)     {         return LOS_NOK;     }          LOS_Start(); } //小灯闪烁任务   UINT32 LOS_LEDExampleEntry(void) {     UINT32 uwRet;     TSK_INIT_PARAM_S stTaskInitParam;     (VOID)memset((void *)(&stTaskInitParam), 0, sizeof(TSK_INIT_PARAM_S));     stTaskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)LOS_LEDExampleTskfunc;//入口函数     stTaskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE;     stTaskInitParam.pcName = "LEDDemo";     stTaskInitParam.usTaskPrio = 10;     uwRet = LOS_TaskCreate(&g_uwledTaskID, &stTaskInitParam);     if (uwRet != LOS_OK)     {         return LOS_NOK;     }     return LOS_OK; } //小灯闪烁 VOID LOS_LEDExampleTskfunc(VOID) { while (1) { LOS_LED_ON(); LOS_TaskDelay(1000); LOS_LED_OFF(); LOS_TaskDelay(1000); } }    4.实现以按键中断的方式切换小灯亮灭状态        在stm32l4xx_it.c中实现GPIO中断回调函数void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)//GPIO中断回调函数 {     if(GPIO_Pin == SW4_Pin)//按键中断     {         LOS_LED_Toggle();//USR_LED状态反转     } }    5.创建任务,实现环境温度的采集,并显示在OLED上        在main函数中做如下添加int main(void) {     UINT32 uwRet = LOS_OK;          ***          //温湿度采集与OLED显示任务     uwRet = LOS_OLED_DHT11ExampleEntry();     if (uwRet != LOS_OK)     {         return LOS_NOK;     }          LOS_Start(); } /*  具体函数实现就不在这里展现了,可见移植完后的附件2 */    6.创建任务,实现电池电压采集,功耗计算        在main函数中做如下添加int main(void) {     UINT32 uwRet = LOS_OK;          ***          //AD采样任务     uwRet = LOS_ADCExampleEntry();         if (uwRet != LOS_OK)         {                 return LOS_NOK;         }              LOS_Start(); } /*  具体函数实现就不在这里展现了,可见移植完后的附件2 */    7.创建任务,实现数据上报与命令接收        在main函数中做如下添加int main(void) {     UINT32 uwRet = LOS_OK;          ***          //NB通信任务     uwRet = LOS_BC95ExampleEntry();         if (uwRet != LOS_OK)         {                 return LOS_NOK;         }              LOS_Start(); } /*  具体函数实现就不在这里展现了,可见移植完后的附件2 */    8.云端配置        profile            插件结果&举例    1.在开发板上可以看到OLED显示温湿度        2.通过调试串口,可以看到AD采样信息    3.在云端可以看到上报的采样信息(温度,湿度,电池电量,功耗)    4.当下发GPS开启命令后,如图,过一会就可以看到上报的GPS坐标注:要将开发板带到户外才能定位.源码(因为论坛附件大小要求不能超过20M,所以暂时不能上传,我们会立刻处理,第一时间补传)附件1   移植完毕的Liteos附件2L476_LITEOS_V2_CIGPlug-in_sign.zipL476_LITEOS_V2_PLKJ_L476.zip
  • [交流吐槽] 开源liteos项目VOID LOS_BC95ExampleTskfunc(VOID)红框里的为什么是这样的不太懂,仅仅是为了唤醒...
  • [问题求助] STM32CubeMx生成的F103裸机程序移植LiteOS 编译报错,求指点
    我已经修改了本来的启动文件,但是任然报错。求大神指点下。官方的移植教程感觉应该是很早以前的。
  • [问题求助] STM32F476RG BC28 搭载liteos ,低功耗设置求助
    硬件平台: 主控MCU stm32F476RG ,NB 通信模块:移远BC28软件环境:主控MCU 运行LiteOS设备要求:低功耗,支持FOTA远程升级mcu主控和NB固件场景描述:室外数据采集监测,数据发送间隔1小时;问题描述: 之前程序采用MSI时钟,经过PLL升级后,SYS主时钟为80M。数据采集上传稳定正常,liteos任务切换正常。        因低功耗考虑,引入了tickless机制。参考了 “EVB_M1_Liteos-master”tickless部分代码。        A第一版程序设计:            第一次进入ticklessHandler,Mcu进入stop模式,1h后rtc唤醒。如下图所示,芯片唤醒后,任务不能切换。           考虑到可能是 osUpdateKernelTickCount函数设置不对,该函数每次要求传入一个本次休眠的tick数void osTicklessHandler(void){#if (LOSCFG_PLATFORM_HWI == YES)....#else    if (g_bTickIrqFlag)    {        UINTPTR uvIntSave;        uvIntSave = LOS_IntLock();        LOS_TaskLock();        g_bTickIrqFlag = 0;        osTicklessStart();        //第一次进入ticklessHandler,Mcu进入stop模式,1h后rtc唤醒        #if (LOSCFG_KERNEL_RUNSTOP == YES)         enterSotpMode(SleepSeconds);        #endif        ......................                  uvIntSave = LOS_IntLock();        osUpdateKernelTickCount(0);  /* param: 0 - invalid */        LOS_TaskUnlock();        LOS_IntRestore(uvIntSave);    }........................}B 第二版设计每次睡眠可以tickless可以的时间  enterSotpMode(g_uwSleepTicks); tickless 有两个重要的变量,每次可以睡眠的tick数由他们决定。由此可知,当OS_SYS_CLOCK越小,每次进入osTicklessHandler,可以休眠的时间更长。void osTicklessStart(void){    UINT32 uwCyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND;      UINT32 uwMaxTicks = LOSCFG_SYSTICK_LOAD_RELOAD_MAX / uwCyclesPerTick..............}使用HSE 8M,降低systick主时钟为1M当时钟钟低于1M的,任务不能正常切换在降低时钟后HAL_DELAY函数 LOS_TaskDelay函数  LOS_TickCountGetint los_dev_uart_read(int uartidx, char *outbuf, int rsize, int mstimout)int los_dev_uart_write(int uartidx, char *inbuf, int wsize, int mstimout)这些和时间有关系的都不太正常即便在1M的主频下可以运行,每次进入tickless最多可以睡眠16s样子,这样休眠1h,需要不断醒来在睡。总结:个人觉得低功耗应该还是第一种设计,但是第一种设计下,睡眠后liteos如何正确的工作进行仍无调度呢?请各位高手赐教
  • [技术干货] Huawei_LiteOS的启动文件与sct文件分析
    软件环境:Keil 51.  裸机启动文件与sct文件分析关于stm32裸机启动文件的简单分析可参考:STM32学习笔记(6):启动代码(启动代码)总结来说:定义STACK段,{NOINIT,读写}:分配一段内存大小为0.5K。定义HEAP段,{NOINIT,读写}:分配一段内存大小为1K。定义RESET段,{DATA,只读}:DCD各种中断向量。定义|.text |段,{CODE,只读}:Reset_Handler函数,函数中最后加载了__main;对剩余的中断函数进行了弱定义;在最后还有一段用户初始化堆栈的代码__user_initial_stackheap。那这些代码都存放在什么位置呢?看一下.sct文件:LR_IROM1 0x08000000 0x00080000  {    ; load region size_region   ER_IROM1 0x08000000 0x00080000  {  ; load address = execution address    *.o (RESET, +First)    *(InRoot$$Sections)    .ANY (+RO)   }   RW_IRAM1 0x20000000 0x00010000  {  ; RW data    .ANY (+RW +ZI)   } }STACK段和HEAP段是RW属性,存在RAM(0x20000000-0x20010000)中,具体的地址由编译器在后面链接时决定,并不是一定存在RAM的开头地址(本人刚开始理解的误区)。RESET段存在FLASH(0x08000000-0x08080000)中,而且是FLASH的最开头。再结合CORTEX-M3的特性,其上电后根据启动引脚来决定PC位置,比如启动设置为FLASH启动,则启动后PC跳到0x08000000。此时CPU会先取2个地址(硬件决定),第一个是栈顶地址,第二个是复位异常地址,这样就跳到Reset_Handler,Reset_Handler执行到将最后跳转到C库的__main。|.text|段是CODE属性,也存在FLASH区。启动代码所做的工作如下图所示:先是建立了堆栈,之后上电后寻找到中断向量表中的复位函数reset_handler执行,之后跳转到__main执行C库函数,最后由__main调用main()函数,进入C的世界。__main的主要作用以及和我们自己写的main()函数的区别,可以参考:ARM启动代码中_main与用户主程序的main()中的区别2.  __user_initial_stackheap分析一波__user_initial_stackheap,这段代码位于裸机启动文件的末尾:                 IF      :DEF:__MICROLIB                                  EXPORT  __initial_sp                  EXPORT  __heap_base                  EXPORT  __heap_limit                                   ELSE                                 IMPORT  __use_two_region_memory                  EXPORT  __user_initial_stackheap                  __user_initial_stackheap                  LDR     R0, =  Heap_Mem                  LDR     R1, =(Stack_Mem + Stack_Size)                  LDR     R2, = (Heap_Mem +  Heap_Size)                  LDR     R3, = Stack_Mem                  BX      LR若是使用了microlib,则只需要将__initial_sp,__heap_base,__heap_limit三个变量定义成全局变量即可(这三个变量也是固定的可被C库引用,在库中需要使用到这三个变量对堆栈进行初始化);否则,就需要自己定义__user_initial_stackheap。microlib缺省的情况下使用的是Keil C库。但是事实上,µVision 库里包含了更多__user_initial_stackheap()的函数体,这样编译器可以根据开发人员scatter文件的内容自动选择合适的函数体。换句话说,针对RVCT v3.x及之后的版本,使用scatter文件的开发人员可以不再重新实现__user_initial_stackheap()的函数体。(参考:__user_initial_stackheap() 上班偷懒翻译的KEIL说明书里的)也就是说不必再自己写了__user_initial_stackheap,自己在做实验验证时,没有使用microlib库,同时也将这部分函数注释掉,并没有产生任何异常。所以对__user_initial_stackheap在这里就不再做更多深入的研究了,这一部分太烧脑了,就当作C库已经为我们准备好了这个函数。3.  堆栈的单区模型和双区模型堆栈分为单区模型和双区模型:单区模型堆和栈在同一存储器区中互相朝向对方增长双区模型将堆和栈分别放置在存储器不同的区中,__user_initial_stackheap() 建立的专用堆限制来检查堆,需要设置堆栈的长度。选择使用单区模型,在sct文件中定义一个特殊的执行域,使用符号:ARM_LIB_STACKHEAP,并使用EMPTY属性。这样库管理器就选择了一个把这个域当作堆和栈合并在一起的__user_initial_stackheap()函数。在这个函数中使用了"Image$$ARM_LIB_STACKHEAP$$Base"和"Image$$ARM_LIB_STACKHEAP$$ZI$ $Limit"符号 。选择使用双区模型,在sct文件中定义两个特殊的执行域,使用符号:ARM_LIB_STACK和ARM_LIB_HEAP,都要使用EMPTY属性。这样库管理器就会选择使用符号:"Image$$ARM_LIB_HEAP$$Base","Image$$ARM_LIB_STACK$$ZI$$limit"、"Image$$ARM_LIB_STACK$$Base"、"Image$$ARM_LIB_STACK$$ZI$$Limit"的__user_initial_stackheap()函数。从裸机的启动文件可以看出,裸机使用的是双区模型,那么问题来了:为啥裸机的.sct文件没有ARM_LIB_STACK和ARM_LIB_HEAP这两个加载域呢?我猜呢,ARM_LIB_STACK和ARM_LIB_HEAP需要跟带$的那四个符号配套使用,但启动文件里没使用带$的那四个符号,没有赋值,而是直接将__initial_sp,__heap_base,__heap_limit这三个变量提供给C库使用。我是这么理解的,有没有屌大的来反驳我一下。4.  Huawei_LiteOS启动文件与sct文件首先启动文件:LOS_Heap_Min_Size   EQU     0x400                 AREA    LOS_HEAP, NOINIT, READWRITE, ALIGN=3 __los_heap_base LOS_Heap_Mem    SPACE   LOS_Heap_Min_Size                 AREA    LOS_HEAP_INFO, DATA, READONLY, ALIGN=2                 IMPORT  |Image$$ARM_LIB_STACKHEAP$$ZI$$Base|                 EXPORT  __LOS_HEAP_ADDR_START__                 EXPORT  __LOS_HEAP_ADDR_END__ __LOS_HEAP_ADDR_START__                 DCD     __los_heap_base __LOS_HEAP_ADDR_END__                 DCD     |Image$$ARM_LIB_STACKHEAP$$ZI$$Base| - 1                 PRESERVE8                 AREA    RESET, CODE, READONLY                 THUMB                 IMPORT  ||Image$$ARM_LIB_STACKHEAP$$ZI$$Limit||                 IMPORT  osPendSV                 EXPORT  _BootVectors                 EXPORT  Reset_Handler _BootVectors                 DCD     ||Image$$ARM_LIB_STACKHEAP$$ZI$$Limit||                 DCD     Reset_Handler Reset_Handler                 IMPORT  SystemInit                 IMPORT  __main                 LDR     R0, =SystemInit                 BLX     R0                 LDR     R0, =__main                 BX      R0                 ALIGN                 END定义LOS_HEAP段,{NOINIT,读写}:分配一段内存大小为1K。定义LOS_HEAP_INFO段,{DATA,只读}:定义__LOS_HEAP_ADDR_START__和__LOS_HEAP_ADDR_END__这两个全局变量供OS使用。定义RESET段,{CODE,只读}:启动向量,第一个是栈顶地址,第二个是Reset_Handler;将Reset_Handler主体也写入了RESET段。首先,可以看出,分配堆栈的方式与裸机不同,使用的是单区模型,从下向上排列:__LOS_HEAP_ADDR_START__=__los_heap_base,为堆低地址;__LOS_HEAP_ADDR_END__=|Image$ $ARM_LIB_STACKHEAP$$ZI$ $Base| - 1,为堆顶(不确定的地址);|Image$ $ARM_LIB_STACKHEAP$ $ZI$ $Base|,为栈底(不确定的地址);|Image$ $ARM_LIB_STACKHEAP$ $ZI$ $Limit|,为栈顶地址;所以,由上文可知,在sct文件中必然会出现ARM_LIB_STACKHEAP这个执行域:LR_IROM1 0x08000000 0x00020000  {    ; load region size_region     ER_IROM1 0x08000000 0x00020000  {    ; load address = execution address         *.o (RESET, +First)         *(InRoot$$Sections)         .ANY (+RO)         * (LOS_HEAP_INFO)     }     VECTOR 0x20000000 0x400  {    ; Vector         * (.data.vector)     }     RW_IRAM1 0x20000400 0x00004800  {    ; RW data         ;.ANY (+RW +ZI)         * (.data, .bss)         * (LOS_HEAP)     }     ARM_LIB_STACKHEAP 0x20004C00 EMPTY 0x400  {    ;LiteOS MSP     } }那么其他的异常中断向量入口在哪里呢?定义在los_hwi.c文件中被定义成了数组的形式:#ifdef __ICCARM__ #pragma  location = ".data.vector" #elif defined (__CC_ARM) || defined (__GNUC__)LITE_OS_SEC_VEC #endifHWI_PROC_FUNC m_pstHwiForm[OS_VECTOR_CNT] = {     (HWI_PROC_FUNC)0,                    // [0] Top of Stack     (HWI_PROC_FUNC)Reset_Handler,        // [1] reset     (HWI_PROC_FUNC)osHwiDefaultHandler,  // [2] NMI Handler     (HWI_PROC_FUNC)osHwiDefaultHandler,  // [3] Hard Fault Handler     (HWI_PROC_FUNC)osHwiDefaultHandler,  // [4] MPU Fault Handler     (HWI_PROC_FUNC)osHwiDefaultHandler,  // [5] Bus Fault Handler     (HWI_PROC_FUNC)osHwiDefaultHandler,  // [6] Usage Fault Handler     (HWI_PROC_FUNC)0,                    // [7] Reserved     (HWI_PROC_FUNC)0,                    // [8] Reserved     (HWI_PROC_FUNC)0,                    // [9] Reserved     (HWI_PROC_FUNC)0,                    // [10] Reserved     (HWI_PROC_FUNC)osHwiDefaultHandler,  // [11] SVCall Handler     (HWI_PROC_FUNC)osHwiDefaultHandler,  // [12] Debug Monitor Handler     (HWI_PROC_FUNC)0,                    // [13] Reserved     (HWI_PROC_FUNC)osPendSV,             // [14] PendSV Handler     (HWI_PROC_FUNC)osHwiDefaultHandler,  // [15] SysTick Handler};这一部分代码被分散加载文件加载到了VECTOR段,位于RAM的开头部分。至于中断是怎么实现的我还的在看几天安利一下自己的博客:https://blog.csdn.net/sinat_27066063
总条数:623 到第
上滑加载中