ftx的原函数的简单介绍

古泉财经 114 0

本篇文章给大家谈谈ftx的原函数,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

matlab中ftx()是什么意思

是对x轴也就是横向做fft,也就是fft(matrix,[],2);

因为有时候信号是二维数组,你做FFT要说明横向还是纵向。

还有fty,他等于fft(matrix),这里不像ftx那么多参数,因为fft这个函数在matlab中默认对纵向数据进行操作。

这俩函数都需要写函数文件进行自定义的

已知x=ftxdt,其中fx为连续函数

lim(x→a)F(x)

=lim(x→a){[x²∫ (x→a) f(t)dt]/(x-a)

=lim(x→a)[2x∫ (x→a) f(t)dt-x²f(x)]

=-a²f(a)

这里,∫x趋向a f(t)dt是按不定下限积分做ftx的原函数的,即x为下限、a为上限

高数 请教一道关于多元复合函数微分的证明题 谢谢!

xfx’+yfy’+zfz’=nf(x,y,z)

t(xftx’+yfty’+zftz’)=nf(tx,ty,tz)

df(tx,ty,tz)/dt=xftx’+yfty’+zftz'=[nf(tx,ty,tz)]/t

df/f=ndt/t

f(tx,ty,tz)=Ct^n

当t=1时 f(x,y,z)=C

即 f(tx,ty,tz)=t^n f(x,y,z)

使用C#实现串口通讯,接受和控制单片机。

通常,在C#中实现串口通信,ftx的原函数我们有四种方法:

第一:通过MSCOMM控件这是最简单的,最方便的方法。可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册。可以访问

一个外国人写的教程

第二:微软在.NET新推出了一个串口控件,基于.NET的P/Invoke调用方法实现,详细的可以访问微软网站

Serial Comm

Use P/Invoke to Develop a .NET Base Class Library for Serial Device Communications

第三:就是用第三方控件啦,可一般都要付费的,不太合实际,何况楼主不喜欢,不作考虑

第四:自己用API写串口通信,这样难度高点,但对于我们来说,可以方便实现自己想要的各种功能。

我们采用第四种方法来实现串口通信,用现成的已经封装好的类库,常见两个串口操作类是JustinIO和SerialStreamReader。介绍JustinIO的使用方法:

打开串口:

函数原型:public void Open()

说明:打开事先设置好的端口

示例:

using JustinIO;

static JustinIO.CommPort ss_port = new JustinIO.CommPort();

ss_port.PortNum = COM1; //端口号

ss_port.BaudRate = 19200; //串口通信波特率

ss_port.ByteSize = 8; //数据位

ss_port.Parity = 0; //奇偶校验

ss_port.StopBits = 1;//停止位

ss_port.ReadTimeout = 1000; //读超时

try

{

if (ss_port.Opened)

{

ss_port.Close();

ss_port.Open(); //打开串口

}

else

{

ss_port.Open();//打开串口

}

return true;

}

catch(Exception e)

{

MessageBox.Show("错误:" + e.Message);

return false;

}

写串口:

函数原型:public void Write(byte[] WriteBytes)

WriteBytes 就是ftx的原函数你的写入的字节,注意,字符串要转换成字节数组才能进行通信

示例:

ss_port.Write(Encoding.ASCII.GetBytes("AT+CGMI\r")); //获取手机品牌

读串口:

函数原型:public byte[] Read(int NumBytes)

NumBytes 读入缓存数,注意读取来的是字节数组,要实际应用中要进行字符转换

示例:

string response = Encoding.ASCII.GetString(ss_port.Read(128)); //读取128个字节缓存

关闭串口:

函数原型:ss_port.Close()

示例:

ss_port.Close();

整合代码:

using System;

using System.Runtime.InteropServices;

namespace JustinIO {

class CommPort {

public int PortNum;

public int BaudRate;

public byte ByteSize;

public byte Parity; // 0-4=no,odd,even,mark,space

public byte StopBits; // 0,1,2 = 1, 1.5, 2

public int ReadTimeout;

//comm port win32 file handle

private int hComm = -1;

public bool Opened = false;

//win32 api constants

private const uint GENERIC_READ = 0x80000000;

private const uint GENERIC_WRITE = 0x40000000;

private const int OPEN_EXISTING = 3;

private const int INVALID_HANDLE_VALUE = -1;

[StructLayout(LayoutKind.Sequential)]

public struct DCB {

//taken from c struct in platform sdk

public int DCBlength; // sizeof(DCB)

public int BaudRate; // current baud rate

/* these are the c struct bit fields, bit twiddle flag to set

public int fBinary; // binary mode, no EOF check

public int fParity; // enable parity checking

public int fOutxCtsFlow; // CTS output flow control

public int fOutxDsrFlow; // DSR output flow control

public int fDtrControl; // DTR flow control type

public int fDsrSensitivity; // DSR sensitivity

public int fTXContinueOnXoff; // XOFF continues Tx

public int fOutX; // XON/XOFF out flow control

public int fInX; // XON/XOFF in flow control

public int fErrorChar; // enable error replacement

public int fNull; // enable null stripping

public int fRtsControl; // RTS flow control

public int fAbortOnError; // abort on error

public int fDummy2; // reserved

*/

public uint flags;

public ushort wReserved; // not currently used

public ushort XonLim; // transmit XON threshold

public ushort XoffLim; // transmit XOFF threshold

public byte ByteSize; // number of bits/byte, 4-8

public byte Parity; // 0-4=no,odd,even,mark,space

public byte StopBits; // 0,1,2 = 1, 1.5, 2

public char XonChar; // Tx and Rx XON character

public char XoffChar; // Tx and Rx XOFF character

public char ErrorChar; // error replacement character

public char EofChar; // end of input character

public char EvtChar; // received event character

public ushort wReserved1; // reserved; do not use

}

[StructLayout(LayoutKind.Sequential)]

private struct COMMTIMEOUTS {

public int ReadIntervalTimeout;

public int ReadTotalTimeoutMultiplier;

public int ReadTotalTimeoutConstant;

public int WriteTotalTimeoutMultiplier;

public int WriteTotalTimeoutConstant;

}

[StructLayout(LayoutKind.Sequential)]

private struct OVERLAPPED {

public int Internal;

public int InternalHigh;

public int Offset;

public int OffsetHigh;

public int hEvent;

}

[DllImport("kernel32.dll")]

private static extern int CreateFile(

string lpFileName, // file name

uint dwDesiredAccess, // access mode

int dwShareMode, // share mode

int lpSecurityAttributes, // SD

int dwCreationDisposition, // how to create

int dwFlagsAndAttributes, // file attributes

int hTemplateFile // handle to template file

);

[DllImport("kernel32.dll")]

private static extern bool GetCommState(

int hFile, // handle to communications device

ref DCB lpDCB // device-control block

);

[DllImport("kernel32.dll")]

private static extern bool BuildCommDCB(

string lpDef, // device-control string

ref DCB lpDCB // device-control block

);

[DllImport("kernel32.dll")]

private static extern bool SetCommState(

int hFile, // handle to communications device

ref DCB lpDCB // device-control block

);

[DllImport("kernel32.dll")]

private static extern bool GetCommTimeouts(

int hFile, // handle to comm device

ref COMMTIMEOUTS lpCommTimeouts // time-out values

);

[DllImport("kernel32.dll")]

private static extern bool SetCommTimeouts(

int hFile, // handle to comm device

ref COMMTIMEOUTS lpCommTimeouts // time-out values

);

[DllImport("kernel32.dll")]

private static extern bool ReadFile(

int hFile, // handle to file

byte[] lpBuffer, // data buffer

int nNumberOfBytesToRead, // number of bytes to read

ref int lpNumberOfBytesRead, // number of bytes read

ref OVERLAPPED lpOverlapped // overlapped buffer

);

[DllImport("kernel32.dll")]

private static extern bool WriteFile(

int hFile, // handle to file

byte[] lpBuffer, // data buffer

int nNumberOfBytesToWrite, // number of bytes to write

ref int lpNumberOfBytesWritten, // number of bytes written

ref OVERLAPPED lpOverlapped // overlapped buffer

);

[DllImport("kernel32.dll")]

private static extern bool CloseHandle(

int hObject // handle to object

);

[DllImport("kernel32.dll")]

private static extern uint GetLastError();

public void Open() {

DCB dcbCommPort = new DCB();

COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS();

// OPEN THE COMM PORT.

hComm = CreateFile("COM" + PortNum ,GENERIC_READ | GENERIC_WRITE,0, 0,OPEN_EXISTING,0,0);

// IF THE PORT CANNOT BE OPENED, BAIL OUT.

if(hComm == INVALID_HANDLE_VALUE) {

throw(new ApplicationException("Comm Port Can Not Be Opened"));

}

// SET THE COMM TIMEOUTS.

GetCommTimeouts(hComm,ref ctoCommPort);

ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout;

ctoCommPort.ReadTotalTimeoutMultiplier = 0;

ctoCommPort.WriteTotalTimeoutMultiplier = 0;

ctoCommPort.WriteTotalTimeoutConstant = 0;

SetCommTimeouts(hComm,ref ctoCommPort);

// SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.

GetCommState(hComm, ref dcbCommPort);

dcbCommPort.BaudRate=BaudRate;

dcbCommPort.flags=0;

//dcb.fBinary=1;

dcbCommPort.flags|=1;

if (Parity0)

{

//dcb.fParity=1

dcbCommPort.flags|=2;

}

dcbCommPort.Parity=Parity;

dcbCommPort.ByteSize=ByteSize;

dcbCommPort.StopBits=StopBits;

if (!SetCommState(hComm, ref dcbCommPort))

{

//uint ErrorNum=GetLastError();

throw(new ApplicationException("Comm Port Can Not Be Opened"));

}

//unremark to see if setting took correctly

//DCB dcbCommPort2 = new DCB();

//GetCommState(hComm, ref dcbCommPort2);

Opened = true;

}

public void Close() {

if (hComm!=INVALID_HANDLE_VALUE) {

CloseHandle(hComm);

}

}

public byte[] Read(int NumBytes) {

byte[] BufBytes;

byte[] OutBytes;

BufBytes = new byte[NumBytes];

if (hComm!=INVALID_HANDLE_VALUE) {

OVERLAPPED ovlCommPort = new OVERLAPPED();

int BytesRead=0;

ReadFile(hComm,BufBytes,NumBytes,ref BytesRead,ref ovlCommPort);

OutBytes = new byte[BytesRead];

Array.Copy(BufBytes,OutBytes,BytesRead);

}

else {

throw(new ApplicationException("Comm Port Not Open"));

}

return OutBytes;

}

public void Write(byte[] WriteBytes) {

if (hComm!=INVALID_HANDLE_VALUE) {

OVERLAPPED ovlCommPort = new OVERLAPPED();

int BytesWritten = 0;

WriteFile(hComm,WriteBytes,WriteBytes.Length,ref BytesWritten,ref ovlCommPort);

}

else {

throw(new ApplicationException("Comm Port Not Open"));

}

}

}

}

}

