一个sio.c的实现及遇到的多任务执行问题
https://sourceforge.net/p/cadcdev/lwip/ci/491e00038f26dc5d775f120aa49519a066819ebf/tree/kos/sio.c
/* KallistiOS ##version## sio.c
Copyright (C)2004 Dan Potter
*/ #include <dc/scif.h>
#include <kos/thread.h>
#include <lwip/lwip.h>
#include "lwip/sio.h" /*
This implements the serial I/O interface for lwIP to use PPP for serial
connections. This hooks straight to dbgio right now but could easily
be swapped over to use the modem stuff.
*/ static volatile int sio_abort = ; sio_fd_t sio_open(u8_t foo) {
int i; sio_abort = ; // Clear out anything in the buffer already
i = ;
while (scif_read() != -)
i++;
if (i)
printf("sio: cleared %d initial chars\n", i); return NULL;
} void sio_send(u8_t ch, sio_fd_t foo) {
scif_write(ch);
scif_flush();
} u8_t sio_recv(sio_fd_t foo) {
int ch; do {
ch = scif_read();
if (ch == -)
thd_sleep();
} while (ch == - && !sio_abort); sio_abort = ;
return ch;
} // I *think* this is right, but sio_* seems to be totally
// undocumented like so many things in lwIP.
u32_t sio_read(sio_fd_t foo, u8_t *outbuf, u32_t bufmax) {
int i, ch; for (i=; i<bufmax && !sio_abort; i++) {
ch = scif_read();
if (ch == -) {
if (i == ) {
thd_sleep();
i--;
continue;
} else
break;
}
outbuf[i] = ch;
} sio_abort = ;
return i;
} // Ditto on the comment for sio_read.
u32_t sio_write(sio_fd_t foo, u8_t *buf, u32_t buflen) {
int i; for (i=; i<buflen && !sio_abort; i++)
scif_write(buf[i]);
scif_flush(); sio_abort = ;
return buflen;
} void sio_read_abort(sio_fd_t foo) {
sio_abort = ;
printf("sio_read_abort called\n");
while (sio_abort)
thd_sleep();
}
上面这个实现似乎没有实现block
下面的实现,一开始while死循环处没有加Delay(1);,结果,其它任务根本起不来,
后来,加了一个Delay(1);之后,其它任务就能起来了。
即使没有Delay(1);,任务调度不是也应该能调度其它任务吗???
/**
* Reads from the serial device.
*
* @param fd serial device handle
* @param data pointer to data buffer for receiving
* @param len maximum length (in bytes) of data to receive
* @return number of bytes actually received - may be 0 if aborted by sio_read_abort
*
* @note This function will block until data can be received. The blocking
* can be cancelled by calling sio_read_abort().
*/
u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len)
{
if(len >= )
{
if(fd.UartNo == )
{
while(USART_GetITStatus(USART1, USART_IT_RXNE) == RESET) {Delay();}
{
*data =(u8)USART_ReceiveData(USART1);
return ;
}
}
else if(fd.UartNo == )
{
while(USART_GetITStatus(USART3, USART_IT_RXNE) == RESET)
{
*data =(u8)USART_ReceiveData(USART3);
return ;
}
}
else if(fd.UartNo == )
{
while(USART_GetITStatus(UART5, USART_IT_RXNE) == RESET)
{
*data =(u8)USART_ReceiveData(UART5);
return ;
}
}
else if(fd.UartNo == )
{
while(USART_GetITStatus(USART6, USART_IT_RXNE) == RESET)
{
*data =(u8)USART_ReceiveData(USART6);
return ;
}
}
}
return ;
}
另外,上面没有实现多字节读取,读取len个,也没有实现abort,可以参考最开始的例子。
目前系统中所有任务的优先级分配如下,空闲任务优先级为0,最大优先级是8:
Main_task 1
ToggleLed4 2
tcpip task 6
udp task 5
eth input 7
slip input 7
slip接收任务如下:
#if SLIP_USE_RX_THREAD
/**
* The SLIP input thread.
*
* Feed the IP layer with incoming packets
*
* @param nf the lwip network interface structure for this slipif
*/
static void
slipif_loop_thread(void *nf)
{
u8_t c;
struct netif *netif = (struct netif *)nf;
struct slipif_priv *priv = (struct slipif_priv *)netif->state; while () {
if (sio_tryread(priv->sd, &c, ) > ) {
slipif_rxbyte_input(netif, c);
}
}
}
#endif /* SLIP_USE_RX_THREAD */
slip接收任务是死循环,没有自动结束,而且优先级是最高的7,因此,slip任务会一直运行,其它任务都无法打断(led、udp任务无法执行)。
在read的while中加Delay(1);可以,而且,这里的Delay(1)得是用的操作系统的delay,如下:
/**
* @brief Inserts a delay time.
* @param nCount: number of Ticks to delay.
* @retval None
*/
void Delay(uint32_t nCount)
{
vTaskDelay(nCount);
}
vTaskDelay就是FreeRTOS操作系统自带的延时函数。因为,操作系统在执行该任务的delay过程中,会去执行其它任务,因此,其它低优先级任务得以继续执行。
如果delay这里用for 100次的这种方式,仍然是不行的,操作系统仍然不能切换到其它任务。
关于vTaskDelay可以看这篇博文http://blog.csdn.net/zhzht19861011/article/details/51705148
需要对整个系统的不同任务、优先级好好了解清楚。
对于高优先级任务,需要执行完就立刻挂起或阻塞,以让其它低优先级任务得以执行。
一个sio.c的实现及遇到的多任务执行问题的更多相关文章
- 意外作出了一个javascript的服务器,可以通过js调用并执行任何java(包括 所有java 内核基本库)及C#类库,并最终由 C# 执行你提交的javascript代码! 不敢藏私,特与大家分
最近研发BDC 云开发部署平台的数据路由及服务管理器意外作出了一个javascript的服务器,可以通过js调用并执行任何java(包括 所有java 内核基本库)及C#类库,并最终由 C# 执行你提 ...
- 假设result是一个float型变量,其值为27.32,value是一个int型变量,其值为15执行以下语句后,两个便利的值分别是多少?为什么?
假设result是一个float型变量,其值为27.32,value是一个int型变量,其值为15执行以下语句后,两个便利的值分别是多少?为什么? 在执行这条语句的过程中,保存在result中的值被读 ...
- Linux是一个基于POSIX和Unix的多用户、多任务、支持多线程和多CPU的性能稳定的操作系统,可免费使用并自由传播。
Linux是一个基于POSIX和Unix的多用户.多任务.支持多线程和多CPU的性能稳定的操作系统,可免费使用并自由传播. Linux是众多操作系统之一 , 目前流行的服务器和 PC 端操作系统有 L ...
- Leaf - 一个由 Go 语言编写的开发效率和执行效率并重的开源游戏服务器框架
转自:https://toutiao.io/posts/0l7l7n/preview Leaf 游戏服务器框架简介 Leaf 是一个由 Go 语言(golang)编写的开发效率和执行效率并重的开源游戏 ...
- 判断本地系统目录下是否存在XML文件,如果不存在就创建一个XMl文件,若存在就在里面执行添加数据
这是我为项目中写的一个测试的例子, 假如,您需要这样一个xml文件, <?xml version="1.0" encoding="utf-8"?> ...
- Linq学习系列-----1.2 一个简单方法的改进思考及不同的执行形式
一.普通模式: #region 模式1 public Form1() { InitializeComponent(); GetProcessByJudge(); } public bool Memor ...
- Spring boot 官网学习笔记 - 开发第一个Spring boot web应用程序(使用mvn执行、使用jar执行)
Creating the POM <?xml version="1.0" encoding="UTF-8"?> <project xmlns= ...
- [mvc>actionResult] 封装一个操作方法的结果并用于代表该操作方法执行框架级操作
- .Net中的AOP系列之构建一个汽车租赁应用
返回<.Net中的AOP>系列学习总目录 本篇目录 开始一个新项目 没有AOP的生活 变更的代价 使用AOP重构 本系列的源码本人已托管于Coding上:点击查看. 本系列的实验环境:VS ...
随机推荐
- 安装k8s和NVIDIA环境
安装环境 系统要求 CPU: 2个核心 内存: 2GB 显卡:NVIDIA系列 安装docker apt install docker.io 安装k8s 添加软件源 方便起见,将Ubuntu的软件管理 ...
- Ubuntu 19.10 安装 jupyter
安装pip3 ubuntu 19.10 已经没有python了,取代的是python3. 执行sudo apt install python3-pip安装pip3 安装jupyter 执行sudo p ...
- Anaconda的CondaHTTPError问题
在Anaconda+Spyder配置Opencv的过程中遇到了缺乏cv2的问题,当时我在cmd的窗口(管理员身份)中输入了如下命令 conda install --channel https://co ...
- kaggle竞赛分享:NFL大数据碗(上篇)
kaggle竞赛分享:NFL大数据碗 - 上 竞赛简介 一年一度的NFL大数据碗,今年的预测目标是通过两队球员的静态数据,预测该次进攻推进的码数,并转换为该概率分布: 竞赛链接 https://www ...
- (分块暴力)Time to Raid Cowavans CodeForces - 103D
题意 给你一段长度为n(1 ≤ n ≤ 3·1e5)的序列,m (1 ≤ p ≤ 3·1e5)个询问,每次询问a,a+b,a+2b+...<=n的和 思路 一开始一直想也想不到怎么分,去维护哪些 ...
- Nmap使用教程(一)
基本扫描技术 扫描单个网络 nmap 192.168.1.1/www.baidu.com 扫描多个网络/目标 nmap 192.168.1.1 192.168.1.2 #将扫描同个网段内不同的ip地址 ...
- python练习题-9-6
本代码是<Python核心编程(第二版)>第九章的9-6练习题,完成的功能为:文件比较:比较两个文本文件是否相同,如果不同,给出第一个不同处的行号和列号. #!/usr/bin/env p ...
- Python使用requests发送post请求的三种方式
1.我们使用postman进行接口测试的时候,发现POST请求方式的编码有3种,具体的编码方式如下: A:application/x-www-form-urlencoded ==最常见的post提交数 ...
- Kotlin DSL for HTML实例解析
Kotlin DSL for HTML实例解析 Kotlin DSL, 指用Kotlin写的Domain Specific Language. 本文通过解析官方的Kotlin DSL写html的例子, ...
- 利用http协议使用普通的网站虚拟主机+安信可A6C GPRS模块实现对stm32的远程升级
步骤: 1.生成bin文件并将bin文件放到虚拟主机目录内 2.做一个php的页面分块读取该bin文件,以asc字符echo出来,并标记好头尾长度和校验. 3.GPRS协议栈连接主机路径,收到内容,将 ...