我爱下载

  • 2019-07-17
  • 加入了学习《DIY》,观看 编程玩具DIY

  • 2019-07-15
  • 回复了主题帖: DFRobot Arduino四路电机驱动板测评名单

    信息已确认,谢谢

  • 2019-05-27
  • 回复了主题帖: 有奖直播【基于TI Sitara™AM5708的工业派开源平台介绍】颁奖啦~

    谢谢网站和ti

  • 2019-05-15
  • 加入了学习《黑科技探头:碰一下就知电流大小(英文)》,观看 黑科技探头:碰一下就知电流大小(英文,国外网友评测)

  • 2019-05-13
  • 发表了主题帖: 【RT-Thread读书笔记】第二部分(5)中断管理和双向链表

    RTT系统使用中断与裸机使用中断相同,但是可以借助操作系统的内核IPC通讯机制,信号量、消息、事件标志组等标志事件,将中断和系统线程建立关联。双向链表是RTT贯彻始终的重要方法,本章节讲到了链表的使用,包括链表初始化rt_list_init(),向链表中插入节点rt_list_insert_after(),向链表指定节点前面插入节点rt_list_insert_before(),从链表中删除节点rt_list_remove()。 此内容由EEWORLD论坛网友我爱下载原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 发表了主题帖: 【RT-Thread读书笔记】第二部分(4)事件、软件定时器、内存管理

    1.   事件事件给我的感觉就是一个操作系统支持的标志位集合,平时编程时,我们都是弄个变量,如果有事发生了,把变量置1,然后在循环中扫描这个变量的状态然后作出相应的处理。很明显这种做法是非常浪费系统资源的,这也真说明操作系统下使用事件方式可以大大的提高系统的实时性。另外本章中强调了事件与信号量和消息队列的区别,非常重要:1)         事件仅用于同步,不提供数据传输功能(这个是与消息队列的不同);2)         事件无排队(这个是与信号量的不同);3)         允许多个线程对同一事件读写操作(优势);事件支持的函数包括:事件产生rt_enent_create(),事件删除rt_event_delete(),事件发送rt_event_send(),事件接收rt_event_recv()。 2.   软件定时器定时器是嵌入式系统中重要的部分,可以说,没有定时器的嵌入式系统是不可想象的。操作系统的软件定时器虽然没有硬件定时器准确,但是胜在数量和硬件定时器比起来可以说是无限了,所以还是非常有利的。本章中提到,软件定时器在使用的时候应该注意:1) 软件定时器的超时函数和硬件的中断响应函数差不多,要求快进快出,且绝对不可以在函数中使用延时,死循环,线程挂起或阻塞之类程序代码;2) 软件定时器和系统线程一样,也是有优先级的,他的优先级由RT_TIMER_THREAD_PRIO来指定;3) 软件定时器分为单次定时器和循环定时器,单次定时器在执行完超时函数后,系统会删除定时器回收资源;4) 定时器线程的堆栈由RT_TIMER_THREAD_STACK_SIZE指定,默认值为512字节。软件定时器的接口函数只有rt_timer_create()。 3.   内存管理对于一个操作系统,无论时实时操作系统,像RTT,还是一个复杂的操作系统,像linux,我觉得对于内存的管理都是极其重要的,虽然他们的内存管理方式存在重大差别,但是,内存管理都是操作系统必须面对的重要而复杂的问题。内存管理包括内存的初始化,分配及释放。本章中,我了解到,RTT系统支持的内存管理方式分为动态内存管理和静态内存管理,他们的主要特点是:1) 动态内存是在动态内存池中申请可变大小的内存;而静态内存是在静态内存池中分配初始化时固定大小的内存;2) 动态内存分配灵活,但静态内存分配和释放更高效;3) 动态内存可随机分配但会出现碎片,静态内存分配不灵活但不会出现碎片;4)根据运作机制,静态内存池中,内存是按照大小相同的内存粒块组织的,也就是说申请到的内存只能是内存粒块的整数倍;而动态存储时一块连续的内存,根据实际需要分配内存;5) 动态内存管理分为小内存管理模式和SLAB内存管理模式两种。6) 小内存管理模式采用内存块链表方式管理,每块内存都包含一个数据头,数据头由magic(幻数)和used(使用标志)组成。7) SLAB内存管理模式比较复杂,他的分配器根据对象的类型组织成很多区(zone)。一个区的大小为32K~128K之间,系统做多可以包括72种对象的区。静态内存的接口函数包括:rt_mp_create(),rt_mp_alloc(),rt_mp_free()。动态内存的接口函数包括:rt_system_heap_init(),rt_malloc(),rt_free()。 此内容由EEWORLD论坛网友我爱下载原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-05-08
  • 回复了主题帖: 【RT-Thread读书笔记】第二部分(3)信号量与互斥量

    部分内容来源于网络,但是对于信号量和互斥量的讲解我认为非常不错,所以一起作为学习笔记展现出来

  • 发表了主题帖: 【RT-Thread读书笔记】第二部分(3)信号量与互斥量

    本帖最后由 我爱下载 于 2019-5-8 11:42 编辑 这里将互斥量在一起学习,因为互斥量是一种特殊信号量。信号量也是RTOS中非常重要的内容,主要实现线程间通讯机制,线程同步或临界资源互斥访问。信号量分为二值信号量和计数信号量。基本接口函数包括信号量创建,信号量删除,信号量释放,信号量获取。这里值得注意的是二值信号量和互斥量的关系,因为他们非常相似。但是二值信号量在使用中会造成优先级翻转问题,因此互斥量应运而生,有效的解决了优先级翻转问题。下面解释一下他们的差异,这内容来源网络,我觉得写的听明白。假定我们现在有三个任务,task1,task2,task3,任务优先级task1最高,然后依次降低。我们知道在系统调度的时候当两个任务同时处于就绪态的时候,系统会优先执行优先级高的任务。好了,让我们来看两个案例:l  优先级翻转分析(使用信号量) 在例子中,我们使用pend()函数来表示获取信号量,用post()函数来表示释放信号量如上图所示,过程分下面几步1) 一开始task3开始运行,先获取到信号量;2) task1开始运行尝试去获取信号量失败被阻塞等待task3执行完;3) task3运行过程中,task2被触发,由于其优先级高于task3,task2被运行,浪费了大量时间;4) 继续运行task3,运行完后释放信号量;5) task1继续运行;看到这里我们可以得知,本应该优先级最高的task1结果居然是最后开始运行的,这就是优先级反转现象。这明显是不利的。比如如果有安装看门狗,task1在长时间没有得到执行,就会触发看门狗,导致系统的重启。 l  改进分析(使用互斥锁)   在例子中,我们使用lock()函数来表示获取互斥锁,用unlock()函数来表示释放互斥锁。如上图所示,过程分下面几步1) 一开始task3开始运行,先获取到互斥锁2) task1开始运行尝试去获取互斥锁失败被阻塞等待task3执行完,但是此时提升task3的优先级,让其优先级跟自己一样3) task3运行过程中,task2被触发,由于其优先级低于task3(第2步被提升过),task2等待运行4) 继续运行task3,运行完后释放互斥锁5) task1继续运行6) task1执行完,执行task2 所以过程跟前面的虽然一样,但是互斥锁多做了一个步骤就是将task3的优先级提升到task1的级别,防止task2中途出来搅局浪费大量时间。其中信号量和互斥量关系的对比部分来源于网络。 此内容由EEWORLD论坛网友我爱下载原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-05-06
  • 发表了主题帖: 【RT-Thread读书笔记】第二部分(2)消息队列和邮箱

    本帖最后由 我爱下载 于 2019-5-6 10:59 编辑 这里将消息队列和邮箱一起来看,时因为他们的机制都是差不多的,唯一的不同是他们所携带的内容规模由差别。消息队列和邮箱的对比:    1)   消息队列所携带消息的规模不定,根据需要可以很大,也可以很小,而邮箱固定为4字节的负载;因此书中介绍,邮箱是一种比较高效的的信息传递方式。    2)   他们都是常用IPC通讯方式,可以应用于线程间,中断和线程间的通讯。    3)   中断内都可以发送信息,但不能接收;消息队列在操作系统中作为灵活快速消息传递的一个缓冲区,传递内容比较灵活。第18章内容中重点体现了消息队列的阻塞机制,实现方式,以及应用方法。关于消息队列,值得关注的地方个人认为:   1)   应用场景:主要用于发送不定长消息的场合,包括线程间消息交换,中断服务程序中消息发送(特别提出中断中不能采用消息接收);   2)   在使用rt_ma_recv(),rt_mq_send(),rt_mq_delete()等函数时,必须首先创建消息队列,并根据队列句柄进行操作。   3)   队列可以采用FIFO模式,同时提供了紧急消息机制,可以提高系统实时性。   4)   在执行rt_mq_recv()函数时,必须首先申请消息存储的缓冲区,并将首地址作为参数传递给函数,否则将出现地址非法错误。   5)   接收消息时候,用于存储消息的缓冲区大小必须大于等消息队列中的消息大小。邮箱在操作系统中作为高效快速信息传递,体现出了邮箱的灵活和高效。第23章内容中重点体现了邮箱运行机制,实现方式,以及应用技巧。关于邮箱,值得关注的地方:   1)   应用场景:主要用于固定信息(4字节)传递的场合,包括线程间,中断服务程序中;   2)   在使用rt_mb_recv(),rt_mb_send_wait(),rt_mb_send (),rt_mb_delete()等函数时,必须首先创建邮箱rt_mb_create(),并根据邮箱句柄进行操作。   3)   邮箱可以采用FIFO模式,或优先级排队模式,支持异步读写工作方式。   4)   收发邮件均支持超时处理。   5)   支持一对多或多对一的操作方式。   6)   书中特殊提到了邮箱的使用技巧,虽然邮箱的负载只能是4字节,但是在stm32等32为系统上,刚好可以传递一个32位的指针信息,因此扩展了邮箱的传递内容,而且依然高效。 此内容由EEWORLD论坛网友我爱下载原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-04-29
  • 发表了主题帖: 【RT-Thread读书笔记】第二部分(1)移植,运行及线程管理

    第二部分(1)主要学习了13-17章的内容 1.   移植RT-Thread到STM32,并创建线程为什么两章一起来呢,因为单独移植一章任何表现没有,知道RTT已经运行,但是却看不到led的闪烁,不知道系统是否真的运行了.按照书中的过程,非常顺利的完成RTT nano移植的过程.如下为思维导图.经过实际代码验证,RTT Nano确实运行了,led灯闪烁正常.这里硬件采用野火的秉火STM32F407核心板为基础完成的软件验证工作。2.   RTT的启动流程在RTT的启动流程一章中,作者介绍了两种启动流程: 万事俱备,只欠东风式和小心翼翼,十分谨慎式两种,RTT采用的是后一种.由于我们采用KEIL 完成RTT的整体过程,这里还提到了一个技术,函数扩展技术即:$Sub$$和$Super$$两个符号,并且扩展的是main函数.这两个符号成对使用,$Sub$$为函数的扩展函数,$Super$$返回原函数.3.   线程管理 RTT中的线程,给我的感觉就是我们常用RTOS中的任务,个人理解就是一个意思。线程分为多个状态:初始态,就绪态,运行态,挂起态,关闭态。这些状态直接是可以发生转换的,这个转换关系我觉得比较重要。 此内容由EEWORLD论坛网友我爱下载原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-04-25
  • 发表了主题帖: 【RT-Thread读书笔记】第一部分 内核简单原理

    RT-Thread读书笔记第一部分RT-Thread作为国产的物联网系统,改变了国人没有一款适合自己的国产物联网操作系统的现状。经过十几年的完善,我们才能看到这样一版强大的操作系统,才有我们目前读这本书的必要。本人虽然常年从事嵌入式系统的研发工作,但是一直没想过一个真正的操作系统是如何诞生的,也没有想过如果让我去写一个操作系统我要怎么做;看了《RT-Thread内核实现与应用开发实战指南》,终于了解了RT-Thread到底是如何从无到有,如何完成任务调度,如何完成任务创建等一些列问题,对于深入理解操作系统,更好的使用操作系统无疑有着深刻的帮助。1.   构建基本系统操作系统的出现是为了改变轮巡式和前后台式程序结构,更加充分利用CPU的计算和执行能力而来了,根据书中的介绍,让我知道了多任务操作系统和原有程序执行方式的差别。一个可以运行的基本系统我觉得应该包口,线程的创建,链表,堆栈管理,可运作的调度器。这里我有几个问题提出,不知道原理:1)   任务切换的基本方式是在中断中,将就绪的高优先级任务堆栈恢复到系统寄存器中,并让其运行的过程,那么哪些寄存器是应该在上下文切换过程中保存起来的,和需要恢复的;2)   中断时候,不论是什么单片机都回保护现场,将一部分寄存器压入堆栈,如何确定哪些是自动压入堆栈的,哪些是需要我们后来手动压入堆栈的;通过前9章的学习,我深刻的感悟到了对于一个操作系统,哪怕是最小的操作系统,都有些非常关键的地方:1)   如何管理就绪任务列表,rtt是通过链表来完成的,也就是说,链表管理是rtt任务调度的一个重要组成部分,也是不同操作系统管理的不同地方;2)   任务或线程切换的方式,rtt中是在PendSV_Handler异常中断中完成;3)   任务切换的真谛就是保存正在运行的任务相关寄存器到任务堆栈中,切换高优先级就绪任务的堆栈内容进入寄存器中,并恢复系统运行;4)   临界代码保护。进入临界段前通过关闭中断的方式来帮助保证临界代码的可靠性,退出临界代码时候恢复中断不是随意的,不能直接打开中断,应该根据进入临界代码前系统中断状态来决定,以防导致错误的打开中断使临界代码不能得到可靠的保证;5)   通过SysTick定时中断完成系统定时,使线程阻塞延时得以实现。2.   多任务的支持与之前的多任务不同,现在的多任务开始支持优先级了,采用的方式为线程就绪优先级组和线程优先级表。这两个概念在我的理解中应该是:1)   优先级组用来告诉系统哪些任务处于READY状态,并且可以按照一定的顺序给各个正在执行的线程状态排队;2)   优先级表和优先级组配合,获取各个正在执行的线程的具体信息。书中同时讲到了为了适合优先级机制对于软件的调整。3.   定时器的实现定时器是非常重要的内容,而多任务系统的定时器可以说是一个更加重要的存在。所有线程级别延时都离不开它。书中将原有延时的处理方式做了调整,推广到了更加广泛的方式下实现定时器。那就是:采用全局的系统定时器列表,当线程延时时,把延时线程挂起,并将线程内定时器挂在系统定时器维护的双向链表内,并按照延时时间从小到大排序,通过SystemTick中对于链表中所有定时器的扫描,判断延时时间到达的线程定时器,并执行定时器的回调函数,将对应的线程添加到任务就绪表中,完成延时到唤醒的过程。书中提到了具体的程序改动方法。4.   时间片轮转以前在使用RTOS时候经常听到这个名词,但是都不是深刻的了解时间片到底是如何轮转的,通过阅读第12章《支持时间片》后,我终于明白RTT是如何实现时间片轮转的。这里面有几个地方我觉得是关键的:1)   赋予线程时间片时间的概念;2)   在时基更新函数中,利用双向就绪线程链表剔出时间片耗尽的线程,将其添加到本优先级链表尾部,同时将本优先级下一个线程添加到就绪列表中;3)   对于没有时间片轮转的人物,执行的时间片时间不确定。 此内容由EEWORLD论坛网友我爱下载原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-04-09
  • 回复了主题帖: 【书籍已全部寄出】【读书月】读RT-THREAD技术好书活动入选名单公布

    获得了读书的机会,感谢。信息确认

  • 2019-03-20
  • 回复了主题帖: hi,小伙伴们!这里有棵测评许愿树

    树莓派3

  • 回复了主题帖: ucosIII中文翻译

    多谢楼主无私奉献

  • 2019-01-02
  • 回复了主题帖: 助力EEWorld 19成长计划,赢取精美好礼!

    “我要助力EEWorld 19成长计划” 助力EEWorld成长目标任务: 连续一个月活跃在论坛(活跃行为包括:发帖,回帖,日志,发表心情,添加好友,好友互动,分享文章,参加活动,上传下载资源,发布和观看视频等系列行为)

  • 2018-11-30
  • 加入了学习《泰克MSO5示波器拆机视频》,观看 泰克MSO5示波器拆机视频

  • 2018-11-29
  • 回复了主题帖: 【颁奖】新驱动力MM32开发板测评活动

    信息已经确认,无误。 谢谢论坛和新驱动力组织的活动。

  • 2018-10-22
  • 发表了主题帖: 新驱动力MM32F031开发板评测:外设PWM和UART的使用

    本帖最后由 我爱下载 于 2018-10-22 13:45 编辑 外设单元pwm和uart的使用评测 测试pwm和uart外设单元,程序依据例程中TIM的PWM例程修改得到,评测主要内容为Uart作为标准输入输出外设接受用户的控制命令,打印程序运行状态,控制pwm按照设计要求改变占空比。Pwm设计为10KHz固定频率可变占空比方式输出,利用TIM3输出端子为PB4,占空比调整范围0%~100%。 对PWM初始化的理解: 对UART的修改: 在官方代码的基础上增加了输入获取功能,支持kbhit()和getchar() 添加如下代码://重定向fgetc函数 int fgetc(FILE*f) {          while((UART1->CSR&UART_IT_RXIEN)==0);     return (UART1->RDR & 0x00ff); } int kbhit(void) {     if((UART1->CSR&UART_IT_RXIEN)==0)               return 0;        else return 1; } 复制代码 主程序代码的修改: while(1)           {               ledflushcount++;               if(ledflushcount >= 100000)               {                      ledflushcount = 0;                      D2_TOGGLE();               }               if(kbhit())               {                      key = getchar();                      switch(key)                      {                             case 'a':                                {                                    if(led0pwmval < 100)                                           led0pwmval += 10;                                    pwmtarget = PWM_PERCEND(led0pwmval);                             }                             break;                             case 's':                             {                                    if(led0pwmval >= 10)                                           led0pwmval -= 10;                                    pwmtarget = PWM_PERCEND(led0pwmval);                             }                             break;                      }                      printf("PWM PER = %d %%\n", led0pwmval);                                     }               if(pwmtarget != pwmcurrent)               {                      if(pwmtarget > pwmcurrent)                             pwmcurrent++;                      else if(pwmtarget < pwmcurrent)                             pwmcurrent--;                      TIM_SetCompare1(TIM3, pwmcurrent);                    }     }       复制代码 执行效果: 通过不断的调大和调小占空比,红色小灯的亮度随着变亮和变暗。 此内容由EEWORLD论坛网友我爱下载原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2018-10-19
  • 加入了学习《电力电子技术》,观看 逆变失败及其抑制办法

  • 加入了学习《电力电子技术》,观看 整流电路的有源逆变工作状态分析

最近访客

< 1/3 >

统计信息

已有182人来访过

  • 芯币:850
  • 好友:3
  • 主题:24
  • 回复:166
  • 课时:--
  • 资源:1

留言

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


现在还没有留言