个人资料
归档
正文

OS-RTOS

(2022-03-20 22:31:32) 下一个

1. Kernel

1.1 编译安装5.9.6 on Ubuntu

https://phoenixnap.com/kb/build-linux-kernel 需要的改动:

1.UEFI BIOS, secure boot要禁止,不然报linux kernel: invalid signature, you need to load the kernel first’,可也自己生成signature:https://help.univention.com/t/problem-booting-server-shows-invalid-signature-you-need-to-load-the-kernel-first/13557 
2.改.config两行,去掉找不到的debian license,去debug以减小尺寸,改后为:
CONFIG_SYSTEM_TRUSTED_KEYS=""
CONFIG_DEBUG_INFO_BTF=n
3.生成的initrd.img需要strip剪裁,不然启动时装入kernel后停在initrd.img处,办法是
https://unix.stackexchange.com/questions/270390/how-to-reduce-the-size-of-the-initrd-when-compiling-your-kernel 
cd /lib/modules/
find . -name *.ko -exec strip --strip-unneeded {} +
cd
sudo make install

1.2 编译安装5.13.1 on Ubuntu

sudo apt update && sudo apt upgrade
sudo reboot
sudo apt install build-essential libncurses5-dev fakeroot xz-utils libelf-dev flex bison libssl-dev dwarves zstd 
cd ~/Downloads
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.13.1.tar.xz
tar xf linux-5.13.1.tar.xz
cd linux-5.13
sudo find /boot/ ( -iname "*config*" -a -iname "*`uname -r`*" ) -exec cp -i -t ./ {} ;
mv *`uname -r`* .config
ls /boot | grep config
sudo gedit .config &
==comment out: #CONFIG_SYSTEM_TRUSTED_KEYS, #CONFIG_SYSTEM_REVOCATION_KEYS, 
==enable: CONFIG_PCIEPORTBUS=y, CONFIG_PCIEAER=y, CONFIG_PCIEAER_INJECT=y, CONFIG_PCIE_ECRC=y, 
sudo make menuconfig
sudo make -j 8
sudo make bzImage -j 8
sudo make modules_install
sudo make install
cd /lib/modules/5.13.1
sudo find . -name *.ko -exec strip --strip-unneeded {} +
sudo update-initramfs -c -k 5.13.1
sudo update-grub
sudo reboot
uname -mrs

若见"cannot represent change to vmlinux-gdb.py",直接删除该文件再编译。最新的5.15.35也同样编译安装。

1.3 remove kernel

https://phoenixnap.com/kb/ubuntu-remove-old-kernels 

2 .Zhphyr RTOS
Zhphyr文档:https://docs.zephyrproject.org/2.7.0/zephyr.pdf?  https://docs.zephyrproject.org/latest/   
Zephyr on ESP32: https://www.zephyrproject.org/zephyr-rtos-on-esp32/ 
2.0 west:https://docs.zephyrproject.org/latest/boards/xtensa/esp32/doc/index.html  需要运行west init才能运行
west espressif update
2.1 install Zephyr
https://docs.zephyrproject.org/latest/getting_started/index.html?upgrade  stc:  https://askubuntu.com/questions/1090223/how-to-upgrade-dtc-version-in-ubuntu-18-04   

https://docs.zephyrproject.org/latest/getting_started/index.html 装Zephyr,编译前要加装 pip3 install pyelftools 不然出错:

cd ~/zephyrproject/zephyr
west build -p auto -b arduino_nano samples/basic/blinky 

起步还可以读:https://www.zephyrproject.org/blinking-an-led-with-zephyr-rtos-creating-an-application/ 

2.2 install ESP32 tool chain

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/linux-macos-setup.html#get-started-prerequisites? 
在Connect your device一节,Linux下可用dmesh | grep /dev/ttyUSB*确定插入的串口号。

装ESPRESSIF: https://docs.espressif.com/projects/esp-idf/en/v4.2/esp32/get-started/index.html#get-started-get-prerequisites 在configure之前要加装:
sudo apt install python-pip;pip install click 
另一错误多半是缺省用了Python2,去掉改用Python3的办法是:
sudo apt purge -y python2.7-minimal
sudo ln -s /usr/bin/python3 /usr/bin/python
sudo apt install -y python3-pip
sudo ln -s /usr/bin/pip3 /usr/bin/pip
python --version