由于篇幅,以及串口通信涉及内容广泛,我在这里只讲这些。

Linux 之mutex 源码分析

 mutex相关的函数并不是linux kernel实现的,而是glibc实现的,源码位于nptl目录下。

首先说数据结构:

typedef union

{

  struct

  {

    int __lock;

    unsigned int __count;

    int __owner;

    unsigned int __nusers;

    /* KIND must stay at this position in the structure to maintain

       binary compatibility.  */

    int __kind;

    int __spins;

  } __data;

  char __size[__SIZEOF_PTHREAD_MUTEX_T];

  long int __align;

} pthread_mutex_t;

 int __lock;  资源竞争引用计数

 int __kind; 锁类型,init 函数中mutexattr 参数传递,该参数可以为NULL,一般为 PTHREAD_MUTEX_NORMAL

结构体其他元素暂时不了解,以后更新。

/*nptl/pthread_mutex_init.c*/

int

__pthread_mutex_init (mutex, mutexattr)

     pthread_mutex_t *mutex;

     const pthread_mutexattr_t *mutexattr;

{

  const struct pthread_mutexattr *imutexattr;

  assert (sizeof (pthread_mutex_t) = __SIZEOF_PTHREAD_MUTEX_T);

  imutexattr = (const struct pthread_mutexattr *) mutexattr ?: default_attr;

  /* Clear the whole variable.  */

  memset (mutex, '\0', __SIZEOF_PTHREAD_MUTEX_T);

  /* Copy the values from the attribute.  */

  mutex-__data.__kind = imutexattr-mutexkind ~0x80000000;

  /* Default values: mutex not used yet.  */

  // mutex-__count = 0;        already done by memset

  // mutex-__owner = 0;        already done by memset

  // mutex-__nusers = 0;        already done by memset

  // mutex-__spins = 0;        already done by memset

  return 0;

}

