仿真一个陀螺 gazebo 注意,这个路径必须是对的,才能够显示正确,目前我不知道怎么设置这个查找路径,所以就先直接写了该路径。然后启动下面命令即可rosrun gazebo_ros spawn_model -file `rospack find gazebo_ros`/objects/top.urdf -urdf -model top -z 0.5rosservice call gazebo/appl...
Gazebo ROS API for C-Turtle gazebo提供了很多ros的API,允许用户操作或者获取各种仿真世界的信息,pose和twist是刚体的状态,一个对象有内部的特性,比如指令和摩擦系数,gazebo中,body是一个刚体,和urdf中的link一样,一个gazebo model有body和joint组成为了确保这个包被编译,但是不确定有什么用,还是先执行了,rosmake gazebo_ros启动gazebo一个...
ROS 基础学完后,接下来的动作 看完初级的tutorials,掌握了基本概念,但是对ROS控制机器人没概念,那么首先从一个模拟器开始会比较直观,这里选择PR2模拟器ROS真正的吸引力不在于它自己发布或订阅的中间件,而在于ROS为世界各地的开发者提供了一种标准机制来分享他们的代码。大量现成可用的程序包(packages)已经势不可挡。要会仿真,首先要知道怎么用仿真器,那么先学习simulator_gazebo首先...
录制与回放数据 将ROS系统运行过程中的数据录制到一个.bag文件中,然后通过回放数据来重现相似的运行过程。由于之前做过其他的tutorials,所以关闭ros,重新打开roscore等还是用小乌龟的例子,检测系统中所有的话题rostopic list -vroot@ben-virtual-machine:~# rostopic list -vPublished topics:* /tu...
编写简单的服务器和客户端 根据tutorials,beginner tutorials中的src下建立对应的cpp文件,然后在cmakelist.txt(/root/catkin_ws/src/beginner_tutorials)中增加下面一段。add_executable(add_two_ints_server src/add_two_ints_server.cpp)target_link_libraries...
编写简单的发布器和订阅器并测试 使用c++和python两种方式首先使用c++1:创建一个发布器节点mkdir -p ~/catkin_ws/src/beginner_tutorials/src 先创建一个文件夹,用于存储该代码包的源码具体代码参考tutorial初始化 ROS 系统 在 ROS 网络内广播我们将要在 chatter 话题上发布std_msgs/String类型的消息 以每秒 10 ...
创建ROS消息和ROS服务 首先需要理解msg和srv创建一个message$ cd ~/catkin_ws/src/beginner_tutorials$ mkdir msg$ echo "int64 num" > msg/Num.msg查看package.xml, 确保它包含一下两条语句: <build_depend>message_generation</build...
ros编辑器 rosed是rosbash的一部分。利用它可以直接通过package名来获取到待编辑的文件而无需指定该文件的存储路径了。例如rosed roscpp Logger.msg 内部使用的是vim也可以修改默认的EDITOR 。export EDITOR='emacs -nw'但是如果要其他终端也生效,需要修改~/.bashrc...
roslaunch启动launch文件中多节点 roslaunch可以用来启动定义在launch文件中的多个节点。由于之前没有调用setup.bash,没有添加工作区路径到ros环境中,所以一开始使用roscd的时候找不到,添加后就可以了通过查看ROS_PACKAGE_PATH 也可以看到新添加的路径。创建一个文件夹launch,然后创建一个文件touch turtlemimic.launch<launch>...
rqt_console 和 roslaunch rqt_console属于ROS日志框架(logging framework)的一部分,用来显示节点的输出信息。rqt_logger_level允许我们修改节点运行时输出信息的日志等级(logger levels)(包括 DEBUG、WARN、INFO和ERROR)。Fatal是最高优先级,Debug是最低优先级。通过设置日志等级你可以获取该等级及其以上优先等级的所有日志消息。比如,将日志等级...
理解ROS服务和参数 服务(services)是节点之间通讯的另一种方式。服务允许节点发送请求(request)并获得一个响应(response)rosservice list,列出当前的服务 rosservice type clear 查看clear服务的类型。clear类型是std_srvs/Empty,这种表示clear不需要发送参数,也没有接收的响应。rosservice call cl...
ROS message 消息 话题之间的通信是通过在节点之间发送ROS消息实现的。对于发布器(turtle_teleop_key)和订阅器(turtulesim_node)之间的通信,发布器和订阅器之间必须发送和接收相同类型的消息。这意味着话题的类型是由发布在它上面的消息类型决定的rostopic type /turtle1/cmd_vel 可以查看消息的类型rosmsg show geometry_msgs/Twis...
ROS话题topic turtlesim_node节点和turtle_teleop_key节点之间是通过一个ROS话题来互相通信的。turtle_teleop_key在一个话题上发布按键输入消息,而turtlesim则订阅该话题以接收该消息话题一个发布,一个订阅。再打开一个终端,输入如下,rosrun rqt_graph rqt_graph,rqt_graph能够创建一个显示当前系统运行情况的动态图形...
ROS节点 首先是一些基本概念,这里只是先列出来。统一理解。Nodes:节点,一个节点即为一个可执行文件,它可以通过ROS与其它节点进行通信。Messages:消息,消息是一种ROS数据类型,用于订阅或发布到一个话题。Topics:话题,节点可以发布消息到话题,也可以订阅话题以接收消息。Master:节点管理器,ROS名称服务 (比如帮助节点找到彼此)。rosout: ROS中相当于std...
ubuntu16.04下安装v-rep 1:首先去官网下载http://coppeliarobotics.com/downloads如下图所示,选择linux版本,教育版选择ubuntu16.04的版本。并选择教育版2:将windows中下载好的文件放到ubuntu虚拟机中,执行 xz -d CoppeliaSim_Edu_V4_0_0_Ubuntu16_04.tar.xz 其中xz是linux的解压...
ROS 基础使用1 ROS的安装可以按照教程来。不再多说http://wiki.ros.org/kinetic/Installation/Ubuntu如果你在查找和使用ROS软件包方面遇到了问题,请确保你已经正确配置了脚本环境。一个检查的好方法是确保你已经设置了像ROS_ROOT和ROS_PACKAGE_PATH这样的环境变量,可以通过以下命令查看:$ export | grep ROSrosb...
bashrc的作用 home 目录下藏着很多隐藏文件。如果你在运行Linux 发行版的话,你就会在靠近隐藏文件列表的上方看见一个名为.bashrc的文件。那么什么是.bashrc,编辑.bashrc又有什么用呢?bash 很可能是作为默认终端被安装的。虽然存在很多不同的shell,bash 却是最常见或许是最主流的。bash 是一个能解释你输入进终端程序的东西,并且基于你的输入来运行命令。它在一定程度上...
如何查看Ros的版本号 今天准备安装V-rep,想看下ROS的版本,之前安装了ROS,一直忙于工作,没有太多时间学习,趁着这段时间,多了解一些机器人仿真相关知识。查看ROS版本号如下步骤,在ubuntu16.04中操作。1、先在终端输入roscore2、打开新终端,再输入,rosparam list3、再输入rosparam get /rosdistro就能得到版本...
vs2017 使用fopen_s error问题解决 vs是一个很好的软件编辑器,有时候我们只是希望编写一些c语言的程序,使用vs进行仿真,仿真成功后可以移植到linux的环境。或者使用gcc等编译器的地方,但是像fopen_s这种函数是微软的所以为了移植性,最好使用标准的fopen函数。、为了在vs下屏蔽fopen的报警,需要设置如下。项目->属性->配置属性->C/C++ -> 预处理器 -> 预处理器定义,增加_C...
scara 机器人三四轴机械结构 滚珠丝杆螺母----旋转运动,花键螺母------轴向运动,可以看到杆上面有竖着的螺纹,而不是普通杆上面只有螺旋的螺纹竖着的螺纹就是花键用的。如果只动四轴电机,四轴的转动会让杆旋转,就像滚珠丝杆一样,但是同时杆也会上下动。原因如下:根据机械解耦矩阵:J3 = A3*M3+A34*M4 也就是说,如果三轴不动。M3 = 0. 那么4轴转动M4不为零的时候,杆也会跟着上下动。如果三轴也跟着相反方向转...
AF_INET与PF_INET区别 在写网络程序的时候,建立TCP socket: sock = socket(PF_INET, SOCK_STREAM, 0);然后在绑定本地地址或连接远程地址时需要初始化sockaddr_in结构,其中指定address family时一般设置为AF_INET,即使用IP。相关头文件中的定义:AF = Address Family PF = Protocol Famil...
SOCK_STREAM与SOCK_DGRAM的区别 对于网络socket的一些理解---------------------------------------------------------------------------------------------------------------SOCK_STREAM是有保障的(即能保证数据正确传送到对方)面向连接的SOCKET,多用于资料(如文件)传送。SOCK_DGRAM是无保障的面向消...
char *a[10]与char (*a)[10] 两种定义的不同 char *a[10];This declares array of 10 pointers to char . 十个指针Whereas , char (*a)[10];declares pointer to array of 10 char's 一个指针
c语言结构体嵌套的对齐方式 1:在代码中有结构体嵌套的方式,又需要获取每个变量的地址。那么需要了解结构体嵌套和单一结构体的一些对齐方面的规则。2:对于嵌入式的设备来说,对齐很重要,有些cpu不支持不对齐的访问方式,有的cpu支持,只是效率上会降低。3:arm中默认编译的时候会进行对齐。规则一:结构体中的第一个成员位置在偏移量0,之后每个变量的偏移量必须是它本身字节数的整数倍。规则二:如果结构体中嵌套结构体,那么嵌套的结构体的...
c语言 pow和sqrt注意 头文件:#include <math.h>sqrt() 用来求给定值的平方根,其原型为: double sqrt(double x);【参数】x 为要计算平方根的值。如果 x < 0,将会导致 domain error 错误,并把全局变量 errno 的值为设置为 EDOM。【返回值】返回 x 平方根。注意,使用 GCC 编译时请加入-lm。----------------...
c语言中的求整函数 1234567#include <math.h> double ceil(double x); double floor(double x); double round(double x);ceil(x)返回不小于x的最小整数值(然后转换为double型)。floor(x)返回不大于x的最大整数值。round(x)返回x的四舍五入整数值。给个例子test.c: ?12345678910...
rtems环境搭建(1) 转到linux平台的原因:在windows下开发的时候虽然使用了msys2,虚拟了类linux环境,安装rtems等都没有问题,但是因为要使用网络栈,libbsd的网络栈是由waf进行编译的,waf是一个python脚本。在msys2中配置waf的时候遇到问题,可能是因为msys2中路径带有windows特色,导致waf配置的时候无法识别rtems的路径。step1:下载ubuntu 16.04....
DMIPS/MHZ的解释 今天看arm处理器的时候这个单位不明白,网上搜索一下终于明白了,记录如下。DMIPS: Dhrystone Million Instructions executed Per Second :主要用于测整数计算能力。 其中: MIPS: Million Instructions executed Per Second,每秒百万条指令,用来计算同一秒内系统的处理能力,即每秒执行了多少百万条指令 ...
arm cache (1) 因为要将关键代码放到L2 cache中使用。所以,现在需要考虑 L2 cache的lockdown 功能,zynq wiki上面有这方面的介绍,网址如下,也有例程可以参考http://www.wiki.xilinx.com/Zynq-7000+AP+SoC+Boot+-+Locking+and+Executing+out+of+L2+Cache+Tech+Tip暂时记录下来,后面参考
关于”error conflicting types for function”编译错误的分析 在使用gcc编译C程序时,有时会碰到“error: conflicting types for ‘function’”的编译错误。从字面意义上理解,是说函数的定义和声明不一致。(一)首先我们看一个函数的定义和声明不一致的例子:#include int func(int a);int func(void) { return 0;}int main(void)
rtems 文件系统(15)-jffs2 研究(8)总结 1:解决了之前的问题后,有发现读写大文件有问题。因此查看了底层驱动,是底层驱动的问题,首先读的时候底层驱动只设置了32个 4byte的阈值,所以读取大块的时候分开读取。写的时候不能一次超过256,不能写到一个页上面。这些都是底层驱动和文件系统联系的问题。因为文件系统是很灵活的。所以底层驱动要和上层操作系统紧密结合。2: 经过验证,现在建立文件夹,删除文件,读写文件,删除文件,建立大的文件,进入
rtems 文件系统(15)-jffs2 研究(7)--->cd命令错误问题查找 [/flash] # cd a0jffs2_lookup()jffs2_igetilookupmalloc new_inode 6440a8 ####################################jffs2_read_inode(): inode->i_ino == 2[JFFS2 DBG] jffs2_do_read_inode: read inode
rtems 文件系统(15)-jffs2 研究(6) 发现不深入了解jffs2完全无法理解错误的根源。更别说找出错误了。还是脚踏实地慢慢来吧。根据5的一些输出信息。我来一步步分析吧输入mkdir命令后。会调用 jffs2_mknod函数,目录也是一个node1:首先分配一个jffs2_raw_inode类型2:进入jffs2_reserve_space函数,保留空间,如果需要保留的空间不够,会触发jffs2_garbage_colle
rtems 文件系统(15)-jffs2 研究(5)--测试打印记录mkdir,嵌套mkdir 记下来测试建立多个文件夹,和文件夹嵌套是否有问题。记录打印信息[/flash] # ls[/flash] # mkdir datajffs2_lookup()JFFS2: jffs2_reserve_space(): Requested 0x44 bytesJFFS2: jffs2_reserve_space(): alloc sem gotJFFS2: jffs2_f
rtems 文件系统(15)-jffs2 研究(4) 经过前面的分析。找到了问题所在,按照分析应该是一些擦除标志没有写入导致错误。追踪这个问题的代码从函数jffs2_erase_pending_blocks跟进去。内部调用了jffs2_erase_block,再调用jffs2_flash_erase。最终调用到底层驱动函数。发现底层驱动函数擦除的时候计算块的时候有问题。如果地址刚好是sector起始地址,并且擦除的数量是sector大小的时候,计
rtems 文件系统(15)-jffs2 研究(3) 下面考虑第一个问题JFFS2: Node totlen on flash (0xFFFFFFFF) != totlen from node ref (0x0000000C)这部分在jffs2_mark_node_obsolete中打印,因为调用这个函数的太多了,没法一个个打断点,所以我在报错的地方打个断点,然后看看能不能向后追溯。输入建立文件夹的命令,然后看打印信息向后追溯[/fl
rtems 文件系统(15)-jffs2 研究(2) 接着之前的说step6:1:接下来调用 jffs2_build_filesystem 函数去建立文件系统,首先是设置scan flag位,进入scan.c中进行扫描,调用的函数是jffs2_scan_medium其中有个配置是关于nand flash的CONFIG_JFFS2_FS_WRITEBUFFER,我使用的是nor,所以用不到,在网上找到解释如下JFFS2_FS_WRI
关于printf输出格式%#08x的解释 #代表的是在字符串前面加上0x。08表示输出8个字符。x是输出16进制当然你也可以写成0x%08x,但是这两种是有区别的。一个输出包括0x输出8bit,而第二种包含0x输出10bitint i = 7;printf("%#010x", i); // gives 0x00000007printf("0x%08x", i); // gives 0x00000007pri
rtems 文件系统(15)-jffs2 研究(1) 根据之前的结果,虽然能够挂载上,但是有很多问题,参考(12)中描述。因为对jffs2完全没有什么概念可言,只知道这是一个flash的文件系统,并且挂载的时候只提供了下面的信息给到jffs2.对于内部怎么操作完全无知。并且flash每次擦除都是一个块一个块的。比如删除一个东西的时候是否会删除其他部分?怎么保留下来的。还是挺好奇的。为了解决问题,只能硬着头皮看jffs2的源码。看一下它挂载
-Wno-pointer-sign 学习 gcc中char 和 unsigned char 有时候传递参数类型不匹配会有报警。比如我会得到报警当在(char*) 和(unsigned char* or signed char*)之间转换的时候,比如传入参数类型不一致。增加下面编译选项可以关闭该报警-Wno-pointer-signto switch off the warning
rtems 文件系统(14)-jffs2使用问题记录 问题记录1: 当我挂载好文件系统后,准备建立一个文件夹试试使用命令mkdir data 结果打印下面信息JFFS2: Node totlen on flash (0xFFFFFFFF) != totlen from node ref (0x0000000C)mkdir 'data' failed:但是后面再次调用mkdir指令的时候就成功了,创建其他的文件夹也成功了。---
rtems 文件系统(13)-flash 底层驱动 根据之前的描述, 只需要实现对应flash芯片的底层驱动就可以了。还是挺方便的。flash一部分作为存放代码,一部分作为文件系统使用,存放代码的部分属于核心部分,不允许随意改动。所以对flash整体的划分规划很重要。暂时想到分为两部分。对于是否那一部分需要加密等操作后续再考虑吧。因为使用的是xilinx的zynq 7000系列。所以先阅读手册。看看qspi的接口。这部分比较简单,主要是查看
rtems 文件系统(12)-flash jffs2 现在IMFS base file system已经建立起来了。到目前为止还是不了解怎么挂载其他的系统。因此查看rtems的wiki,看是否可以获取一些信息,并且看一下confdefs.h中关于文件系统这一部分。发现可以通过配置,增加jffs2的文件系统到rtems_filesystem_table中。要使用jffs2需要包含一个库函数。libjffs2.a在配置中增加#define CON
rtems shell (3)-初始化 配置完成后,下面需要进行初始化才能够使用shell可以很容易的连接到串口和telnet server。那么是怎么连接的呢?1:串口rtems_shell_init 产生一个task来运行rtems shell。调用者将自己挂起,并让 shell接管了控制台设备。当用户退出shell时,控制返回调用者。void start_shell(
rtems shell (2)-配置 配置rtems shell 。可以获取的命令是用户自己配置的。配置方式类似于confdefs.h如果配置所有命令(既不是filesystem management,也不是network相关的)那么只需要下面几行即可#define CONFIGURE_SHELL_COMMANDS_INIT#define CONFIGURE_SHELL_COMMANDS_ALL#include
rtems shell (1) 一直以来认为shell就是一些函数的接口。接触rtems以后,要系统的学习一下shellshell是一种交互方式,用来操作,诊断,配置等目的。rtems的shell是一种命令行的交互方式。一些命令和标准posix一致。其他是rtems具体的。用户debug和分析嵌入式系统。shell就是一个循环,读取输入,把输入作为命令的参数,他可以通过标准的串口或者是rtems的telnetd serv
rtems 文件系统(11) 前一篇文章对 jffs2有了一定的了解,也在rtems的 cpukit/libfs/jffs2中找到了对应的rtems移植好的该文件系统。当然还没有仔细的阅读源码。因为对IMFS部分还有些疑问。 imfs的源码也在cpukit/libfs/imfs中。这里面有各种文件操作函数的文件,初始化的框架跟踪了一次,有了一定了解。但是其他的各个文件比如mknod,mount命令都有对应的文件,但是这些函数是
rtems 文件系统(10)-jffs2 根据之前的了解。查看flash文件系统该怎么挂载呢?首先在confdefs.h中看到下面的说明/** * @defgroup ConfigFilesystems Filesystems and Mount Table Configuration * * @ingroup Configuration * * Defines to control the file system
rtems 文件系统(9) 随着对文件系统的进一步了解。继续查看手册。IMFS(In-Memory FileSystem)是一个全功能的POSIX文件系统,在memory中保存所有的信息。 每一个文件,设备,hard link 目录都被表示为一种数据结构,叫做jnode。该类型在cpukit/libfs/src/imfs/imfs.h中定义struct IMFS_jnode_tt { rtems_cha
rtems 文件系统(8) 实现文件系统的需求rtems的文件系统框架是兼容posix files 和 directories接口标准的。以下的文件系统特性产生了一个功能转换层。1:应用程序提供了一套标准的POSIX标准功能集,这些功能允许它们和文件,设备,目录进行接口。这些接口并不反映从属文件系统的实现类型。2:框架允许在base filesystem下面挂载不同类型的文件系统。3:定位文件信息的机制在
rtems 文件系统(7) 上一次说了base file system,那么理解了首先要有一个base file system,这个文件系统就是IMFS,有了这个base file system以后才能挂载其他的文件系统。我最后希望能够挂载一个flash的文件系统,但是现在还是不知道该怎么做?那么阅读手册中挂载mount和解除挂载unmount挂载点的概念1:挂载点必须是一个目录。可以有文件和其他目录在它下面
rtems 文件系统(6) base file system的理解通过跟踪源代码 ,rtems_filesystem_initialize跟踪下去。发现手册上写的都可以理解了• Initialization of mount table chain control structure 建立一个链表的mount结构• Allocation of ajnodestructure that will serve
rtems 文件系统(5)_3 之前讲到mount函数中会调用如下函数。那么这个函数中做了什么呢?下面对IMFS_initialize_support函数进行分析,该函数在cpukit/libfs/src/imfs/imfs_initsupp.c中。int IMFS_initialize_support( rtems_filesystem_mount_table_entry_t *mt_entry, const vo
文件系统的概念 最近在看rtems的文件系统。对于操作系统知之甚少,所以百度了一下,进行总结首先要明白的是“什么是文件系统”,文件系统是对一个存储设备上的数据和元数据进行组织的机制。这种机制有利于用户和操作系统的交互。在一篇oracle的技术文章中看到这样一句话“尽管内核是 Linux 的核心,但文件却是用户与操作系统交互所采用的主要工具。这对 Linux 来说尤其如此,这是因为在 UNIX
rtems 文件系统(5)_2 接之前的(5)_1. mount函数的分析。如果找到了rtems_filesystem_fsmount_me_t类型的该文件系统的处理函数,那么下面就可以继续安装了,接下来是alloc_mount_table_entry,该函数在在cpukit/libcsupport/src/mount.c中定义,该函数主要是分配内存,多是字符串的处理。rtems_filesystem_mount_tab
rtems 文件系统(5)_1 之前讲到 rtems_filesystem_initialize 函数中调用了mount函数,在该函数中实现了文件系统的挂载,那么到底怎么挂载的呢?下面具体分析一下int mount( const char *source, const char *target, const char
rtems start.s中一些汇编字符的学习 在看start.s时有些汇编不理解,1: .arm是什么意思?2:.globl _start 的作用?3:.section ".bsp_start_text", "ax" 的意思?通过下面的解释就一目了然了。一、汇编一般使用的场合:(1)、汇编语言在ARM中一般用在启动代码中,比如Bootloader 初始化时
rtems 文件系统(4) 上一篇中说道 这个地方是入口,再向上追溯,可以找到在cpukit/libcsupport/include/rtems/libio.h中定义了这个函数指针类型,typedef void (*rtems_libio_helper)(void);然后下面定义了一个该类型的函数指针。 rtems_fs_init_helperconst rtems_libio_helper rtems_
rtems 文件系统(3) 通过查询源码,有一点点模糊的感觉,还是接着看文档比较靠谱。调用rtems_filesystem_initialize()函数将会挂载‘In Memory File System’作为 the base filesystem初始化过程在 cpukit/sapi/include/confdefs.h 中有定义#ifdef CONFIGURE_INIT //一般都会定义这个宏。co
rtems文件系统(2) 看到rtems手册上写pathname evaluation process 路径评估过程,因为对文件系统理解不多。暂时理解为实现文件系统时需要考虑的功能------- 路径的检查功能在 RTEMS 文件系统结构下的路径检查处理包括三部分:1)路径检查handler函数 2)跨越挂载点的路径检查3)系统节点信息表数据结构 1:路径检查函数包括 patheval()和
rtems文件系统(1) 本文主要整理了 rtems 文件系统相关的知识。rtems 架构支持• Mountable file systems 可挂载• Hierarchical file system directory structure 分级• POSIX compliant set of routines for the manipulation of files and directories p
英文中 vi和vt的区别 V:verb是动词的总称动词分为及物动词( transitive verb简称VT),不及物动词(intransitive verb简称VI)答:实义动词可根据是否需要宾语分为及物动词和不及物动词。不及物动词后面不跟宾语, 也没有被动语态; 及物动词后面一定要有宾语;及物动词(transitive verb)后面要跟宾语,意义才完整。例如:You muxt consider the matter
#define几点注意事项 1、 用无参宏定义一个简单的常量#define LEN 12这个是最常见的用法,但也会出错。比如下面几个知识点你会吗?可以看下:(1)#define NAME "zhangyuncong"程序中有"NAME"则,它会不会被替换呢?(2)#define 0x abcd可以吗?也就是说,可不可以用不是标识符的字母替
数组作为函数参数的几点说明 如果一个函数以一维数组为参数,我们可以这样声明这个函数void func(int* a) ;void func(int a[]) ;void func(int a[3]) ;实际上,这三种形式是等价的,在使用数组做参数时,编译器会自动将数组名转换为指向数组第一个元素的指针,为什么呢?这要从参数的传递方式说起,参数有三种传递方式,按值传递,按指针传递,按引用传递,分别如下
GCC __attribute__ ((weak)) 看rtems库的是否发现这个地方不懂,就搜索了一下,下面的文章让我豁然开朗。GCC中的弱符号与强符号我们经常在编程中碰到一种情况叫符号重复定义。多个目标文件中含有相同名字全局符号的定义,那么这些目标文件链接的时候将会出现符号重复定义的错误。比如我们在目标文件A和目标文件B都定义了一个全局整形变量global,并将它们都初始化,那么链接器将A和B进行链接时会报错:
float double 和long double IEEE754浮点数的表示方法。C语言里对float类型数据的表示范围为-3.4*10^38~+3.4*10^38。double为-1.7*10^-308~1.7*10^308,long double为-1.2*10^-4932~1.2*10^4932.类型比特(位)数有效数字数值范围float
hash table 原理和实现 最近需要用到hash table来作为数据库使用。对其进行学习。下面的文章是一个不错的开始什么是哈希表哈希表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即key,即可查找到其对应的值。哈希的思路很简单,如果所有的键都是整数,那么就可以使用一个简单的无序数组来实现:将键作为索引,值即为其对应的值,这样就可以快速访问任意键的值。这是对于简
linker -l的使用 在使用xilinx sdk的时候,添加了rtems插件,在rtems下要增加库的时候,-l后面的库名字一直设置不对,后面查询了手册,发现,原来它会自动在前面加上lib,在后面加上.a 所以在界面上只需要写std就好了,实际他回去找libstd.a这个库,之前我写上全称,他总是找不到-llibrary-l librarySearch the library named lib
warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] 下面的文章详细介绍了这个warning的来源和解决方法。也可以关闭优化,当然关闭优化并不是最终解决方法。down voteacceptedFirst off, let's examine why you get the aliasing violation warnings.Aliasing rules simply say that y
BSS段清零的原因 BSS段清零的原因是因为这个段是BSS 要说为什么要有BSS的话,历史就比较久远了。 BSS段我所知道的起源是Unix最初的时候(当然,不排除可能有更早的情况)。变量分两种:局部变量、全局变量。根据C语法的规定,局部变量不设置初始值的时候,其初始值是不确定的,局部变量(不含静态局部变量)的存储位置位于栈上,具体位置不固定。全局变量(和静态局部变量)有专门数据段存储,初始值是0,具体位置
.section 后面跟着的“ax”是什么意思 今天看到如下描述不理解,主要是ax,搜索网络得到如下答案。.section".bsp_start_text", "ax""ax"表示该节区可分配并且可执行*/ ax是 allocation execute的缩写
linker 文件中的keep 查看linker文件的时候发现不理解 keep,查询网络后有了理解。keep相当于告诉编译器,这部分不要被垃圾回收。There's a --gc-sections option that enables garbage collection of unused input sections. The default behavior (of not performing this garb
__attribute__ 编译属性 今天看到下面语句不理解,查询了一下。作为记录__attribute__((section(".bsp_start_text")))__attribute__这个关键词是GNU编译器中的编译属性,ARM编译器也支持这个用法。__attribute__主要用于改变所声明或定义的函数或 数据的特性,它有很多子项,用于改变作用对象的特性。比如对函数,noline将禁止进行内联扩展、noretu
naked 特性 对于nake的不理解,查看了arm的文档。发现就是指定编译器不要产生序言和结尾。只能用__asm This attribute tells the compiler that the function is an embedded assembly function. You can write the body of the function entirely in assembly c
大端和小端存储 如果将一个32位的整数0x12345678存放到一个整型变量(int)中,这个整型变量采用大端或者小端模式在内存中的存储由下表所示。为简单起见,本文使用OP0表示一个32位数据的最高字节MSB(Most Significant Byte),使用OP3表示一个32位数据最低字节LSB(Least Significant Byte)。 地址偏移大端模
gcc 编译选项 一些编译选项要了解,比如-march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard -marm可以参考下面的链接https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html
汇编指令 定义一个函数入口的宏的解释 经常,我们在看代码的时候对一些汇编的directives不明白。那么以下面为例,#define FUNCTION_THUMB_ENTRY(name) \ .thumb; \ .thumb_func; \ .align 2; \ .globl name; \ .type name, %function; \ name:The .thum
c语言#和## 的用法 关于#和##在C语言的宏中,#的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号。比如下面代码中的宏:#define WARN_IF(EXP) do{ if (EXP) fprintf(stderr, "Warning: " #EXP "/n"); } while(0)那么
查看gcc预编译的宏 在阅读很多源码的时候经常被一些宏定义搞晕,因为这些宏定义在源码中没有定义,那么就有可能是编译器预定义的。至于编译器的学习,那是另外一部分,暂时不考虑但是我们可以查看预编译的宏,采用gcc -E -dM - -E 预处理后即停止,不进行编译.预处理后的代码送往标准输出. GCC忽略任何不需要预处理的输入文件.-dM 告诉预处理器输出有效的宏定义列表(预处
ARM 汇编 .extern 和.global .global.global关键字用来让一个符号对链接器可见,可以供其他链接对象模块使用。 .global _start 让_start符号成为可见的标示符,这样链接器就知道跳转到程序中的什么地方并开始执行。linux寻找这个 _start标签作为程序的默认进入点。在汇编和C混合编程中,在GNU ARM编译环境下,汇编程序中要使用.global伪操作声明汇编程序为全局的函数
ARM pc指针低两位为何为0 PC是32位的(31:0)。ARM状态下,指令是32位的,指令地址都是4字节对齐,所以PC值肯定是4的倍数,所以最低两位(位[1:0])肯定为0,前面的30位位[31:2]用于保存PC如果是thumb状态,指令是16位的,指令地址是2字节对齐。
备注内存访问顺序的文章 备注内存访问顺序的文章,有时间看看https://community.arm.com/processors/b/blog/posts/memory-access-ordering---an-introduction
DMB DSB ISB 简介 DMB: Data memory barrier理解DMB指令,先看下面例子,在core 0和core1上同时跑两个不同的指令(如下表所示)core 0core 1Write A;Write B;Load B;Load A;这里core0在执行两个指令,写A B两个值的时候,可能会发生乱序也可能Write A时发生Ca
内存隔离指令(memory barrier instructions)的使用 像ARM7TDMI这样经典的ARM处理器会按照程序的顺序来执行指令或访问数据。而最新的ARM处理器会对执行指令和访问数据的顺序进行优化。举个例子,ARM v6/v7的处理器会对以下指令顺序进行优化。 [cpp] view plain copyLDR r0, [r1] ; 从普通/可Cache的内存中读取,并导致cache未命中
volatile和 memory barrier volatile c语言中 volatile 关键字用于告诉编译器,严禁将此处的汇编语句与其它的语句重组合优化。volatile只能保证编译器不会做乱序执行优化. 1. 不对*p操作生成乱序指令(通常如此,具体请看后面的解释)(比如条件判断) 2. 每次从*p取数据的时候,一定会进行一次访存操作,哪怕前面不久才取过*p
gcc内嵌汇编 __asm__ __volatile__ 理解 gcc内嵌汇编简介在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C 变量,你只要告诉程序中C语言表达式与汇编指令操作数之间的对应关系即可, GCC会自动插入代码完成必要的操作。1、简单的内嵌汇编例:__asm__ __volatile__("hlt"); "__asm__"表示后面的代码为内嵌汇编