错误在menuconfig失败,找不到不到支持bidict>=0.21.0的模块,最后将Ubuntu升级到20.04按此文装成功:https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/linux-macos-setup.html#get-started-prerequisites 编译用idf.py

2.3 不匹配

至此,Zephyr和ESP32各自的工具都就绪,可是Zephyr编译ESP32不是用ESP32的工具链,因此我按https://www.zephyrproject.org/zephyr-rtos-on-esp32/  装后,编译时才发现Zephyr version: 3.0.99是,cmake需3.20,west需0.7.1,dtc需1.5.0,似乎是官网要求的:https://docs.zephyrproject.org/latest/getting_started/index.html

换句话无论按哪个指南做,其中部分软件更新后,都可导致失败。按官网发现sdk是0.14而非0.12,又是个耗时的过程。最后编译错误出在

1)-- Found west (found suitable version "0.12.0", minimum required is "0.7.1")
2)-- Found dtc: /usr/bin/dtc (found suitable version "1.5.0", minimum required is "1.4.6")
3)CMake Error at /home/jodai/zephyrproject/zephyr/cmake/toolchain/espressif/generic.cmake:52 (message):
  Unable to find toolchain in
  /home/jodai/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf
错误3最重要,看Cmake可知它产生的工具链是: ~/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf而实际的是:~/.espressif/tools/zephyr/xtensa-esp32-elf/xtensa-esp32-elf,换句话工具链要由github下指定版本。

2.3 nRF52840-MDK
支持 Bluetooth 5、Bluetooth Mesh、Thread、IEEE 802.15.4、ANT 等无线协议,带有片上 Arm CryptoCell 加密子系统,集成了多功能调试器 Arm Mbed DAPLink,提供“拖放式”下载固件、USB CDC 虚拟串口、CMSIS-DAP 仿真等功能。板载Microchip 两端口 USB 2.0 高速集线器,只需一个 USB 接口即可同时使用 DAPLink 和 nRF52840 的 USB 设备控制器;有64Mbit 超低功耗 QSPI FLASH、可编程按键、RGB LED、晶片天线及外部天线连接器等硬件资源。

nRF52840-MDK 支持Zephyr框架,跨平台开发,可以玩转多种开源软件框架(如:nRF5 SDK, Mesh, OpenThread, ZigBee 3.0, Mbed OS 5, Zephyr, Mynewt, iBeacon, Eddystone, Web Bluetooth 等等),提供丰富的在线文档及示例,帮助加速物联网应用开发。https://bbs.huaweicloud.com/blogs/163505 

中肯提醒:如果您是 MCU 世界的新手且功耗不是大问题,请选择 ESP32。 Nordic 的东西(比如这个板子)更适合实际的生产绑定产品开发和原型设计,更加健壮和灵活,但根据我的经验,IDE 并不直观,支持库也不那么广泛。 我只向有经验的用户或快速学习者推荐这个产品。 如果您知道自己在做什么,这是一个很棒的产品,并且比官方的 Nordic nRF 开发板小得多,后者是无用的巨大。直观的 arduino IDE 更好地支持相同外形尺寸的 esp32 板,并具有广泛的支持库、示例代码示例和庞大的社区来提供帮助。

Zephyr用了类似Linux的menuconfig,Intel曾在开始时很热心,现在是NXP。缺点是比较复杂,样本多是板子厂家提供通用性一般,感觉工具出问题比较麻烦不如make直接给出原因。arduino IDE就太简洁直观了。所用版本备忘:

$ cmake --version
cmake version 3.23.0
$ python3 --version
Python 3.8.10
$ dtc --version
Version: DTC 1.5.0
$ west --version
West version: v0.12.0
~/zephyrproject/zephyr$ west build -p auto -b esp32 samples/basic/blinky
https://github.com/espressif/crosstool-NG/releases

3. FreeRTOS