init函数就比较简单了,将mutex结构体清零,设置结构体中__kind属性。

/*nptl/pthread_mutex_lock.c*/

int

__pthread_mutex_lock (mutex)

     pthread_mutex_t *mutex;

{

  assert (sizeof (mutex-__size) = sizeof (mutex-__data));

  pid_t id = THREAD_GETMEM (THREAD_SELF, tid);

  switch (__builtin_expect (mutex-__data.__kind, PTHREAD_MUTEX_TIMED_NP))

    {

     …

    default:

      /* Correct code cannot set any other type.  */

    case PTHREAD_MUTEX_TIMED_NP:

    simple:

      /* Normal mutex.  */

      LLL_MUTEX_LOCK (mutex-__data.__lock);

      break;

  …

  }

  /* Record the ownership.  */

  assert (mutex-__data.__owner == 0);

  mutex-__data.__owner = id;

#ifndef NO_INCR

  ++mutex-__data.__nusers;

#endif

  return 0;

}

该函数主要是调用LLL_MUTEX_LOCK, 省略部分为根据mutex结构体__kind属性不同值做些处理。

宏定义函数LLL_MUTEX_LOCK最终调用,将结构体mutex的__lock属性作为参数传递进来

#define __lll_mutex_lock(futex)                                                \

  ((void) ({                                                                \

    int *__futex = (futex);                                                \

    if (atomic_compare_and_exchange_bool_acq (__futex, 1, 0) != 0)        \

      __lll_lock_wait (__futex);                                        \

  }))

