单片机中的printf思考

问题:

1. printf自带的库编译出来的大小比较大(flash吃紧)

2. printf是一个不定长参数, 意味着函数无法知道传入的长度. 解决这个问题有2中方法:1.设置足够大小的数组作为参数存储; 2. 使用动态内存分配的方式来做(应该使用的是这个方式).(内存吃紧)

问题解释:

1. 之前写裸机的时候从来没思考过printf问题, 因为写裸机的时候一般printf只是打印调试的时候日志, 打印完成后会关闭打印功能.因此在裸机中, 并且会关闭打印的时候这个还是可以使用的.

2. 大家应该也发现了,没人在51单片计算串口重定向,然后调用系统的printf吧, 就是库函数消耗内存和flash

 在实时系统中, 系统自带的printf那就问题更多了:

        1. 函数重入的问题, 也许有人会说我使用实时系统的互斥, 临界区保护等,当然没问题.

        2. 其次我们知道实时系统中, 所有函数的开销是设定堆栈大小的, 如果是系统库用一个足够大的数组作为数据存储, 意味着堆栈会爆掉, 程序跑飞(系统中应该不会用这么傻的方法). 那如果是使用动态内存分配的方法, 那么这也将是一个不定时炸弹.为啥说是不定时炸弹呢? 因为printf必定调用的是系统malloc, 意味着可能会出现内存碎片.到时候可能申请不到内存, 打印功能就可能失效了.

   

问题解决:

        由于我们公司的产品是工业产品, 用到了很多打印, 如果调用系统printf, 程序崩溃真的很难查.因此解决方法就是自己实现printf(我们的printf源码是从linux内核抄过来的).    

        而实际上, printf是通过snprintf封装来的, 我们定义了一个静态数组来存储printf要打印的内容,,用snprintf打印里面的内容,  这样多线程中的每个线程的堆栈就只提供给任务使用.避免堆栈溢出照成的程序崩溃.(当然也可以用系统提供的snprintf替代自己实现的snprintf, 可能编译代码多点, 但不会出现不可靠的问题)

        公司的项目代码的打印只对输出到串口进行了保护, 将数据复制到静态数组并没保护, 但是打印出来并没有出现数据乱码.

        代码使用的ucos2, 可以在中断打印, 但是打印内部是关中断了, 至少我知道freertos中任务关中断和中断关中断是不一样的, 没学过ucos2, 可能是它自己特性, 本身可以做到.

        细细推敲下来, 发现一个小小的printf都有各种问题, 何况自己写的bug呢, 虽然公司的代码让我看的不爽, 但确实稳定,.

相关推荐

  1. 单片机printf思考

    2023-12-09 23:28:04       37 阅读
  2. Go语言Print Printf Println区别

    2023-12-09 23:28:04       34 阅读
  3. pythonprint函数用法

    2023-12-09 23:28:04       34 阅读
  4. printf

    2023-12-09 23:28:04       30 阅读
  5. Unity控制帧率思考

    2023-12-09 23:28:04       20 阅读
  6. 平移矩阵数学思考

    2023-12-09 23:28:04       8 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-09 23:28:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-09 23:28:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-09 23:28:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-09 23:28:04       20 阅读

热门阅读

  1. 分享一个用C#写的Aspose.Words生成word的工具类

    2023-12-09 23:28:04       31 阅读
  2. c语言编程题经典100例——(90~95例)

    2023-12-09 23:28:04       34 阅读
  3. [动态规划]最长公共子序列

    2023-12-09 23:28:04       31 阅读
  4. 从Android源码中生成系统签名文件

    2023-12-09 23:28:04       37 阅读
  5. 面向无组织点云中快速鲁棒的边缘提取方法

    2023-12-09 23:28:04       31 阅读
  6. 考研真题数据结构

    2023-12-09 23:28:04       32 阅读
  7. Centos7安装docker支持NVIDIA GPU

    2023-12-09 23:28:04       30 阅读
  8. 反向传播算法

    2023-12-09 23:28:04       34 阅读
  9. 《C++新经典设计模式》之第18章 备忘录模式

    2023-12-09 23:28:04       37 阅读
  10. 考研真题数据结构

    2023-12-09 23:28:04       37 阅读
  11. 数据科学:Scipy、Scikit-Learn笔记

    2023-12-09 23:28:04       33 阅读
  12. Kotlin关键字二——constructor和init

    2023-12-09 23:28:04       44 阅读
  13. python中星号(*)的作用

    2023-12-09 23:28:04       41 阅读
  14. F. Maximum White Subtree

    2023-12-09 23:28:04       32 阅读