https://github.com/freertos?  https://zhuanlan.zhihu.com/p/145699420  https://blog.csdn.net/Chuangke_Andy/article/details/115397230 官网的18f452代码不能编译:1)所有源码是同一目录上载到官网变成多级目录 2)XIDE加include路径无效 3)核心已经修改不配套 4)原编译器用PICC与XC8不兼容,XC8声称的#asm也不能用,asm()可用。新片PIC18F26/46/56Q43为28/40/44/48pin,PIC18F26Q43-I/SP $2.08,PIC18F45Q43T-I/PT $1.7, PIC18F4550T-I/PT $7.91:
18F4550T-I/PT  TQFP44,10x10 2.0-5.5V 32K 2KB-DRAM 256B-EEPROM 48MHz I/O-35 UART/I2C/SPI 10bx13chAD no-DAC  USB2.0
18F45Q43T-I/PT TQFP48,7x7   1.8-5.5V 32K 2KB-DRAM  1KB-EEPROM 64MHz I/O-36 +I2S+PWM     12bx35chAD 8bx1ch no-USB
18F45K50-I/P   DIP40        2.3-5.5V $2.08 32K 2KB-DRAM 256B-EEPROM 48MHz I/O-35 UART/I2C/SPI 10bx13chAD 5bx1ch USB2.0

https://github.com/tahaemara/MicroRTOS-for-PIC-18F-Family PIC18F4550用mikroc PRO for PIC编译。https://www.youtube.com/watch?v=hYynOanPZWU 使用T0时钟延迟和软件堆栈。uP初始化栈指针STKPTR为0,TOSU:TOSH:TOSL存有当前栈指针STKPTR的内容24bit,操作栈时需禁止GIE。STKOVF/STKUNF为上溢/下溢标志。上溢时若STVREN置位将中断,否则栈顶0x7F内容被重写;但是人工设置STVREN不会中断。STKUNF同理。新品F45K50:1) Have lesser flash write cycles
2) Needs no crystal for USB. built in oscillator works up to 16 MHz.
3) Oscillator configuration, config bits are slightly different.
4) Has a 5-bit DAC and CTMU peripheral for capacitive sensing.
5) might not supported by free mcc18 compilers
6) not supported by PICkit2 (non-official device file supports this)
7) LPT1OSC config bit not available on the K part.

https://github.com/FreeRTOS/FreeRTOS/releases 

以前就说过,Pic因为时间长芯片程序会丢,现有用Pic的产品需重编程,否则不要用。ESP32价廉物美可覆盖多数嵌入式,但是基于ARM的板子也很多。我用Arduino IDE试了ESP32版本的FreeRTOS-因为CPU是双核,很好用很容易,如果sample code夹杂了其它CPU的.h文件需要改造。

3.1 FreeRTOS的学习笔记

https://freertos.org/Documentation/161204_Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide.pdf 
FreeRTOS 
 └─Source 
       ├─tasks.c               FreeRTOS source file - always required
       ├─list.c                   FreeRTOS source file - always required
       ├─queue.c              FreeRTOS source file - nearly always required
       ├─timers.c              FreeRTOS source file - optional
       ├─event_groups.c  FreeRTOS source file - optional
       └─Portable

            ├─[compiler]/[architecture]         All C/asm files
            └─MemMang
                   └─heap_?.c                         heap_?.c, ?=1-5, heap files               

目前v10,由v9开始无需heap manager,有5个heap?.c可选:1适用于任务创建后无需删除,没有回收的环境;3类似传统malloc/free但有线程安全性且忽略
TOTAL_HEAP_SIZE;4是2的增强,会把释放的相连的缓冲池合并;5用于缓冲池不连续的环境需要配置。函数是pvPortMalloc() 和vPortFree(),也有统计函数xPortGetFreeHeapSize()(unit in bytes)和configTOTAL_HEAP_SIZE定义堆的大小单位是栈宽,如64bit则为64bit。FreeRTOS中,函数前缀v返回void,x返回变量,pv返回void指针,pd是常量。注意ESP32的RAM类型多,官网另有heap说明。注意在原版Vanilla FreeRTOS中uxTaskGetStackHighWaterMark返回Dword长度而在ESP-IDF中返回Byte长度,是堆栈空余最小值。https://www.youtube.com/watch?v=Qske3yZRW5I#t=10m38s? 