atomic_compare_and_exchange_bool_acq (__futex, 1, 0)宏定义为:

#define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \

  ({ __typeof (mem) __gmemp = (mem);                                      \

     __typeof (*mem) __gnewval = (newval);                              \

      \

     *__gmemp == (oldval) ? (*__gmemp = __gnewval, 0) : 1; })

这个宏实现的功能是:

如果mem的值等于oldval,则把newval赋值给mem,放回0,否则不做任何处理,返回1.

由此可以看出,当mutex锁限制的资源没有竞争时,__lock 属性被置为1,并返回0,不会调用__lll_lock_wait (__futex); 当存在竞争时,再次调用lock函数,该宏不做任何处理,返回1,调用__lll_lock_wait (__futex);

void

__lll_lock_wait (int *futex)

{

  do

    {

      int oldval = atomic_compare_and_exchange_val_acq (futex, 2, 1);

      if (oldval != 0)

lll_futex_wait (futex, 2);

    }

  while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0);

}

atomic_compare_and_exchange_val_acq (futex, 2, 1); 宏定义:

/* The only basic operation needed is compare and exchange.  */

#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \

  ({ __typeof (mem) __gmemp = (mem);                                      \

     __typeof (*mem) __gret = *__gmemp;                                      \

     __typeof (*mem) __gnewval = (newval);                              \

      \

     if (__gret == (oldval))                                              \

       *__gmemp = __gnewval;                                              \

     __gret; })

这个宏实现的功能是,当mem等于oldval时,将mem置为newval,始终返回mem原始值。

此时,futex等于1,futex将被置为2,并且返回1. 进而调用

lll_futex_wait (futex, 2);

#define lll_futex_timed_wait(ftx, val, timespec)                        \

