[xenomai驱动] 字符设备测试

本文深入解析Xenomai3驱动程序的开发流程,包括关键函数、设备注册与用户端调用API,以及Makefile配置。涵盖驱动结构、模块加载与卸载、设备读写函数使用等核心内容。
Xenomai3驱动程序:
驱动C文件:  自定义Mydriver.c,用于xenomai内核设备驱动相关
原始源文件路径:xenomai3.x\kernel\drivers\testing\rtdmtest.c
相关函数解析:

static int __init rtdm_test_init(void){
  #Todo初始化模块工作,可同时打开多个设备
}

static void __exit rtdm_test_exit(void)
{
  #Todo退出模块工作
}

static struct rtdm_driver rtdm_basic_driver = {
	.profile_info		= RTDM_PROFILE_INFO(rtdm_test_basic, //在proc/devices/查看的设备
						    RTDM_CLASS_TESTING,
						    RTDM_SUBCLASS_RTDMTEST,
						    RTTST_PROFILE_VER),
	.device_flags		= RTDM_NAMED_DEVICE | RTDM_EXCLUSIVE,
	.device_count		= 2,
	.context_size		= sizeof(struct rtdm_basic_context),
	.ops = {    //相关操作函数定义
		.open		= rtdm_basic_open,
		.close		= rtdm_basic_close,
		.write_rt	= rtdm_basic_write_rt,
		.ioctl_rt	= rtdm_basic_ioctl_rt,
		.ioctl_nrt	= rtdm_basic_ioctl_nrt,
	},
};

static struct rtdm_device device[3] = {
	[0 ... 1] = {
		.driver = &rtdm_basic_driver,
		.label = "rtdm%d", //作为打开的设备名%d=1,2
	},
	[2] = {
		.driver = &rtdm_actor_driver,
		.label = "rtdmx", //设备打开的名字为rtdmx
	}
};


rtdm_dev_register(device);   #注册设备
rtdm_dev_unregister( device ); #反注册设备

可以同时注册,反注册多个设备,设备数量在结构体rtdm_driver的成员device_count定义

module_init(rtdm_test_init);  #定义模块初始接口函数
module_exit(rtdm_test_exit);  #定义模块卸载接口函数

安装模块指令 insmod xxx.ko , 卸载模块指令 rmmod xxx  #xxx为生成的ko模块名称
dmesg -T 指令用于显示printk 内核日志打印

###################################################################

  用户端调用相关的xenomai-api函数 (部分代码解析)
   int devFd ;
   #define DEIVICE_NAME "rtdm1"  //定义相应的设备名称,对应上面device结构体的label
   devFd = rt_dev_open(DEVICE_NAME, 0); //xeno2.x 位置<trank/rtdm/rtdm.h>
   devFd = rtdm_open(DEVICE_NAME, 0); //xeno3.x 位置<cobalt/kernerl/rtdm/rtdm.h>
   #设备读写函数
   rt_dev_write,rt_dev_read;  //原型位置<trank/rtdm/rtdm.h>
   rtdm_write,rtdm_read;  //原型位置<cobalt/kernerl/rtdm/rtdm.h>

############################################################
## 内核程序 Makefile

#may be need this define empty
CONFIG_STACK_VALIDATION=

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

obj-m += rtdmtest.o

all: modules

