久久久国产精品视频袁燕,99re久久精品国产,亚洲欧美日韩国产综合v,天天躁夜夜躁狠狠久久,激情五月婷婷激情五月婷婷

一口Linux
認(rèn)證:優(yōu)質(zhì)創(chuàng)作者
作者動態(tài)
某通信公司筆試題,你會做幾道?
1星期前
10種初學(xué)者最常見的c語言段錯誤實例及原因分析
05-30 12:13
linux系統(tǒng)監(jiān)控工具小神器:btop
05-17 17:37
有沒有權(quán)貴開后門讓子女做軟件開發(fā)人員?
05-10 23:36
一文包你學(xué)會網(wǎng)絡(luò)數(shù)據(jù)抓包
03-15 09:26

某通信公司筆試題,你會做幾道?

筆試部分

1.描述下面代碼中兩個static各自的含義:

static void func(void){    static unsigned int i; }

參考答案:

  1. 行1,static表示靜態(tài)函數(shù),該函數(shù)只有當(dāng)前文件的其他函數(shù)才可以調(diào)用它

  2. 行3,局部靜態(tài)變量

    生存周期:從程序運行到程序結(jié)束

    作用域:只有當(dāng)前函數(shù)才可以訪問

    段位置:全局data段【不是棧區(qū)】,并且每次訪問都會保存上一次執(zhí)行的結(jié)果

2. 寫出執(zhí)行下面代碼后變量a的值:

unsigned int a,b=3;void move(unsigned int *p,unsigned int val){ p=&val;      }void main(void){ a = b++; move(&a,b);      }
/*功能:把十六進(jìn)制數(shù)轉(zhuǎn)換為字符,如0xA8轉(zhuǎn)換為字母A和數(shù)字8*參數(shù):hex是待轉(zhuǎn)換的十六進(jìn)制數(shù);char1和char2是轉(zhuǎn)換后的字符的存儲指針*返回值:返回0表示轉(zhuǎn)換成功,返回-1表示參數(shù)錯誤或轉(zhuǎn)換失敗*/

參考答案:3

解析:

  • 行11執(zhí)行完

先將b的值賦值給a,然后b自加

  • 行3,調(diào)用move后

move函數(shù)的形參p指向全局變量a,指針變量p中的值是a的地址

全局變量b的值4賦值給形參val,變量val中的值是4

  • 行5執(zhí)行完

將val的地址賦值給指針變量p,p不再指向a,轉(zhuǎn)而指向了變量val

本題主要考察傳值傳址的區(qū)別,這是新手最不容易理解的一個知識點。

3. 在32位的單片機系統(tǒng)中,下面的結(jié)構(gòu)體長度是多少?

typedef struct{    short a;    char b;    char C;    int d;     }struct1;
typedef struct{    char a;    short b;    unsigned char c;    int d;}struct2;

參考答案:8/12

解析:

主要是字節(jié)對齊導(dǎo)致的問題,struct1,struct2各成員在內(nèi)存中分布如下:

實際項目開發(fā)中,為了保證結(jié)構(gòu)體字節(jié)對齊,往往使用以下宏來保證數(shù)據(jù)不存在歧義。

#pragma pack(1)typedef struct{    char a;    short b;    unsigned char c;    int d;}struct2;#pragma

4. 請使用typedef定義一個數(shù)據(jù)類型func_t為指向void型函數(shù)的函數(shù)指針,再使用此數(shù)據(jù)類型定義一個指向void型函數(shù)的函數(shù)指針,并通過此指針來調(diào)用函數(shù)test。

參考答案:

#include typedef void (*func_t)(int data) ;void testfunc(int data){ printf("yikou linux %d\n",data);}int main(int argc, char **argv){ func_t pfunc; pfunc = testfunc; pfunc(9);}

函數(shù)名也是個地址,我們可以讓函數(shù)指針指向一個函數(shù)。

linux內(nèi)核中大量使用函數(shù)指針,各種不同的外設(shè)向子系統(tǒng)注冊操作函數(shù)集,子系統(tǒng)通過這些操作函數(shù)集對外設(shè)做不同的操作。

比如下面是字符設(shè)備操作函數(shù)集,結(jié)構(gòu)體定義:

struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); ssize_t (*read_iter) (struct kiocb *, struct iov_iter *); ssize_t (*write_iter) (struct kiocb *, struct iov_iter *); int (*iterate) (struct file *, struct dir_context *); int (*iterate_shared) (struct file *, struct dir_context *); unsigned int (*poll) (struct file *, struct poll_table_struct *); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *, fl_owner_t id); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, loff_t, loff_t, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); int (*flock) (struct file *, int, struct file_lock *); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); int (*setlease)(struct file *, long, struct file_lock **, void **); long (*fallocate)(struct file *file, int mode, loff_t offset,     loff_t len); void (*show_fdinfo)(struct seq_file *m, struct file *f);#ifndef CONFIG_MMU unsigned (*mmap_capabilities)(struct file *);#endif ssize_t (*copy_file_range)(struct file *, loff_t, struct file *,   loff_t, size_t, unsigned int); int (*clone_file_range)(struct file *, loff_t, struct file *, loff_t,   u64); ssize_t (*dedupe_file_range)(struct file *, u64, u64, struct file *,   u64);} __randomize_layout;

5.請編寫宏定義實現(xiàn)以下功能:

  • 1)將無符號整數(shù)a的第1位置1,同時保證其它位的值不改變;
a |= 0x1<<1;

默認(rèn)位數(shù)從0開始計。

  • 2)將無符號整數(shù)b的第5位清0,同時保證其它位的值不改變;
b &=(~(0x1<<5));
  • 3)計算出任意結(jié)構(gòu)體類型的常數(shù)組(如struct tt tab[])的元素個數(shù)
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))main(){ printf("array num:%d\n",ARRAY_SIZE(tab));}

宏定義在內(nèi)核中也頻繁的使用,來看下等待隊列宏定義:

#define wait_event(wq_head, condition)      \do {          \ might_sleep();        \ if (condition)        \  break;        \ __wait_event(wq_head, condition);     \} while (0)
#define __wait_event(wq_head, condition)     \ (void)___wait_event(wq_head, condition, TASK_UNINTERRUPTIBLE, 0, 0, \       schedule())
#define ___wait_event(wq_head, condition, state, exclusive, ret, cmd)  \({          \ __label__ __out;       \ struct wait_queue_entry __wq_entry;     \ long __ret = ret; /* explicit shadow */    \          \ init_wait_entry(&__wq_entry, exclusive ? WQ_FLAG_EXCLUSIVE : 0); \ for (;;) {        \  long __int = prepare_to_wait_event(&wq_head, &__wq_entry, state);\          \  if (condition)       \   break;       \          \  if (___wait_is_interruptible(state) && __int) {   \   __ret = __int;      \   goto __out;      \  }        \          \  cmd;        \ }         \ finish_wait(&wq_head, &__wq_entry);     \__out: __ret;         \})

要完全看懂這段代碼,還是需要一定功底的,不光要看懂語法,還要了解內(nèi)核相關(guān)的其他子系統(tǒng)原理,1個月5個月1年2年????

6.請按照說明實現(xiàn)下面的函數(shù):

/*功能:把十六進(jìn)制數(shù)轉(zhuǎn)換為字符,如0xA8轉(zhuǎn)換為字母A和數(shù)字8*參數(shù):hex是待轉(zhuǎn)換的十六進(jìn)制數(shù);char1和char2是轉(zhuǎn)換后的字符的存儲指針*返回值:返回0表示轉(zhuǎn)換成功,返回-1表示參數(shù)錯誤或轉(zhuǎn)換失敗*/
}

本題主要考察數(shù)據(jù)在內(nèi)存的形式相關(guān)知識點,在實際應(yīng)用中可以說非常廣,很不錯的一道題目。

讀者可以嘗試下面一個問題

如何將16進(jìn)制的字符串,轉(zhuǎn)換成對應(yīng)的16進(jìn)制整數(shù)?

字符串?dāng)?shù)組char buf[]="a8";將字母a和8拼成0xa8,賦值給hexunsigned char hex;

7. i2c編程題

請根據(jù)PCAxxxxx這款芯片的數(shù)據(jù)手冊,編寫芯片的驅(qū)動代碼,要求涵蓋芯片90%以上的功能:可以忽略INT(中斷)引腳的功能:可以使用標(biāo)準(zhǔn)C語言或偽代碼進(jìn)行編寫;I2C總線驅(qū)動部分,可以只設(shè)計驅(qū)動接口,不進(jìn)行具體實現(xiàn)。