({                                                                        \

   DO_INLINE_SYSCALL(futex, 4, (long) (ftx), FUTEX_WAIT, (int) (val),        \

     (long) (timespec));                                \

   _r10 == -1 ? -_retval : _retval;                                        \

})

该宏对于不同的平台架构会用不同的实现,采用汇编语言实现系统调用。不过确定的是调用了Linux kernel的futex系统调用。

futex在linux kernel的实现位于:kernel/futex.c

SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,

struct timespec __user *, utime, u32 __user *, uaddr2,

u32, val3)

{

struct timespec ts;

ktime_t t, *tp = NULL;

u32 val2 = 0;

int cmd = op FUTEX_CMD_MASK;

if (utime (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||

      cmd == FUTEX_WAIT_BITSET ||

      cmd == FUTEX_WAIT_REQUEUE_PI)) {

if (copy_from_user(ts, utime, sizeof(ts)) != 0)

return -EFAULT;

if (!timespec_valid(ts))

return -EINVAL;

t = timespec_to_ktime(ts);

if (cmd == FUTEX_WAIT)

t = ktime_add_safe(ktime_get(), t);

tp = t;

}

/*

 * requeue parameter in 'utime' if cmd == FUTEX_*_REQUEUE_*.

 * number of waiters to wake in 'utime' if cmd == FUTEX_WAKE_OP.

 */

if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE ||

    cmd == FUTEX_CMP_REQUEUE_PI || cmd == FUTEX_WAKE_OP)

val2 = (u32) (unsigned long) utime;

return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);

}

futex具有六个形参,pthread_mutex_lock最终只关注了前四个。futex函数对参数进行判断和转化之后,直接调用do_futex。

long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,

u32 __user *uaddr2, u32 val2, u32 val3)

{

int clockrt, ret = -ENOSYS;

int cmd = op FUTEX_CMD_MASK;

int fshared = 0;

if (!(op FUTEX_PRIVATE_FLAG))

fshared = 1;

clockrt = op FUTEX_CLOCK_REALTIME;

if (clockrt cmd != FUTEX_WAIT_BITSET cmd != FUTEX_WAIT_REQUEUE_PI)

return -ENOSYS;

switch (cmd) {

case FUTEX_WAIT:

val3 = FUTEX_BITSET_MATCH_ANY;

case FUTEX_WAIT_BITSET:

ret = futex_wait(uaddr, fshared, val, timeout, val3, clockrt);

break;

         …

default:

ret = -ENOSYS;

}

return ret;

}

省略部分为对其他cmd的处理,pthread_mutex_lock函数最终传入的cmd参数为FUTEX_WAIT,所以在此只关注此分之,分析futex_wait函数的实现。

static int futex_wait(u32 __user *uaddr, int fshared,

      u32 val, ktime_t *abs_time, u32 bitset, int clockrt)

{

struct hrtimer_sleeper timeout, *to = NULL;

struct restart_block *restart;

struct futex_hash_bucket *hb;

struct futex_q q;

int ret;

           … … //delete parameters check and convertion

retry:

/* Prepare to wait on uaddr. */

ret = futex_wait_setup(uaddr, val, fshared, q, hb);

if (ret)

goto out;

/* queue_me and wait for wakeup, timeout, or a signal. */

futex_wait_queue_me(hb, q, to);

… … //other handlers

return ret;

}

futex_wait_setup 将线程放进休眠队列中,

futex_wait_queue_me(hb, q, to);将本线程休眠,等待唤醒。

唤醒后,__lll_lock_wait函数中的while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0); 语句将被执行,由于此时futex在pthread_mutex_unlock中置为0,所以atomic_compare_and_exchange_bool_acq (futex, 2, 0)语句将futex置为2,返回0. 退出循环,访问用户控件的临界资源。

/*nptl/pthread_mutex_unlock.c*/

int

internal_function attribute_hidden

__pthread_mutex_unlock_usercnt (mutex, decr)

     pthread_mutex_t *mutex;

     int decr;