配置文件是FreeRTOS/Source/include/FreeRTOSConfig.h,缺省配置的tick是10ms(可改为1ms)是所有延迟的最小单位,延迟时间用pdMS_TO_TICKS()转为tick,延迟函数是vTaskDelay()和vTaskDelayUntil(),后者是定周期的任务执行。如果不用系统延迟函数,较低优先级的任务将被堵塞。FreeRTOS配置configUSE_PREEMPTION和configUSE_TIME_SLICING可为抢占式或合作(轮转)式,通常两者都置1。任务是一个死循环的函数或进程,其堆栈和变量均在其heap中,由主程序中的vTaskStartScheduler系统调度将其在条件满足时投入运行,这些条件包括端口或定时中断、各种信号量等。任务相关函数有:xTaskCreate、xTaskCreateStatic、vTaskPrioritySet、uxTaskPriorityGet、vTaskDelete()。任务状态有:running、ready、blocked、suspended四种状态。任务优先级通常是0-31。最低为0是系统idle任务专用,idle任务实现一些系统统计功能,可用vApplicationIdleHook添加用户任务,如将系统置于低功耗,此时configUSE_IDLE_HOOK需为1。

Queue队列是一个FIFO先进先出的数据区,但数据的拷贝也可以取消或重写,任何任务均可访问。通常用于任务间通信,也可用于任务与中断服务程序的通信。在任务等待队列数据时会进入blocked态。可能会有多个任务因等待数据而进入blocked;一旦数据到来,只有最高优先级或等待最久的任务会被激活。 同样,可能会有多个写任务因队列满处于blocked,待可写入时只有一个被激活,但写入操作可指定最大等待时延。Queue由 xQueueCreateStatic() 或 xQueueCreateStatic()创建并返回handle;由xQueueSendToBack()和xQueueSendToFront()写入,或xQueueSendToFrontFromISR()和xQueueSendToBackFromISR();读是xQueueReceive()。Queue的内容可以是任何数据结构。
TCP TCP/IP stack包的例子:从网络接收的数据通过结构IPStackEvent_t的发送到TCP/IP任务,结构中的eEventType设置为eNetworkRxEvent,而pvData 指向包含接收数据的缓冲区;根据eEventType来处理各类事件/数据。
如果必须用多个Queue来处理数据,可以把它们放入Queue Set队列集中,而无需逐个判断是否有数据待处理,并可捆绑Semaphores信号灯。这是通过将configUSE_QUEUE_SETS置1和xQueueCreateSet、xQueueAddToSet来实现的。然后用xQueueSelectFromSet先取得有数据的Queue Handle或SemaphoreHandle_t handle,比较其名后用xQueueReceive或xSemaphoreTake做相应处理。

mail box在此是长度为1的Queue。Queue通常为另一个任务或中断服务程序提供数据,后者则取出数据;mailbox不同的是它的写xQueueOverwrite是覆盖性的;数据可为任何任务或中断服务程序通过xQueuePeek来读但并不取出,用户代码可用返回pdTRUE来表明新数据,否则pdFALSE。

软件计时器用于以固定频率周期或在未来设定时刻执行程序,籍由其ATimerCallback回调函数实现。这是可选的,需要configUSE_TIMERS置1并包括FreeRTOS/Source/timers.c。回调函数不能被blocked,因此不能调用API、vTaskDelay或xTicksToWait不为0的xQueueReceive。Software Timer由xTimerCreateStatic或xTimerCreate创建,相关函数有xTimerStart/Stop/Reset/ChangePeriod等。它可以是One shot或Auto-reload,有Dormant休眠和Running运行两种状态,Timer service或称RTOS daemon任务自动运行并由configTIMER_TASK_PRIORITY和configTIMER_TASK_STACK_DEPTH配置,API通过timer command queue给它下达命令,队列长度是configTIMER_QUEUE_LENGTH。每个Timer可通过vTimerSetTimerID()设置ID,由pvTimerGetTimerID()直接读取,不通过命令队列。xTimerChangePeriod可以改变定时,例如在CheckTasksAreRunningWithoutError返回错误后。

