FreeRTOS
移植和配置
- 移植
- 路径
- 配置
- 函数前缀字母与输出形式有关
- x 句柄
- v void
任务
- 创建
xTaskCreate(func, name, ram, param, priority, handle)vTaskStartScheduler(void)
- 删除
vTaskDelete(handle)NULL 可以删除自己 - 挂起
vTaskSuspend(handle)vTaskResume(handle)vTaskSuspendFromISR(handle)vTaskSuspendAll(void)vTaskResumeAll(void)
- 切换
taskYIELD(void) - 调度
- 运行 就绪 阻塞 挂起
- 时间片调度 优先级调度
- 空闲任务 空闲任务回调函数 常用于进入低功耗模式
- 信息
vTaskList(buffer)vTaskGetRunTimeStats(buffer)
- 优先级
vTaskPrioritySet(handle, newPriority)uxTaskPriorityGet(handle)
- 临界区
- 临界区代码不会被中断打断,会影响系统的实时性, 常用于全局变量的保护和修改
taskENTER_CRITICAL(void)taskEXIT_CRITICAL(void)taskENTER_CRITICAL_FROM_ISR(void)taskEXIT_CRITICAL_FROM_ISR(void)taskDISABLE_INTERRUPTS(void)在临界区开启中断 一般用退出
时间
- 轮转
vApplicationTickHook(void)启用时间片轮转回调函数
- 延时
xTaskGetTickCount(void)获取节拍赫兹xTaskGetTickCountFromISR(void)中断中获取节拍赫兹vTaskDelay(ticks)相对延时vTaskDelayUntil(p, ticks)绝对延时vApplicationIdleHook(void)启用空闲任务回调函数
任务栈
- 内存分配失败
vApplicationMallocFailedHook(void)分配失败回调函数 - 溢出
vApplicationStackOverflowHook(handle,name)栈溢出回调函数 - 确定大小
uxTaskGetStackHighWaterMark(handle)返回最小剩余空间
内存管理
- 申请和释放
* pvPortMalloc(size)申请空间vPortFree(pv)释放vPortInitialiseBlocks(void)初始化内存堆函数xPortGetFreeHeapSize(void)未分配大小xPortGetMinimumEverFreeHeapSize(void)最小未分配大小
- 动态分配
\Sourse\portable\MemMang\heap_x.c内存管理方案- heap1: 分配后不允许释放
- heap2:可以释放但不合并,会造成碎片
- heap3:封装了malloc free 线程安全(多任务调用),占用大
- heap4: 支持内存碎片处理
- heap5: 支持将动态内存设置在不连续的区域上
通信
- 消息队列
xQueueCreate(length, size)创建XQueueCreateStatic静态xQueueSend(queue, p, waitTime)xQueueSendFromISR(q, p, woken)发到队尾xQueueSendToBack(q, p, wait)基本同上xQueueSendToFront(q, p, wait)发到队首xQueueReceive(q, buffer, wait)获取xQueueReceiveFromISR(q, buffer, woken)
- 二值信号量
xSemaphoreCreateBinary(void)创建xSemaphoreGive(sem)xSemaphoreGiveFromISR(sem, woken)给出xSemaphoreTake(sem, wait)获取
- 计数信号量
xSemaphoreCreateCounting(maxNum, initNum)
- 互斥信号量
xSemaphoreCreateMutex(void)- 优先级继承
- 递归信号量
xSemaphoreCreateRecursiveMutex(void)xSemaphoreTakeRecursive(mutex, wait)获取xSemphoreGiveRecursive(mutex)释放
- 通知
- 每个任务的任务控制块都有一个32位的
ulNotifiedValue变量 - 可以用于实现消息队列、信号量、事件组,速度更快
- 但缺陷在于,要求只要一个任务在等待,发送消息不支持超时等待
- 信号量
ulTaskNotifyTake(减少pdFALSE/清零pdTRUE,wait)xTaskNotifyGive(handle)xTaskNotifyGiveFromISR(handle, woken)xTaskNotifyWait(输入前清除,退出前清除,pv, wait)xTaskNotify(handle, value, mode)xTaskNotifyFromISR(handle, value, mode, woken)eNoAction不改值eSetBits改字节值eIncrement加一eSetValueWithOverwrite覆盖eSetValWithoutOverwrite没收到就不改
- 每个任务的任务控制块都有一个32位的
- 事件组
xEventGroupCreate(void)创建xEventGroupSetBits(group, bits)xEventGroupSetBitsFromISR(group, bits, woken)设置xEventGroupWaitBits(group, needBits, 退出清除,是否等待全部置一, wait)
定时器
- 定时器
xTimerCreate(name, period, reload, id, callback)创建xTimerStart(timer, block)启动pvTimerGetTimerID(timer)获取id
- 低功耗
- 睡眠模式 WFE WFI
- 停机模式
PWR_EnterSTOPMode - 待机模式
PWR_EnterSTANDBYMode__HAL_RCC_PWR_CLK_ENABLE()使能PWR 时钟__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU)清除 Wake_UP 标志HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1)设置 WKUP 用于唤醒HAL_PWR_EnterSTANDBYMode()进人待机模式
- tickless
- 空闲任务运行,其他任务挂起或阻塞,PECTED_IDIE_TIME_BEFORE_SLEEP小于低功耗模式节拍数时
- 系统自动调用
portSUPPRESS_TICKS_AND_SLEEP()函数 进入低功耗模式
命令行
- CLI 移植 略
- CLI 命令
func(buffer, len, cmd)实现命令FreeRTOS_CLIGetParameter(str, param, len)命令参数 放在上面函数内FreeRTOS_CLIRegisterCommand(register)注册命令FreeRTOS_CLIProcessCommand(input, buffer, len)命令处理
文件
- FAT移植 略
I2C_Soft_Init()初始化iic__HAL_RCC_CRC_CLK_ENABLE()开启CRC时钟FF_SDDiskInit("/")初始化sd卡
- 创建
ff_mkdir(dir)创建文件夹ff_chdir(dir)切换目录ff_rmdir(dir)删除ff_getcwd(buffer, len)查看当前工作目录
- 读写
ff_stdio.hfile = ff_fopen(filename, mode)可以用于创建ff_fclose(file)ff_fwrite(buffer, size, len, file)ff_fread(buffer, size, len, file)ff_fputc(char, file)写入单字节ff_fgets(buffer, size,file)读取字符串ff_fprintf(file, format)格式化写入文件ff_fseek(file, offset, whence)将读写位置移动到offset+whenceff_ftell(file)当前位置ff_seteof(file)截断到当前位置ff_truncate(filename, maxsize)打开文件,截断到最大长度ff_rewind(file)回到开头
- 文件操作
ff_feof(file)指针是否在文件末尾ff_rename(oldName, newName, 是否删除源文件)移动或重命名ff_remove(path)删除文件ff_stat(filename, buffer)读取文件属性保存到bufferff_filelength(file)文件长度ff_findfirst(dir, data)目录中第一个文件ff_findnext(dada)目录中下一个文件(夹)
网络编程
- TCP/IP 移植 略
- UDP
socket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM/STREAM, FREERTOS_IPPROTO_UDP/TCP)创建FreeRTOS_setsocket(socket, level, option, value, len)选项设置FreeRTOS_sendto(socket, buffer, len, flag, address, addrlen)发送FreeRTOS_recvfrom(socket, buffer, len, flag, addr, addrlen)接收
- TCP 客户端
FreeRTOS_connect(socket, addr, addrlen)连接FreeRTOS_shutdown(socket, FreeRTOS_CLOST_RDWR)关闭连接FreeRTOS_closesocket(socket)关闭套接字FreeRTOS_send(socket, buffer, len, flags)在上文连接后发送FreeRTOS_recv(socket, buffer, len, flags)接收数据
- TCP 服务端
FreeRTOS_bind(socket, addr, addrlen)绑定到本地端口号FreeRTOS_listen(socket, maxLink)开始监听FreeRTOS_accept(socket, addr, addrlen)接收连接