我有一个简单的字符设备驱动程序,允许您从自定义硬件设备读取.它使用DMA将数据从设备的内存复制到内核空间(然后再复制到用户).
该read调用非常简单.它启动DMA写入,然后等待等待队列.当DMA完成时,中断处理程序设置一个标志并唤醒等待队列.需要注意的重要一点是,我可以随时启动DMA,甚至在设备提供数据之前.DMA引擎将等待,直到有数据要复制.这很好用.我可以在用户空间中实现一个简单的阻塞读取调用,它的行为与我期望的一样.
我想实现,poll以便我可以select在用户空间中使用系统调用,允许我同时监视此设备和套接字.
我能找到的大部分资源poll都说:
poll_wait可能表示状态发生变化的每个等待队列第二部分让我感到困惑.我见过的大多数示例都有一种简单的方法(指针比较或状态位)来检查数据是否可用.在我的情况下,除非我启动DMA,否则数据将永远不可用,即使我这样做,数据也不会立即可用(在设备实际拥有数据和DMA完成之前可能需要一些时间).
那怎么实现呢?该poll函数是否应该实际启动DMA以使数据最终可用?我想这会破坏我的read功能.
我正在研究共享内存上的Linux内核限制
/proc/sys/kernel/shmall
Run Code Online (Sandbox Code Playgroud)
指定可以分配的最大页面数.将此数字视为x,将页面大小视为p.我假设"x*p"字节是系统范围共享内存的限制.
现在我写了一个小程序来创建一个共享内存段,并且我连接到该共享内存段两次,如下所示
shm_id = shmget(IPC_PRIVATE, 4*sizeof(int), IPC_CREAT | 0666);
if (shm_id < 0) {
printf("shmget error\n");
exit(1);
}
printf("\n The shared memory created is %d",shm_id);
ptr = shmat(shm_id,NULL,0);
ptr_info = shmat(shm_id,NULL,0);
Run Code Online (Sandbox Code Playgroud)
在上面的程序ptr和ptr_info不同.因此共享内存映射到我的进程地址空间中的2个虚拟地址.
当我这样做时,ipcs它看起来像这样
...
0x00000000 1638416 sun 666 16000000 2
...
Run Code Online (Sandbox Code Playgroud)
现在我的问题已达到上述shmall限制x * p.此限制是否适用于为每个共享内存段分配的所有虚拟内存的总和?或者此限制是否适用于物理内存?
物理内存在这里只是一个(共享内存),当我做2时,上面的程序shmat存在两倍于我的进程地址空间中分配的内存量.如果shmat在单个共享内存段上连续执行,这个限制很快就会出现?
任何人都可以帮助我使用AT命令写入特征值,或者如何使用Hm10模块将数据从arduino发送到另一个ble设备.
HM10发送AT + START后,确实发布了数据包,并且可以检测服务和特性,但是特征值是默认值0x00,我该如何改变呢?
已多次检查数据表,但找不到能够执行相同操作的AT命令.
更新:在中央模式下设置HM10的类似问题:
中央模式设置!
1)AT + ROLE1 - 设置为中央模式
2)AT + IMME1 - 从RESET开始
3)AT + SHOW1 - 显示发现的设备
4)AT + DISC? - 发现设备获取设备MAC ID,
5)AT + CON [MAC ID]
结果:总是给OK + CONNA,10秒后OK + CONNF
我很困惑,在"AT + DISC"之前使用"AT + START"?导致AT + START不起作用,反之亦然.使用AT + START结果进入OK + CONN循环,然后连续OK + LOST,不再接受AT命令.我相信它确实会产生一个
你能按正确的顺序提出建议吗?
使用LightBlue iOS应用程序作为外围设备.我如何选择服务并订阅特征以从应用程序接收数据?
谢谢.
arduino at-command characteristics bluetooth-lowenergy hm-10
什么是irq域,我读了内核文档(https://www.kernel.org/doc/Documentation/IRQ-domain.txt),他们说:
注册为唯一irqchips的中断控制器的数量显示出上升趋势:例如,GPIO控制器等不同类型的子驱动器通过将其中断处理程序建模为irqchips,即实际上是级联中断控制器,避免重新实现与IRQ核心系统相同的回调机制.
如何将GPIO控制器称为中断控制器?
linux interrupt linux-device-driver linux-kernel embedded-linux
我为我们开发的外围设备编写了一个平台驱动程序,并希望向sysfs公开一些配置选项.我已设法使用属性结构(见下文)和sysfs_create_file探测函数创建适当的文件,但我无法弄清楚如何将show/store函数附加到平台驱动程序中的结构.
我在网上找到的大多数资源使用了一个device_attribute结构或类似的东西来创建他们的文件,这也适合吗?还有另一种方法可以为平台驱动程序执行此操作吗?
我的属性struct看起来像这样:
struct attribute subkey_attr = {
.name = "subkeys",
.mode = S_IWUGO | S_IRUGO,
};
Run Code Online (Sandbox Code Playgroud)
我使用此调用注册该文件:
riddler_kobject = &pdev->dev.kobj;
ret_val = sysfs_create_file(riddler_kobject, &subkey_attr);
Run Code Online (Sandbox Code Playgroud) 我用C语言用MPI编写了以下代码:
#include <mpi.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int size, rank;
MPI_Status status;
int buf[1000];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == 0) {
int i = 0;
while (i != 1000) {
buf[i] = i;
i++;
}
MPI_Send(buf, 999, MPI_INT, 1, 1, MPI_COMM_WORLD);
printf("msg has been sent\n");
}
if (rank == 1) {
int sz = sizeof(buf);
int lst = buf[sz-1];
MPI_Recv(buf, 999, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
printf("la taille du buf %d et …Run Code Online (Sandbox Code Playgroud) 比方说,我想用printk()内部arch/x86/boot/string.c编译内核之前.我必须包含哪个头文件,以便链接器知道在哪里找到printk()?我尝试过#include <linux/kernel.h>,#include <linux/printk.h>但在make bzImage告诉我链接器找不到时总是出错printk:
arch/x86/boot/compressed/string.o: In function `memcmp`:
string.c:(.text+0x19): undefined reference to `printk`
Run Code Online (Sandbox Code Playgroud) 我想保留 2GB 起 512 MB 的 RAM。我尝试过使用memmap=512M$2G. 但是我使用的时候重启后就cat /proc/cmdline显示memmap=512MM并且系统变得很慢。我使用的是非 UEFI 系统。
我正在努力理解平台设备驱动程序与字符设备接口之间的链接以及将数据存储在特定于设备的数据结构中.
我创建了一个结构来跟踪与我的设备相关的数据,然后将它添加到probe函数的devices结构中:
dev_set_drvdata(dev, data_struct);
Run Code Online (Sandbox Code Playgroud)
我还保留了全球副本data_struct.
我注册了一个misc设备,以便我可以mmap()通过ioctl()命令访问设备.如果我想访问此设备data_struct,目前我通过全局副本访问它.是否有另一种方法通过inode或file指针访问我存储在设备结构中的数据?
我目前只允许一个设备实例,但我想确保我正确实现这一点,以便将来可能有多个设备使用相同的驱动程序.
driver kernel-module linux-device-driver linux-kernel embedded-linux
我目前正在研究操作系统的低级组织.为了实现我想要了解Linux内核是如何加载的.
我无法理解的是从16位(实模式)到32位(保护模式)的转换.它发生在这个文件中.
该protected_mode_jump函数对稍后执行的32位代码执行各种辅助计算,然后启用调节器中的PE位CR0
movl %cr0, %edx
orb $X86_CR0_PE, %dl # Protected mode
movl %edx, %cr0
Run Code Online (Sandbox Code Playgroud)
然后执行长跳转到32位代码:
# Transition to 32-bit mode
.byte 0x66, 0xea # ljmpl opcode
2: .long in_pm32 # offset
.word __BOOT_CS # segment
Run Code Online (Sandbox Code Playgroud)
据我所知in_pm32,32位函数的地址在下面声明protected_mode_jump:
.code32
.section ".text32","ax"
GLOBAL(in_pm32)
# some code
# ...
# some code
ENDPROC(in_pm32)
Run Code Online (Sandbox Code Playgroud)
的__BOOT_CS扇区基是0(GDT被设定预先这里),因此这意味着,偏移应该是基本上绝对地址in_pm32的功能.
这就是问题所在.在机器代码生成期间,汇编器/链接器不应该知道in_pm32函数的绝对地址,因为它不知道在实模式下它将在内存中加载的位置(各种引导加载程序可以占用不同的空间量,以及实模式内核)在引导加载程序之后加载).
此外,链接器脚本(setup.ld在同一文件夹中)将代码的原点设置为0,因此看起来in_pm32地址将是从实模式内核开始的偏移量.它应该可以正常使用16位代码,因为CS寄存器设置正确,但是当发生长跳转时,CPU已经处于保护模式,因此相对偏移不应该起作用.
所以我的问题:.byte …