{

  switch (__builtin_expect (mutex-__data.__kind, PTHREAD_MUTEX_TIMED_NP))

    {

   … …

    default:

      /* Correct code cannot set any other type.  */

    case PTHREAD_MUTEX_TIMED_NP:

    case PTHREAD_MUTEX_ADAPTIVE_NP:

      /* Normal mutex.  Nothing special to do.  */

      break;

    }

  /* Always reset the owner field.  */

  mutex-__data.__owner = 0;

  if (decr)

    /* One less user.  */

    --mutex-__data.__nusers;

  /* Unlock.  */

  lll_mutex_unlock (mutex-__data.__lock);

  return 0;

}

省略部分是针对不同的__kind属性值做的一些处理,最终调用 lll_mutex_unlock。

该宏函数最终的定义为:

#define __lll_mutex_unlock(futex)                        \

  ((void) ({                                                \

    int *__futex = (futex);                                \

    int __val = atomic_exchange_rel (__futex, 0);        \

\

    if (__builtin_expect (__val 1, 0))                \

      lll_futex_wake (__futex, 1);                        \

  }))

atomic_exchange_rel (__futex, 0);宏为:

#define atomic_exchange_rel(mem, value) \

  (__sync_synchronize (), __sync_lock_test_and_set (mem, value))

实现功能为:将mem设置为value,返回原始mem值。

__builtin_expect (__val 1, 0) 是编译器优化语句,告诉编译器期望值,也就是大多数情况下__val 1 ?是0,其逻辑判断依然为if(__val 1)为真的话执行 lll_futex_wake。

现在分析,在资源没有被竞争的情况下,__futex 为1,那么返回值__val则为1,那么 lll_futex_wake (__futex, 1);        不会被执行,不产生系统调用。 当资源产生竞争的情况时,根据对pthread_mutex_lock 函数的分析,__futex为2, __val则为2,执行 lll_futex_wake (__futex, 1); 从而唤醒等在临界资源的线程。

lll_futex_wake (__futex, 1); 最终会调动同一个系统调用,即futex, 只是传递的cmd参数为FUTEX_WAKE。

在linux kernel的futex实现中,调用

static int futex_wake(u32 __user *uaddr, int fshared, int nr_wake, u32 bitset)

{

struct futex_hash_bucket *hb;

struct futex_q *this, *next;

struct plist_head *head;

union futex_key key = FUTEX_KEY_INIT;

int ret;

if (!bitset)

return -EINVAL;

ret = get_futex_key(uaddr, fshared, key);

if (unlikely(ret != 0))

goto out;

hb = hash_futex(key);

spin_lock(hb-lock);

head = hb-chain;

plist_for_each_entry_safe(this, next, head, list) {

if (match_futex (this-key, key)) {

if (this-pi_state || this-rt_waiter) {

ret = -EINVAL;

break;

}

/* Check if one of the bits is set in both bitsets */

if (!(this-bitset bitset))

continue;

wake_futex(this);

if (++ret = nr_wake)

break;

}

}

spin_unlock(hb-lock);

put_futex_key(fshared, key);

out:

return ret;

}

该函数遍历在该mutex上休眠的所有线程,调用wake_futex进行唤醒,

static void wake_futex(struct futex_q *q)

{

struct task_struct *p = q-task;

/*

 * We set q-lock_ptr = NULL _before_ we wake up the task. If

 * a non futex wake up happens on another CPU then the task

 * might exit and p would dereference a non existing task

 * struct. Prevent this by holding a reference on p across the

 * wake up.

 */

get_task_struct(p);

plist_del(q-list, q-list.plist);

/*

 * The waiting task can free the futex_q as soon as

 * q-lock_ptr = NULL is written, without taking any locks. A

 * memory barrier is required here to prevent the following

 * store to lock_ptr from getting ahead of the plist_del.

 */

smp_wmb();

q-lock_ptr = NULL;

wake_up_state(p, TASK_NORMAL);

put_task_struct(p);

}

wake_up_state(p, TASK_NORMAL);  的实现位于kernel/sched.c中,属于linux进程调度的技术。

ftx的原函数的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于、ftx的原函数的信息别忘了在本站进行查找喔。

标签: #ftx的原函数

  • 评论列表

留言评论