中断服务调用的API函数(*fromISR)导致更高优先级任务应当被换入时,FreeRTOS设计为在中断内不做自动切换,但可通过portYIELD_FROM_ISR()或portEND_SWITCHING_ISR()来切换,两者功能相同,都是taskYIELD()的可在中断内使用的的版本,有的只移植其一。调用的参数是pxHigherPriorityTaskWoken,它应初始化为pdFALSE,在发生上述情况下被RTOS置为pdTRUE。如果初始化为NULL则禁止其功能。极少数移植只允许portYIELD_FROM_ISR()在终端服务程序的最后使用。
Deferred Interrupt Processing是指尽可能的把中断服务的功能放在服务程序之外的任务中,以减小中断开销和使用更多的API功能,该任务的优先级通常高于其它任务,用xSemaphoreCreateBinary创建且调用xSemaphoreTake()使自己挂起。在中断服务程序中调用xSemaphoreGiveFromISR()给该任务、开中断后调用portYIELD_FROM_ISR(),将直接切换到该任务。这种semaphore的用法与常规不同-不给还,更像是长度为1的Queue。vPortGenerateSimulatedInterrupt()可用于中断仿真。
centralized deferred interrupt processing是指用xTimerPendFunctionCallFromISR()延迟中断处理给RTOS Daemon守护程序,避免每个中断都要一个外处理任务;该函数的中断不安全版是xTimerPendFunctionCall。许多API函数有中断安全版(fromISR),例如Queue读写函数。
嵌套的中断需要配置,注意Cortex-M的中断是数字越小优先级越高,可以用Assert使得FreeRTOS检测。


资源管理任务在访问不可重入且非线程安全的共享资源时,需要独占访问权直至资源到一致状态。用于例如对非原子的读-修改-写代码用Mutex以免被打断,或在打印字符行时不会被插入其它字符串,两者均可用宏调用taskENTER_CRITICAL()和taskEXIT_CRITICAL()来包围,称为基本临界区。在中断中临界区可用uxSavedIntruptStatus = taskENTER_CRITICAL_FROM_ISR();和taskEXIT_CRITICAL_FROM_ISR(uxSavedIntrStatus);来包围。另一对可以使用的函数是vTaskSuspendAll和xTaskResumeAll。
binary semaphore通常用于事件同步或延迟的中断处理,counting semaphore通常用于事件或资源计数。常规的它是0~N之间的变量;但在FreeRTOS中是长度为N内容不论的Queue。它由configUSE_COUNTING_SEMAPHORES置1使能,用xSemaphoreCreateCounting创建,多次调用xSemaphoreGiveFromISR可以设置大于1的值。
mutual exclusion(Mutex)
互斥锁与之类似,常用于任务中来独占被多个任务共享的资源。Mutex可理解为token,获得它的任务独享资源,用后必须交回;而binary semaphore多用于事件同步,获得后不必交回多被丢弃。由configUSE_MUTEXES使能,xSemaphoreCreateMutex创建,仍用xSemaphoreTake和xSemaphoreGive来获得和交回。低优先级的任务能因获得Mutex而导致高优先级的任务被blocked,直至Mutex被释放,这被称为Priority inversion优先级反转。由于低优先级的任务不被换出,相当于它具有了与高优先级任务同样的优先级,又称Mutex有Priority Inheritance优先级继承的特点;而binary semaphore没有这个特点。如果是同一优先级,刚获得Mutex的任务B要等下次调度;但前一任务A可能再次获得Mutex并继续运行,导致任务B不能即时运行,这需要适当的编码以平衡任务的运行时间,或及时调用taskYIELD。
如果两个任务互相用Mutex独占了对方所需资源,两者都因等待而无法运行,这被称为Dead lock死锁,需要在编码时避免或给Mutex等待限时,或者将资源置于Gatekeeper任务管理之下,需要的任务都通过它来获得资源。使用时configUSE_TICK_HOOK置1,然后定义vApplicationTickHook(),它在每个tick被执行,因此必须简短。
Dead Lock死锁也可在单个任务中因多次获取Mutex而忘了释放而产生,这时可用Recursive Mutex,同一任务可N次获得该Mutex,但是在N次释放前别的任务不可获得该Mutex。相关函数名在Mutex前有前缀Recursive。


事件组允许任务在阻塞状态下等待多个组合事件;可在事件发生时unblock等待该事件(组)的所有任务,可以由多个任务共享。EventBits_t缺省为32bit,低24bit分别对应一个事件。以FreeRTOS+TCP TCP/IP stack包为例,它包括在FreeRTOS_Socket_t结构中,含有TCP socket的accept/bind/read/close及Abort事件,由FreeRTOS+TCP API使用。
相关函数为xEventGroupCreate、xEventGroupSetBits(FromISR)、xEventGroupWaitBits,最后这个函数允许所在任务按事件组blocked和unblocked。事件组也可用于任务同步,例如接受到TCP包的任务委托其它几个任务处理,在都处理完后相关事件都被置位,该包就可close。


