Fillmore

  • 2019-05-24
  • 发表了主题帖: 【分享】Flash 管理工具: FAL (Flash 抽象层)库

    之前做了一些关于 Flash 的开源组件,比如:EasyFlash,SFUD, EasyLogger(内部的 Flash 插件),经常会有些网友问我一些关于 Flash 的问题,比如:在 Flash 的使用过程相信大家会经常遇到 OTA 升级时如何对 Flash 进行分区,多个 Flash 如何集中管理,片外的 fatfs 文件系统能否跑在片内等。 今天跟大家分享一个运行在MCU上的 Flash 管理工具,名为 FAL(Flash 抽象层),它是 RT-Thread 开源的一个通用软件包,能够运行在裸机平台,也能无缝兼容 RT-Thread 系统。一起来看下它的特色。 介绍FAL (Flash Abstraction Layer) Flash 抽象层是对 Flash 及基于 Flash 的分区进行管理、操作的抽象层,对上层统一了 Flash 及 分区操作的 API ,并具有以下特性:支持静态可配置的分区表,并可关联多个 Flash 设备;分区表支持 自动装载 。避免在多固件项目,分区表被多次定义的问题;代码精简,对操作系统 无依赖 ,可运行于裸机平台,比如对资源有一定要求的 Bootloader;统一的操作接口。保证了文件系统、OTA、NVM(例如:EasyFlash) 等对 Flash 有一定依赖的组件,底层 Flash 驱动的可重用性;自带基于 Finsh/MSH 的测试命令,可以通过 Shell 按字节寻址的方式操作(读写擦) Flash 或分区,方便开发者进行调试、测试; FAL 框架图如下:http://bbs.21ic.com/data/attachment/forum/201905/21/154054weujalv8a35lah7v.jpg 使用 fal使用 fal 前需要对项目的 Flash 进行移植工作,移植的文档位于: /samples/porting/README.md 。移植完成后,调用 fal_init() 初始化该库。 常见应用基于 FAL 分区的 fatfs 文件系统例程基于 FAL 分区的 littlefs 文件系统应用笔记基于 FAL 分区的 EasyFlash 移植说明 Finsh/MSH 测试命令fal 提供了丰富的测试命令,项目只要在 RT-Thread 上开启 Finsh/MSH 功能即可。在做一些基于 Flash 的应用开发、调试时,这些命令会非常实用。它可以准确的写入或者读取指定位置的原始 Flash 数据,快速的验证 Flash 驱动的完整性,甚至可以对 Flash 进行性能测试。具体功能如下:输入 fal 可以看到完整的命令列表msh />fal Usage: fal probe [dev_name|part_name]   - probe flash device or partition by given name fal read addr size               - read 'size' bytes starting at 'addr' fal write addr data1 ... dataN   - write some bytes 'data' starting at 'addr' fal erase addr size              - erase 'size' bytes starting at 'addr' fal bench              - benchmark test with per block size msh />复制代码 指定待操作的 Flash 设备或 Flash 分区当第一次使用 fal 命令时,直接输入 fal probe 将会显示分区表信息。可以指定待操作的对象为分区表里的某个分区,或者某个 Flash 设备。分区或者 Flash 被成功选中后,还将会显示它的一些属性情况。大致效果如下:msh />fal probe    No flash device or partition was probed. Usage: fal probe [dev_name|part_name]   - probe flash device or partition by given name. [I/FAL] ==================== FAL partition table ==================== [I/FAL] | name      | flash_dev    |   offset   |    length  | [I/FAL] ------------------------------------------------------------- [I/FAL] | bl        | stm32_onchip | 0x00000000 | 0x00010000 | [I/FAL] | app       | stm32_onchip | 0x00010000 | 0x000b0000 | [I/FAL] | ef        | norflash0    | 0x00000000 | 0x00100000 | [I/FAL] | download  | norflash0    | 0x00100000 | 0x00100000 | [I/FAL] ============================================================= msh /> msh />fal probe download Probed a flash partition | download | flash_dev: norflash0 | offset: 1048576 | len: 1048576 |. msh />复制代码 擦除数据 先输入 fal erase ,后面跟着待擦除数据的起始地址以及长度。以下命令为:从 0 地址(相对 Flash 或分区)开始擦除 4096 字节数据
    注意:根据 Flash 特性,擦除动作将按扇区对齐进行处理。所以,如果擦除操作地址或长度未按照 Flash 的扇区对齐,将会擦除掉与其关联的整个扇区数据。msh />fal erase 0 4096 Erase data success. Start from 0x00000000, size is 4096. msh />复制代码
    写入数据 先输入 fal write ,后面跟着 N 个待写入的数据,并以空格隔开。以下命令为:从地址 8 的位置依次开始写入 1、2、3、4 、 5 这 5 个字节数据msh />fal erase 0 4096 Erase data success. Start from 0x00000000, size is 4096. msh />复制代码 读取数据 先输入 fal read ,后面跟着待读取数据的起始地址以及长度。以下命令为:从 0 地址开始读取 64 字节数据msh />fal read 0 64 Read data success. Start from 0x00000000, size is 64. The data is: Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F [00000000] FF FF FF FF FF FF FF FF 01 02 03 04 05 FF FF FF [00000010] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF [00000020] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF [00000030] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF msh />复制代码 性能测试 性能测试将会测试 Flash 的擦除、写入及读取速度,同时将会测试写入及读取数据的准确性,保证整个 Flash 或整个分区的 写入与读取 数据的一致性。先输入 fal bench ,后面跟着待测试 Flash 的扇区大小(请查看对应的 Flash 手册,SPI Nor Flash 一般为 4096)。由于性能测试将会让整个 Flash 或者整个分区的数据丢失,所以命令最后必须跟 yes 。msh />fal bench 4096 yes Erasing 1048576 bytes data, waiting... Erase benchmark success, total time: 2.674S. Writing 1048576 bytes data, waiting... Write benchmark success, total time: 7.107S. Reading 1048576 bytes data, waiting... Read benchmark success, total time: 2.716S. msh />复制代码 更多 API 及最新代码详见 GitHub:https://github.com/RT-Thread-packages/fal 本坛下载:

  • 回复了主题帖: 【RT-Thread读书笔记】+ 痛并快乐着

    深表同感

  • 2019-04-22
  • 回复了主题帖: 【RT-Thread读书笔记】正视操作系统

    本帖最后由 Fillmore 于 2019-4-22 16:06 编辑 ucos/freertos/RT-Thread,选择这三款 OS 的都是值得去接触的,它们的年限都比较长了,在市面上都蛮有知名度,用过的人比较多,更有说服力。 基本功能、性能:各家 RTOS 差异很小,可比性并不是很大 易用性/可读性 :这块 FreeRTOS 应该说是最差,奇葩的匈牙利命名法,代码实现用了很多宏,可读性非常差。ucos 可读性还可以,注释也很全。 RT-Thread 这块也还行,它是类 Linux 的代码风格,面向对象的设计模式,代码简洁易懂。在保证了体积(最小 ROM:3K RAM:1.5K)的同时,还借鉴了 Linux 的设备驱动框架、虚拟文件系统、Shell 等功能    物联网组件丰富真正的好处在于做物联网产品时候可以做到开箱即用。RTT能运行 Python、JavaScript、Lua 这些高级语言的脚本,相较来说还是可以提供不少方便的

  • 2019-04-19
  • 回复了主题帖: 【RT-Thread读书笔记】之初识模样

    感谢分享! 期待楼主之后的分享

  • 2019-04-12
  • 发表了日志: wireshark抓tls数据包

  • 发表了主题帖: wireshark抓tls数据包

    随着物联网的发展,连接到互联网的设备数量呈指数增长,物联网信息安全越来越重要。因此,TLS 逐渐成为物联网通讯的标配。但是 TLS 是加密传输,这给调试增加了一定的难度。笔者最近工作中一直用到 HTTPS,但是苦于 wireshark 只能抓取 HTTP 的明文数据包,无法抓取 HTTPS 的数据包,于是就有了这篇文章,在 RT-Thread 系统上,使用 wireshark 抓取 HTTPS 数据包. 1、简单介绍TLS1.2握手和协商过程2、设备端解密https数据包配置wiresharkwireshark抓包全文在这里>>>https://mp.weixin.qq.com/s/IN10NzvTpi5EG84yyYmzPg

  • 2019-04-11
  • 回复了主题帖: 【STM32MP157C-EV1】首次开箱评测之后会在上面跑rtt在分享其他

  • 发表了主题帖: 【STM32MP157C-EV1】首次开箱评测之后会在上面跑rtt在分享其他

    此内容由EEWORLD论坛网友Fillmore原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-04-02
  • 发表了主题帖: STM32串口唤醒STOP模式的实现

    前言 STM32常见的低功耗模式有三种:睡眠模式、STOP模式以及待机模式,STM32L系列还有其他低功耗模式。这里主要讲的是STOP模式,STOP模式可以通过外部中断或事件唤醒,但是不能通过串口中断唤醒,因为串口中断本身不是外部中断,那么如何才能实现串口唤醒STOP模式呢? 因为我这里只是为了做验证,为了快速验证,我也就没有用RT-Thread的PM电源管理组件进入STOP模式,感兴趣的读者可以用RT-Thread的电源管理组件去实现进行STOP模式。 一、为什么要串口唤醒STOP模式? 想象一下,在某些场合,如果你有一个无线通信模块(例如ESP8266、SIM800C)和STM32通过串口发送AT命令来对接服务器实现与服务器的数据交互,那么如果在没有进行数据交互的时候,我们是不是可以让STM32进入STOP模式来达到省电的状态,从而让电池续航更长。例如:STM32+ESP8266与后台服务器进行数据交互,当不用发送数据完毕,等待下次发送数据或等待后台下发数据给设备的这段时间可以让STM32进入STOP模式来达到省电,当后台服务器下发数据给设备的时候,我们可以向让后台发送一个唤醒设备的指令,ESP8266接收到后台的这条指令之后通过串口下发给STM32,那么就可以唤醒STM32了,这时候STM32就可以继续接收后台下发的数据。 二、串口唤醒STOP模式的思路 1、我们知道STOP模式只能外部中断或事件唤醒,那么想象一下,在STM32进行STOP模式之前,是不是可以先将UART_RX对应的GPIO引脚配置为外部中断引脚,而串口接收到字符相当于接收到01010...这样的高低电平,从二可以唤醒串口,当唤醒之后,我们再马上重新初始化串口,把UART_RX对应的GPIO引脚配置为接收中断模式?答案当然是可以的。 2、唤醒之后的程序是从哪里开始执行?答案是从进行STOP模式之前的那个地方重新开始执行,一会进行验证。 三、串口唤醒STOP模式实验 光说不练都是假把式,接下来进行实验。 1、实验平台:中国移动物联网OneNET NB开发板(板载STM32)。 2、STM32F103RET6、12M外部晶振、串口3进行实验。 3、操作系统:RT-Thread。 4、用RT-Thread创建两个线程,一个线程用于读取按键是否按下,按下则调用进入STOP模式函数进入STOP模式,另一个线程读取串口接收到的数据。 1、如何进行STOP模式? 实验时用的是标准库,在这里主要实现在进入STOP模式前将RX对应的GPIO引脚配置为外部中断模式以及进入STOP模式,代码如下: /************************************************************** 函数名称:system_enter_stop 函数功能:系统进入STOP模式 输入参数:无 返 回 值:无 备    注:无 **************************************************************/ void system_enter_stop(void) {         uart_exti_init(); /* 进入STOP模式前配置RX引脚为外部中断模式 */         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR , ENABLE); /* 开电源管理时钟 */         //PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI); /* 进入STOP模式,外部中断唤醒 */         PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE); /* 进入STOP模式,外部中断或事件唤醒 */ } 2、配置RX对应的GPIO引脚为外部中断模式 这里采用RT-Thread的PIN设备进行配置,在配置之前需要先关闭UART中断、复位UART、复位GPIO,然后在进行配置为外部中断模式,代码如下: /************************************************************** 函数名称:uart_exti_init 函数功能:RX引脚配置为外部中断 输入参数:无 返 回 值:无 备    注:无 **************************************************************/ void uart_exti_init(void) {         /* 关闭UART中断、复位UART、复位GPIO */         USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);         USART_Cmd(USART3, DISABLE);         GPIO_DeInit(GPIOB);         USART_DeInit(USART3);         /* 配置RX对应的GPIO引脚为外部中断模式 */         rt_pin_mode(PIN_UART3_RX, PIN_MODE_INPUT_PULLUP);         rt_pin_attach_irq(PIN_UART3_RX, PIN_IRQ_MODE_FALLING, uart_exti_callback, RT_NULL);         rt_pin_irq_enable(PIN_UART3_RX, PIN_IRQ_ENABLE); } 3、接收中断回调函数 在上面的配置中,有一个接收回调函数uart_exti_callback,就是在发送中断的时候要执行的事情,在接收回调函数里面,我们主要实现SystemInit,重新初始化串口,代码如下: /************************************************************** 函数名称:uart_exti_callback 函数功能:RX引脚外部中断唤醒回调函数 输入参数:args:回调函数入口参数 返 回 值:无 备    注:无 **************************************************************/ void uart_exti_callback(void *args) {         SystemInit();         uart_reinit();                /* 重新初始化串口 */         rt_kprintf("wake up\r\n"); } 4、进入STOP模式的线程 这里,创建一个线程来实现判断是否按键按下,按下则调用system_enter_stop函数进入STOP模式,同时为了验证唤醒之后时钟正常以及程序是从进行STOP模式之前的那个地方重新开始执行,我们设计LED灯500ms亮500ms灭,再一个计数变量,每隔1秒自动加1并打印,代码如下: static void sleep_thread_entry(void *parameter) {         unsigned char key;         unsigned int count=0;                 while(1)         {                 key = key_scan(0);                 if(key == KEY4_PRES)                 {                         rt_kprintf("system_enter_stop\r\n");                         system_enter_stop();                 }                 LED1(1);                 rt_thread_mdelay(500);                 LED1(0);                 rt_thread_mdelay(500);                 rt_kprintf("count:%d\r\n",count);                 count++;         } } 5、实验操作和现象 1、开机之后,LED闪烁,串口打印count每隔1秒加1的值,等待一小会按下按键KEY4进入STOP模式: https://img-blog.csdnimg.cn/20190327201706247.png FinSH抓取的串口打印信息 2、对比进入STOP模式前和STOP模式之后的电流情况(这里进入STOP模式之后电流还是很大是因为我们板子还接了其他耗电的模块,我们这对比电流有没有降下来就可以了),很明显,电流降下来了: https://img-blog.csdnimg.cn/20190327202004750.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NhbmpheV9XdQ==,size_16,color_FFFFFF,t_70 进入STOP模式前的电流 https://img-blog.csdnimg.cn/20190327202126303.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NhbmpheV9XdQ==,size_16,color_FFFFFF,t_70 进入STOP模式后的电流 3、通过串口发送一个字符“A”,唤醒了STM32,这时候串口并不会打印字符“A”,因为唤醒之后要重新初始化串口,第二次发送字符“A”才能显示,这时候,我们观察FinSH打印出来的信息,可以看到count是从9开始打印,说明STOP唤醒之后会从原来进入STOP模式之前的地方重新执行代码: https://img-blog.csdnimg.cn/20190327203059831.png 验证代码的执行情况 https://img-blog.csdnimg.cn/20190327203226307.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NhbmpheV9XdQ==,size_16,color_FFFFFF,t_70 唤醒之后第二次发一个字符能正常打印 4、接下来,我们再次按下KEY4重新然STM32进入STO模式,然后发送一个比较长的字符串来唤醒STM32,例如发“ABCDEFGHIJKLMNOPQ1234567890”,这时候,我们发现第一次发送之后,竟然会有字符出来,不是说没有吗?而且这些字符和我们发送的不一样,少了,第二次才正常: https://img-blog.csdnimg.cn/20190327203630102.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NhbmpheV9XdQ==,size_16,color_FFFFFF,t_70 唤醒之后打印字符不正常 四、串口唤醒存在的问题 1、上面我们提到,发送一个字符唤醒就很正常,而发送比较长的字符串唤醒却出现了不然正常的现象,这是为什么呢?想象一下m如果你是发一串很长的数据来唤醒串口,这串数据也是通过0101010等二进制来发送的,当RX引脚被触发中断唤醒MCU之后,唤醒之后串口初始化完成了,剩余的数据也就会接着以010101的高低电平发给STM32的串口,有可能导致有些字符的01丢失了一部分(例如上面出现了K567890),从而可以接下来的字符会打印出来。如果是发一个字符,一个字符的01010101其实也就8位,发送很快的,唤醒之后都已经发送结束了,所以就会直接唤醒,也就不会接收这个字符,只有第二次发送的时候才会接收到这个字符。

  • 发表了日志: STM32串口唤醒STOP模式的实现

  • 2019-03-25
  • 评论了课程: EEWORLD大学堂----RTOS培训最新版——15天入门RT-Thread内核

    Sunnl 发表于 2019-2-24 16:52 为什么系统空闲50歌OS Tick,空闲线程的钩子函数进入了100000次?
    并不是一个ostick才调用一次空闲线程喽,一个ostick的时间可以调用多次

  • 评论了课程: EEWORLD大学堂----RTOS培训最新版——15天入门RT-Thread内核

    yyy101314 发表于 2019-2-28 10:41 回复一下
    并不是一个ostick才调用一次空闲线程喽,一个ostick的时间可以调用多次

  • 加入了学习《新版RTOS教程:15天入门RT-Thread内核》,观看 初识RT-Thread

  • 2019-03-22
  • 回复了主题帖: 【第1天】从0-1跟我一起实战入门“RT-Thread_Nano 3.0.3 内核”

    EE大学堂 发表于 2019-3-22 16:12 感谢楼主的精彩分享,干货满满啊,借楼插播个视频教程分享: >>RT-thread在线培训 >>新版RTOS教程:1 ...
    嘿嘿 谢谢

  • 发布了课程: 新版RTOS教程:15天入门RT-Thread内核

  • 回复了主题帖: RT-Thread 的新书到手了,干货满满

    期待你的读书笔记

  • 回复了主题帖: 【读书月】读一本RT-Thread技术好书,写下你的读书笔记

    支持管管 之前也用过其他rtos  但是最喜欢RT-Thread了

  • 2019-03-06
  • 加入了学习《新版RTOS教程:15天入门RT-Thread内核》,观看 内存池的使用

  • 2019-03-05
  • 加入了学习《新版RTOS教程:15天入门RT-Thread内核》,观看 软件定时器的使用

  • 加入了学习《新版RTOS教程:15天入门RT-Thread内核》,观看 消息队列的使用

最近访客

< 1/2 >

统计信息

已有17人来访过

  • 芯币:74
  • 好友:--
  • 主题:13
  • 回复:14
  • 课时:--
  • 资源:1

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言