參考答案,下面是基于linux的i2c驅(qū)動架構(gòu):

#define YIKOU_MAJOR 500#define YIKOU_MINOR 0struct yikou_device { struct cdev cdev; struct i2c_client *client;};struct yikou_device *yikou; static int yikou_read_byte(struct i2c_client *client, unsigned char reg){ int ret; char txbuf[1] = { reg }; char rxbuf[1]; struct i2c_msg msg[2] = {  {client->addr, 0, 1, txbuf},  {client->addr, I2C_M_RD, 1, rxbuf} }; ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); if (ret < 0) {  printk("ret = %d\n", ret);  return ret; } return rxbuf[0];}static int yikou_write_byte(struct i2c_client *client, unsigned char reg, unsigned char val){ char txbuf[2] = {reg, val}; struct i2c_msg msg[2] = {  {client->addr, 0, 2, txbuf}, }; i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); return 0;}static long yikou_ioctl(struct file *file, unsigned int cmd, unsigned long arg){ union yikou_data data; struct i2c_client *client = yikou->client; switch(cmd) {        case CMD1:            data.data1 = mpu6050_read_byte(client, REG1);            break;        default:            printk("invalid argument\n");            return -EINVAL; } if (copy_to_user((void *)arg, &data, sizeof(data)))  return -EFAULT; return sizeof(data);}struct file_operations yikou_fops = { .unlocked_ioctl = yikou_ioctl,    ......};static int yikou_probe(struct i2c_client *client, const struct i2c_device_id *id){ int ret; dev_t devno = MKDEV(YIKOU_MAJOR, YIKOU_MINOR); printk("match OK!\n"); yikou = kzalloc(sizeof(*yikou), GFP_KERNEL); if (yikou == NULL) {  return -ENOMEM; } yikou->client = client; ret = register_chrdev_region(devno, 1, "yikou"); cdev_init(&yikou->cdev, &yikou_fops); ret = cdev_add(&yikou->cdev, devno, 1);  ...... return 0;}static int yikou_remove(struct i2c_client *client){ ...... return 0;}static struct of_device_id yikou_dt_match[] = { {.compatible = "invensense,yikou" }, ......};struct i2c_driver yikou_driver = { .driver = {  ......  .of_match_table = of_match_ptr(yikou_dt_match), }, .probe   = yikou_probe, ......};module_i2c_driver(yikou_driver);

其中struct i2c_msg的封裝需要參考datasheet讀寫數(shù)據(jù)時序

編寫i2c_msg信息原則如下:

  1. 有幾個S信號,msg數(shù)組就要有幾個元素;
  2. addr為從設(shè)備地址,通過i2c總線調(diào)用注冊的probe函數(shù)的參數(shù)i2c_client傳遞下來;
  3. len的長度不包括S、AD、ACK、P;
  4. buf為要發(fā)送或者要讀取的DATA的內(nèi)存地址。

比如下面是某芯片寫和讀的時序:

在這里插入圖片描述

  1. Single-Byte Write Sequence時序只需要1個i2c_msg,len值為2,buf內(nèi)容為是RA、DATA;
  2. Single-Byte Read Sequence時序需要2個i2c_msg,len值分別都為1,第1個msg的buf是RA,第2個msg的buf緩沖區(qū)用于存取從設(shè)備發(fā)送的DATA。

在這里插入圖片描述

點評:i2c是非常重要的一個知識點,基本上做嵌入式,或早或晚都會接觸他。

面試部分:

  • 1.面試官問對公司有什么了解嗎?
  • 2.自我介紹,講一下做的項目;
  • 3.攔截網(wǎng)站怎么實現(xiàn);
  • 4.wan/lan自適應(yīng)具體怎么實現(xiàn);
  • 5.路由器主要承擔(dān)一個什么樣的角色,傳輸數(shù)據(jù)的過程會用到哪些協(xié)議;
  • 6.手機連接路由器的lan口之后怎么獲取數(shù)據(jù)包;
  • 7.應(yīng)用和驅(qū)動哪個熟練;
  • 8.內(nèi)核里創(chuàng)建線程(pthread_create)后怎么結(jié)束?
聲明:本內(nèi)容為作者獨立觀點,不代表電子星球立場。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯的朋友,別忘了一鍵三連哦!
贊 0
收藏 1
關(guān)注 181
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