Task Notifications任务通知:指任务间直接通信,不通过例如queue、semaphore等对象中转。将configUSE_TASK_NOTIFICATIONS置1后,每个任务都有“Notification State”和uint32的“Notification Value”。注意:发送任务不能阻塞以待发送完成。接收任务只允许是一个且不能是中断服务程序,可选指定时延的堵塞式等待它的通知状态变为Pending,在读取通知值后状态被置为Not-Pending。有两套函数:简化的发送xTaskNotifyGive()/xTaskNotifyGiveFromISR(),发送后通知值自动加1,配用堵塞等待的ulTaskNotifyTake()接收,可以取代以前的binary semaphore用于延迟的中断服务;增强的xTaskNotify()/xTaskNotifyFromISR() /xTaskNotifyWait(),多了对通知值的读写,可提供类似mail box或事件组覆盖写入的功能。xTaskNotifyWait()以可选的超时等待调用任务接收通知。如果接收任务在等待通知到达时已在等待通知的blocked态,则接收RTOS任务将被unblock并清除通知。
书中伪码例154:由Mutex互斥的xUART_Send()被共享来发送数据,先用xSemaphoreTake()清空,继而调用底层发送,再用xSemaphoreTake()使自己处于堵塞态。UART硬件在最后一字符被发送后中断,在中断服务中用xSemaphoreGiveFromISR()使得xUART_Send()解除堵塞,随即portYIELD_FROM_ISR()切换运行。

例155:semaphore带来的存储和执行开销、及初始化在上例中是不必要的。本例中semaphore由TaskHandle_t类型的xTaskToNotify取代,后者由API和中断共享。如果CPU位长不低于任务通知值,写入是原子操作,否则写入需临界域保护。用于接收的类似实现见例156。例157则用xTaskNotifyWait()以便传送ADC值,很实用的方法。本章最后说明了云端收发的流程

关于调试:并非所有编译器都提供Assert,为此可在配置中定义等效的configASSERT(),出错时后续的代码不会运行。例如自定义函数vAssertCalled()然后定义:
    #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
FreeRTOS提供Malloc failed hook、Stack overflow hook、Task Run-Time Statistics、Run-Time Statistics Clock,配置后与uxTaskGetSystemState()联用。另有Helper函数和Trace Hook Macros,许多IDE也提供debug plugin。FreeRTOS+Trace是Percepio提供的运行时诊断和优化工具,包括互联的20种图表。
最常见开发问题是incorrect interrupt priority assignment, stack overflow, inappropriate use of printf().
1)中断优先级:硬件中断的优先级应高于任务。不能超出configMAX_SYSCALL_INTERRUPT_PRIORITY,不能不定义,ARM Cortex把最低数字认为最高优先级。例如某CPU中断和配置最高中断都是5,但可被优先级4中断,则API中断优先级的值不应低于5。ARM Cortex的硬件和库实现都各有不同。优先级可分为pre-emption priority和sub-priority两部分,请只使用前一部分。有时候configMAX_SYSCALL_INTERRUPT_PRIORITY被称为configMAX_API_CALL_INTERRUPT_PRIORITY。
2)堆栈溢出:uxTaskGetStackHighWaterMark()返回某任务栈的最小剩余空间。配置configCHECK_FOR_STACK_OVERFLOW为1(返回栈的历史)或2(返回最近20此)并使用下列函数原型来勾取栈溢出的处理函数:void vApplicationStackOverflowHook( TaskHandle_t *pxTask, signed char *pcTaskName );
3)乱用printf()/sprintf():除非特殊设计。这两函数通常不具有线程安全性,可能会用malloc()或用堆栈,会加大程序尺寸和开销。开源的printf-stdarg.c可用来替代库函数,并可将输出重定向到端口。
其它注意事项:在中断服务中或调度器被挂起-例如在临界区域内-使用一般API函数可能崩盘。在调度器运行前的中断可能崩盘。在调度器工作前使用API可能导致中断被禁止。