modules:
	$(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules

modules_install:
	$(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules_install

clean:
	$(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules clean


#############################################################
## -------   用户端程序Makefile -------------
###### CONFIGURATION ######

### List of applications to be build
APPLICATIONS = mydrivertest

### Note: to override the search path for the xeno-config script, use "make XENO=..."

###### USER SPACE BUILD (no change required normally) ######
ifneq ($(APPLICATIONS),)

### Default Xenomai installation path
XENO ?= /usr/xenomai

XENOCONFIG=$(shell PATH=$(XENO):$(XENO)/bin:$(PATH) which xeno-config 2>/dev/null)

### Sanity check
ifeq ($(XENOCONFIG),)
all::
        @echo ">>> Invoke make like this: \"make XENO=/path/to/xeno-config\" <<<"
        @echo
endif


CC=$(shell $(XENOCONFIG) --cc) 

CFLAGS=$(shell $(XENOCONFIG) --skin=native --cflags) $(MY_CFLAGS)

LDFLAGS=$(MY_LDFLAGS) 
LDLIBS=$(shell $(XENOCONFIG) --skin=native --ldflags) \
        $(shell $(XENOCONFIG) --skin=rtdm --ldflags --no-auto-init)

# This includes the library path of given Xenomai into the binary to make live
# easier for beginners if Xenomai's libs are not in any default search path.
LDFLAGS+=-Xlinker -rpath -Xlinker $(shell $(XENOCONFIG) --libdir) 


all:: $(APPLICATIONS)

clean::
	$(RM) $(APPLICATIONS) *.o

endif
########################################################

# 若make出现** No rule to make target 'tools/objtool/objtool' , 
# 在可添加make CONFIG_STACK_VALIDATION= 来编译.
#######################################################

变量解析:

rtdm_driver结构体中的  devie_flags

RTDM_NAMED_DEVICE     通过名称做设备寻找

RTDM_EXCLUSIVE  设备独占

RTDM_PROTOCOL_DEVICE   通过协议ID,SocketType 寻址


C知识引申:
//在#define中,标准只定义了#和##两种操作。
//#用来把参数转换成字符串,##则用来连接两个前后两个参数,把它们变成一个字符串。

#define Conn(x,y)    x##y   //连接x,y

#define ToChar(x)    #@x    //加单引号

#define ToString(x)  #x     //加双引号

参考博客:
https://blog.youkuaiyun.com/woshidahuaidan2011/article/details/53522792




  
 

 

### 安装Xenomai 为了使Xenomai能够在Linux操作系统上正常工作,需先完成其安装过程。对于大多数现代Linux发行版而言,推荐通过源码编译的方式进行安装以获得最佳兼容性和性能[^1]。 #### 准备环境 确保主机已更新至最新的软件包状态,并安装必要的构建工具链以及依赖库文件。这通常涉及GCC编译器、make工具以及其他一些辅助程序和支持库。 ```bash sudo apt-get update && sudo apt-headers-$(uname -r) git wget libncurses-dev bison flex libssl-dev ``` #### 获取并解压Xenomai源代码 访问官方GitHub仓库下载指定版本的压缩包或者克隆整个Git存储库来获取最新开发快照: ```bash git clone https://github.com/xenomai/xenomai.git cd xenomai ``` #### 编译与安装 执行`./bootstrap`初始化脚本准备配置选项;接着利用`./configure`命令设置目标平台参数(如内核路径)。最后调用`make`启动实际编译流程并将生成的目标文件放置到适当位置。 ```bash ./bootstrap ./configure --enable-smp --with-core=cobalt make -j$(nproc) sudo make install ``` ### 配置Xenomai 成功安装之后,还需进一步调整系统以便充分利用Xenomai所提供的特性。这部分主要包括加载相应的模块和服务端口等操作。 #### 加载核心模块 重启计算机前应手动加载Cobalt子系统的驱动组件,这样可以立即生效而无需等待下次引导时自动激活它们。 ```bash sudo modprobe cobalt ``` #### 修改GRUB菜单项 为了让Xenomai能够接管中断处理机制从而实现更严格的定时控制,建议修改GRUB引导管理器中的默认内核行加入特定标志位。 编辑/etc/default/grub文件,在`GRUB_CMDLINE_LINUX_DEFAULT`变量后面追加如下字符串: ``` "isolcpus=1 nohz_full=1 rcu_nocbs=1" ``` 保存更改后运行`update-grub`刷新配置缓存,随后重新启动机器让新设定生效。 ### 解决常见问题 当遇到困难时可以从以下几个方面入手排查原因所在: - **确认硬件支持**:并非所有的CPU架构都得到了充分测试验证,因此如果是在较新的处理器型号上面部署可能会碰到未知错误。 - **检查权限级别**:某些功能可能需要root用户身份才能正常使用,请尝试切换超级管理员模式重试一遍相同指令集看看是否有改善效果。 - **查阅日志记录**:查看/var/log/syslog或dmesg输出寻找任何异常提示信息帮助定位具体故障点。
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值