3.2 FreeRTOS配置文件详解
C:Userse6400AppDataLocalArduino15packagesesp32hardwareesp321.0.6toolssdkincludefreertosfreertosFreeRTOSConfig.h 
内核配置一
参数名称          参数说明
USE_PREEMPTION      定义调度器模式
CPU_CLOCK_HZ       定义CPU的主频
TICK_RATE_HZ       定义系统时钟节拍数
MAX_PRIORITIES      定义可供用户使用的最大优先级数
MINIMAL_STACK_SIZE   定义空闲任务的栈空间大小
MAX_TASK_NAME_LEN   定义任务名最大的字符数
USE_16_BIT_TICKS    系统时钟节拍计数使用TickType_t数据类型定义
IDLE_SHOULD_YIELD   用于使能与空闲任务同优先级的任务
内核配置二
参数名称                   参数说明
USE_MUTEXES                 用于使能互斥锁
USE_RECURSIVE_MUTEXES          用于使能递归互斥锁
USE_COUNTING_SEMAPHORES           用于使能计数信号量
QUEUE_REGISTRY_SIZE               用于设置可以注册的信号量和消息队列个数
USE_APPLICATION_TASK_TAG          用于使能任务标记
ENABLE_BACKWARD_COMPATIBILITY     用于使能新版本对老版本的兼容特性
USE_PORT_OPTIMISED_TASK_SELECTION 用于优化优先级列表中药执行的最高优先级任务的算法
USE_TICKLESS_IDLE                 用于使能tickless低功耗模式
USE_TASK_NOTIFICATIONS            使能任务间直接的消息传递,包括信号量、事件标志组和消息邮箱
内存管理
参数名称            参数说明
MEMORY_ALLOCATION   定义内存分配模式
TOTAL_HEAP_SIZE     定义动态内存分配总长度
HEAP_NUMBER         定义动态内存管理方式
任务运行信息获取配置
参数名称                         参数说明
GENERATE_RUN_TIME_STATS          用于使能任务运行状态参数统计
USE_TRACE_FACILITY               使能此配置将添加额外的结构体成员和函数
USE_STATS_FORMATTING_FUNCTIONS   用户配置宏定义 configUSE_TRACE_FACILITY 和 configUSE_STATS_FORMATTING_FUNCTIONS
   都为 1 的时候,将使能函数 vTaskList() 和 vTaskGetRunTimeStats(),如果两者中任何一个为 0,那么这两个函数都将被禁能
软件定时器
参数名称        参数说明
USE_TIMERS      用于使能软件定时器
中断优先级
参数名称                                参数说明
LIBRARY_LOWEST_INTERRUPT_PRIORITY       用于配置 FreeRTOS 用到的 SysTick 中断和 PendSV 中断的优先级
LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY  定义了受 FreeRTOS 管理的最高优先级中断
函数Include            配置
参数名称               参数说明
vTaskPrioritySet       设置任务优先级
uxTaskPriorityGet      获取任务优先级
vTaskDelete            任务删除
vTaskCleanUpResources  清理任务资源
vTaskSuspend           任务挂起
vTaskDelayUntil        任务绝对延时
vTaskDelay             任务延时
xTaskGetSchedulerState 获取调度器状态
xTaskResumeFromISR     在中断中恢复任务
xQueueGetMutexHolder   获取互斥锁持有者
pcTaskGetTaskName      获取任务名称
uxTaskGetStackHighWaterMark 获取任务堆栈信息
xTaskGetCurrentTaskHandle   获取当前任务句柄
eTaskGetState               获取任务状态
xEventGroupSetBitFromISR    在中断中设置事件标志组
xTimerPendFunctionCall      定时器挂起后回调函数
xTaskAbortDelay             终止任务延时
xTaskGetHandle              获取任务句柄
————————————————原文链接:https://blog.csdn.net/Chuangke_Andy/article/details/109597607 
 
3.3 移植
 
3.4 用CubeMX移植
https://blog.csdn.net/so_cracy/article/details/80246414 配置里把FreeRTOS勾选,若定时器冲突换一个,即可。
CubeMX - STM32Cube initialization code generator:https://blog.csdn.net/ybhuangfugui/article/details/52225736
 
[ 打印 ]
阅读 ()评论 (0)
评论
目前还没有任何评论
登录后才可评论.