当前位置:文档之家› Linux soc声卡构架分析

Linux soc声卡构架分析

Linux soc声卡构架分析
Linux soc声卡构架分析

Linux soc声卡构架分析(DMA)

以S3C2440为例进行分析,对应的文件linux-2.6.32.2/sound/soc/s3c24xx/s3c24xx_uda134x.c 其中module_init入口内容为:

357 static int __init s3c24xx_uda134x_init(void)

358 {

359 return platform_driver_register(&s3c24xx_uda134x_driver);

360 }

359行是一个平台驱动的注册函数,注册的驱动是s3c24xx_uda134x_driver。内容如下:348 static struct platform_driver s3c24xx_uda134x_driver = {

349 .probe = s3c24xx_uda134x_probe,

350 .remove = s3c24xx_uda134x_remove,

351 .driver = {

352 .name = "s3c24xx_uda134x",

353 .owner = THIS_MODULE,

354 },

355 };

由上面的name = "s3c24xx_uda134x"可知,这个驱动对应的平台设备早在系统启动时在dev_init中注册进来了,所以接下来的事情就是直接调用probe方法。

290 static int s3c24xx_uda134x_probe(struct platform_device *pdev)

291 {

292 int ret;

293

294 printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n");

295

296 s3c24xx_uda134x_l3_pins = pdev->dev.platform_data;

297 if (s3c24xx_uda134x_l3_pins == NULL) {

298 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "

299 "unable to find platform data\n");

300 return -ENODEV;

301 }

302 s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power;

303 s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model;

304

305 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data,

306 "data") < 0)

307 return -EBUSY;

308 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk,

309 "clk") < 0) {

310 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);

311 return -EBUSY;

312 }

313 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode,

314 "mode") < 0) {

315 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);

316 gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);

317 return -EBUSY;

318 }

319

320 s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1);

321 if (!s3c24xx_uda134x_snd_device) {

322 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "

323 "Unable to register\n");

324 return -ENOMEM;

325 }

326

327 platform_set_drvdata(s3c24xx_uda134x_snd_device,

328 &s3c24xx_uda134x_snd_devdata);

329 s3c24xx_uda134x_snd_devdata.dev = &s3c24xx_uda134x_snd_device->dev;

330 ret = platform_device_add(s3c24xx_uda134x_snd_device);

331 if (ret) {

332 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n");

333 platform_device_put(s3c24xx_uda134x_snd_device);

334 }

335

336 return ret;

337 }

305-318行就是设置udal34x要用的gpio引脚的功能。

320-334行是融入soc-core的关键,320行申请的platform_dev是soc-core的device结构。对应驱动的名称也应该是"soc-audio"。330行是问题的关键,s3c24xx_uda134x_snd_device 注册并与soc-core驱动进行匹配。相关的内容在linux/sound/soc/soc-core.c文件中。

Soc-core的入口是module_init(snd_soc_init)。

2546 static int __init snd_soc_init(void)

2547 {

2548 #ifdef CONFIG_DEBUG_FS

2549 debugfs_root = debugfs_create_dir("asoc", NULL);

2550 if (IS_ERR(debugfs_root) || !debugfs_root) {

2551 printk(KERN_W ARNING

2552 "ASoC: Failed to create debugfs directory\n");

2553 debugfs_root = NULL;

2554 }

2555 #endif

2556

2557 return platform_driver_register(&soc_driver);

2558 }

2557行是soc-core驱动注册的核心,soc_driver的内容如下:

1057 /* ASoC platform driver */

1058 static struct platform_driver soc_driver = {

1059 .driver = {

1060 .name = "soc-audio",

1061 .owner = THIS_MODULE,

1062 .pm = &soc_pm_ops,

1063 },

1064 .probe = soc_probe,

1065 .remove = soc_remove,

1066 };

Soc_driver和s3c24xx_uda134x_snd_device的名称匹配,满足mach的基本条件。后面会调用soc_driver的probe方法进行驱动的进一步枚举。

978 /* probes a new socdev */

979 static int soc_probe(struct platform_device *pdev)

980 {

981 int ret = 0;

982 struct snd_soc_device *socdev = platform_get_drvdata(pdev);

983 struct snd_soc_card *card = socdev->card;

984

985 /* Bodge while we push things out of socdev */

986 card->socdev = socdev;

987

988 /* Bodge while we unpick instantiation */

989 card->dev = &pdev->dev;

990 ret = snd_soc_register_card(card);

991 if (ret != 0) {

992 dev_err(&pdev->dev, "Failed to register card\n");

993 return ret;

994 }

995

996 return 0;

997 }

928行是获取平台驱动数据,这里就是前面设置的:

platform_set_drvdata(s3c24xx_uda134x_snd_device,&s3c24xx_uda134x_snd_devdata);

s3c24xx_uda134x_snd_devdata的数据类型为struct snd_soc_device

static struct snd_soc_device s3c24xx_uda134x_snd_devdata = {

.card = &snd_soc_s3c24xx_uda134x,

.codec_dev = &soc_codec_dev_uda134x,

.codec_data = &s3c24xx_uda134x,

};

Struct snd_soc_device描述了一个soc子系统中的soc设备其成员如下:

struct snd_soc_device {

struct device *dev;

struct snd_soc_card *card;

struct snd_soc_codec_device *codec_dev;

void *codec_data;

};

首先主要关注struct snd_soc_card *card;这个数据结构,后面的内容就是这张声卡实例化。475 struct snd_soc_card {

476 char *name;

477 struct device *dev;

478

479 struct list_head list;

480

481 int instantiated;

482

483 int (*probe)(struct platform_device *pdev);

484 int (*remove)(struct platform_device *pdev);

485

486 /* the pre and post PM functions are used to do any PM work before and

487 * after the codec and DAI's do any PM work. */

488 int (*suspend_pre)(struct platform_device *pdev, pm_message_t state);

489 int (*suspend_post)(struct platform_device *pdev, pm_message_t state);

490 int (*resume_pre)(struct platform_device *pdev);

491 int (*resume_post)(struct platform_device *pdev);

492

493 /* callbacks */

494 int (*set_bias_level)(struct snd_soc_card *,

495

496

497 /* CPU <--> Codec DAI links */

498 struct snd_soc_dai_link *dai_link;

499 int num_links;

500

501 struct snd_soc_device *socdev;

502

503 struct snd_soc_codec *codec;

504

505 struct snd_soc_platform *platform;

506 struct delayed_work delayed_work;

507 struct work_struct deferred_resume_work;

508 };

接下来进入到snd_soc_register_card(card);函数,这事soc_probe的核心。

2302 static int snd_soc_register_card(struct snd_soc_card *card)

2303 {

2304 if (!card->name || !card->dev)

2305 return -EINV AL;

2306

2307 INIT_LIST_HEAD(&card->list);

2308 card->instantiated = 0;

2309

2310 mutex_lock(&client_mutex);

2311 list_add(&card->list, &card_list);

2312 snd_soc_instantiate_cards();

2313 mutex_unlock(&client_mutex);

2314

2315 dev_dbg(card->dev, "Registered card '%s'\n", card->name);

2316

2317 return 0;

2318 }

函数首先初始化一个list头,并将当前card加入到card_list全局的一张soc声卡链表中。然后就调用snd_soc_instantiate_cards();来具体实例化一张声卡。

971 static void snd_soc_instantiate_cards(void)

972 {

973 struct snd_soc_card *card;

974 list_for_each_entry(card, &card_list, list)

975 snd_soc_instantiate_card(card);

976 }

974行遍历card_list然后调用snd_soc_instantiate_card实例化。

840 static void snd_soc_instantiate_card(struct snd_soc_card *card)

841 {

842 struct platform_device *pdev = container_of(card->dev,

843 struct platform_device,

844 dev);

845 struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev;

846 struct snd_soc_platform *platform;

847 struct snd_soc_dai *dai;

848 int i, found, ret, ac97;

849

850 if (card->instantiated)

851 return;

852

853 found = 0;

854 list_for_each_entry(platform, &platform_list, list)

855 if (card->platform == platform) {

856 found = 1;

857 break;

858 }

859 if (!found) {

860 dev_dbg(card->dev, "Platform %s not registered\n",

861 card->platform->name);

862 return;

863 }

865 ac97 = 0;

866 for (i = 0; i < card->num_links; i++) {

867 found = 0;

868 list_for_each_entry(dai, &dai_list, list)

869 if (card->dai_link[i].cpu_dai == dai) {

870 found = 1;

871 break;

872 }

873 if (!found) {

874 dev_dbg(card->dev, "DAI %s not registered\n",

875 card->dai_link[i].cpu_dai->name);

876 return;

877 }

878

879 if (card->dai_link[i].cpu_dai->ac97_control)

880 ac97 = 1;

881 }

882

883 for (i = 0; i < card->num_links; i++) {

884 if (!card->dai_link[i].codec_dai->ops)

885 card->dai_link[i].codec_dai->ops = &null_dai_ops;

886 }

887

888 /* If we have AC97 in the system then don't wait for the

889 * codec. This will need revisiting if we have to handle

890 * systems with mixed AC97 and non-AC97 parts. Only check for 891 * DAIs currently; we can't do this per link since some AC97

892 * codecs have non-AC97 DAIs.

893 */

894 if (!ac97)

895 for (i = 0; i < card->num_links; i++) {

896 found = 0;

897 list_for_each_entry(dai, &dai_list, list)

898 if (card->dai_link[i].codec_dai == dai) {

899 found = 1;

900 break;

901 }

902 if (!found) {

903 dev_dbg(card->dev, "DAI %s not registered\n",

904 card->dai_link[i].codec_dai->name);

905 return;

906 }

907 }

909 /* Note that we do not current check for codec components */

910

911 dev_dbg(card->dev, "All components present, instantiating\n");

912

913 /* Found everything, bring it up */

914 if (card->probe) {

915 ret = card->probe(pdev);

916 if (ret < 0)

917 return;

918 }

919

920 for (i = 0; i < card->num_links; i++) {

921 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;

922 if (cpu_dai->probe) {

923 ret = cpu_dai->probe(pdev, cpu_dai);

924 if (ret < 0)

925 goto cpu_dai_err;

926 }

927 }

928

929 if (codec_dev->probe) {

930 ret = codec_dev->probe(pdev);

931 if (ret < 0)

932 goto cpu_dai_err;

933 }

934

935 if (platform->probe) {

936 ret = platform->probe(pdev);

937 if (ret < 0)

938 goto platform_err;

939 }

940

941 /* DAPM stream work */

942 INIT_DELAYED_WORK(&card->delayed_work, close_delayed_work);

943 #ifdef CONFIG_PM

944 /* deferred resume work */

945 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); 946 #endif

947

948 card->instantiated = 1;

949

950 return;

952 platform_err:

953 if (codec_dev->remove)

954 codec_dev->remove(pdev);

955

956 cpu_dai_err:

957 for (i--; i >= 0; i--) {

958 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;

959 if (cpu_dai->remove)

960 cpu_dai->remove(pdev, cpu_dai);

961 }

962

963 if (card->remove)

964 card->remove(pdev);

965 }

850行如果声卡已经是实例化了的就直接返回。

854行遍历platform_list链表,这个platform_list是个全局变量初始化是通过linux/sound/soc/s3c24xx/s3c24xx-pcm.c中的初始化完成的,内容如下:

static int __init s3c24xx_soc_platform_init(void)

{

return snd_soc_register_platform(&s3c24xx_soc_platform);

}

module_init(s3c24xx_soc_platform_init);

snd_soc_register_platform目标是注册一个soc_platform结构到platform_list链表中供后文使用。这里对应得平台是s3c24xx_soc_platform,如下:

459 struct snd_soc_platform s3c24xx_soc_platform = {

460 .name = "s3c24xx-audio",

461 .pcm_ops = &s3c24xx_pcm_ops,

462 .pcm_new = s3c24xx_pcm_new,

463 .pcm_free = s3c24xx_pcm_free_dma_buffers,

464 };

snd_soc_register_platform完成的工作主要是将s3c24xx_soc_platform加入到platform_list,同时重新扫描card链,看是否有卡兼容当前soc_platform。具体代码如下:

2431 int snd_soc_register_platform(struct snd_soc_platform *platform)

2432 {

2433 if (!platform->name)

2434 return -EINV AL;

2435

2436 INIT_LIST_HEAD(&platform->list);

2437

2438 mutex_lock(&client_mutex);

2439 list_add(&platform->list, &platform_list);

2440 snd_soc_instantiate_cards();

2441 mutex_unlock(&client_mutex);

2442

2443 pr_debug("Registered platform '%s'\n", platform->name);

2444

2445 return 0;

2446 }

2440行重新回到了snd_soc_instantiate_cards()中,解释清楚platform_list以后继续会爱到snd_soc_instantiate_cards函数。

855行匹配两个平台是否一致。一路走来

card->platform实际上就是s3c24xx_uda134x_snd_devdata中的snd_soc_s3c24xx_uda134x指向的platform。

static struct snd_soc_device s3c24xx_uda134x_snd_devdata = {

.card = &snd_soc_s3c24xx_uda134x,

.codec_dev = &soc_codec_dev_uda134x,

.codec_data = &s3c24xx_uda134x,

};

static struct snd_soc_card snd_soc_s3c24xx_uda134x = {

.name = "S3C24XX_UDA134X",

.platform = &s3c24xx_soc_platform,

.dai_link = &s3c24xx_uda134x_dai_link,

.num_links = 1,

};

从上面的结构不难看出card->platform=&s3c24xx_soc_platform,与之前注册的一至,found=1,跳出搜索,反之如果没有找到匹配的目标,表示platform还尚未注册进来,一直等到platform 注册再次调用instantial_card来实现平台的匹配。

找完platform,接下来进入数字音频接口的匹配也就是dai(digital audio interface),整个dai 匹配的过程与platform的匹配过程相似的,dai_list注册的内容如下:

/linux/sound/soc/s3c24xx/s3c24xx-i2s.c

static int __init s3c24xx_i2s_init(void)

{

return snd_soc_register_dai(&s3c24xx_i2s_dai);

}

module_init(s3c24xx_i2s_init);

snd_soc_register_dai注册数字接口的内容如下:

2345 int snd_soc_register_dai(struct snd_soc_dai *dai)

2346 {

2347 if (!dai->name)

2348 return -EINV AL;

2349

2350 /* The device should become mandatory over time */

2351 if (!dai->dev)

2352 printk(KERN_W ARNING "No device for DAI %s\n", dai->name);

2353

2354 if (!dai->ops)

2355 dai->ops = &null_dai_ops;

2356

2357 INIT_LIST_HEAD(&dai->list);

2358

2359 mutex_lock(&client_mutex);

2360 list_add(&dai->list, &dai_list);

2361 snd_soc_instantiate_cards();

2362 mutex_unlock(&client_mutex);

2363

2364 pr_debug("Registered DAI '%s'\n", dai->name);

2365

2366 return 0;

2367 }

2354-2355行是如果dai没有注册操作方法,那么就使用默认的dai设置方法。这里注册的dai接口内容如下:

struct snd_soc_dai s3c24xx_i2s_dai = {

.name = "s3c24xx-i2s",

.id = 0,

.probe = s3c24xx_i2s_probe,

.suspend = s3c24xx_i2s_suspend,

.resume = s3c24xx_i2s_resume,

.playback = {

.channels_min = 2,

.channels_max = 2,

.rates = S3C24XX_I2S_RA TES,

.formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, .capture = {

.channels_min = 2,

.channels_max = 2,

.rates = S3C24XX_I2S_RA TES,

.formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, .ops = &s3c24xx_i2s_dai_ops,

};

和snd_soc_register_platform一样,snd_soc_register_dai同样调用了snd_soc_instantiate_cards()来重新实例化card。

另外需要注意的是struct snd_soc_card结构中的struct snd_soc_dai_link实际上关联链接的是cpu音频接口与codec编解码接口。内容如下:

struct snd_soc_dai_link {

char *name; /* Codec name */

char *stream_name; /* Stream name */

/* DAI */

struct snd_soc_dai *codec_dai;

struct snd_soc_dai *cpu_dai;

/* machine stream operations */

struct snd_soc_ops *ops;

/* codec/machine specific init - e.g. add machine controls */

int (*init)(struct snd_soc_codec *codec);

/* Symmetry requirements */

unsigned int symmetric_rates:1;

/* Symmetry data - only valid if symmetry is being enforced */

unsigned int rate;

/* DAI pcm */

struct snd_pcm *pcm;

};

很明显struct snd_soc_dai *codec_dai;和struct snd_soc_dai *cpu_dai;分别指向了不同的音频接口,这里card->dai_link[i].cpu_dai= &s3c24xx_i2s_dai指的是cpu的i2s接口,与刚注册的相同。所以接口匹配,注意snd_soc_instantiate_card中879行是关于AC97声卡的配置,这里略过。

883-886行是关于数字编解码接口的相关信息,card->dai_link[i].codec_dai->ops内容如下:static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {

.name = "UDA134X",

.stream_name = "UDA134X",

.codec_dai = &uda134x_dai,

.cpu_dai = &s3c24xx_i2s_dai,

.ops = &s3c24xx_uda134x_ops,

};

struct snd_soc_dai uda134x_dai = {

.name = "UDA134X",

/* playback capabilities */

.playback = {

.stream_name = "Playback",

.channels_min = 1,

.channels_max = 2,

.rates = UDA134X_RATES,

.formats = UDA134X_FORMATS,

},

/* capture capabilities */

.capture = {

.stream_name = "Capture",

.channels_min = 1,

.channels_max = 2,

.rates = UDA134X_RATES,

.formats = UDA134X_FORMATS,

},

/* pcm operations */

.ops = &uda134x_dai_ops,

};

894-907行是不支持AC97标准的的codec相关的处理,这里还是使用了dai_list链表。Codec 的注册在/sound/soc/codecs/uda134x.c中的module_init(uda134x_init);

static int __init uda134x_init(void)

{

return snd_soc_register_dai(&uda134x_dai);

}

codec_dai的内容如下:

struct snd_soc_dai uda134x_dai = {

.name = "UDA134X",

/* playback capabilities */

.playback = {

.stream_name = "Playback",

.channels_min = 1,

.channels_max = 2,

.rates = UDA134X_RATES,

.formats = UDA134X_FORMATS,

},

/* capture capabilities */

.capture = {

.stream_name = "Capture",

.channels_min = 1,

.channels_max = 2,

.rates = UDA134X_RATES,

.formats = UDA134X_FORMATS,

},

/* pcm operations */

.ops = &uda134x_dai_ops,

};

911行开始,是真正instantiating的过程,下面一一分析:

914行如果card有probe方法,则直接调用。这里没有提供也就跳过了。

920-927行是cpu_dai接口的枚举过程,对应的函数在linux/sound/soc/s3c24xx/s3c24xx-i2s.c 中的s2c24xx_i2s_probe,内容如下:

389 static int s3c24xx_i2s_probe(struct platform_device *pdev,

390 struct snd_soc_dai *dai)

391 {

392 pr_debug("Entered %s\n", __func__);

393

394 s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100);

395 if (s3c24xx_i2s.regs == NULL)

396 return -ENXIO;

397

398 s3c24xx_i2s.iis_clk = clk_get(&pdev->dev, "iis");

399 if (s3c24xx_i2s.iis_clk == NULL) {

400 pr_err("failed to get iis_clock\n");

401 iounmap(s3c24xx_i2s.regs);

402 return -ENODEV;

403 }

404 clk_enable(s3c24xx_i2s.iis_clk);

405

406 /* Configure the I2S pins in correct mode */

407 s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK);

408 s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK);

409 s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK);

410 s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI);

411 s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO);

412

413 writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON);

414

415 s3c24xx_snd_txctrl(0);

416 s3c24xx_snd_rxctrl(0);

417

418 return 0;

419 }

这个函数主要是针对s3c2440 I2S内部寄存器的配置。

394行重映射内部寄存器,

398-404行是设置系统时钟。

407-412行是设置I2S的GPIO功能,使之支持I2S

413行使能I2S功能

415行函数实现如下:

76 static void s3c24xx_snd_txctrl(int on)

77 {

78 u32 iisfcon;

79 u32 iiscon;

80 u32 iismod;

81

82 pr_debug("Entered %s\n", __func__);

83

84 iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON);

85 iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);

86 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);

87

88 pr_debug("r: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon);

89

90 if (on) {

91 iisfcon |= S3C2410_IISFCON_TXDMA | S3C2410_IISFCON_TXENABLE;

92 iiscon |= S3C2410_IISCON_TXDMAEN | S3C2410_IISCON_IISEN;

93 iiscon &= ~S3C2410_IISCON_TXIDLE;

94 iismod |= S3C2410_IISMOD_TXMODE;

95

96 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);

97 writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);

98 writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);

99 } else {

100 /* note, we have to disable the FIFOs otherwise bad things

101 * seem to happen when the DMA stops. According to the

102 * Samsung supplied kernel, this should allow the DMA

103 * engine and FIFOs to reset. If this isn't allowed, the

104 * DMA engine will simply freeze randomly.

105 */

106

107 iisfcon &= ~S3C2410_IISFCON_TXENABLE;

108 iisfcon &= ~S3C2410_IISFCON_TXDMA;

109 iiscon |= S3C2410_IISCON_TXIDLE;

110 iiscon &= ~S3C2410_IISCON_TXDMAEN;

111 iismod &= ~S3C2410_IISMOD_TXMODE;

112

113 writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);

114 writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);

115 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);

116 }

117

118 pr_debug("w: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); 119 }

函数是对I2S内部的控制寄存器的设置。

回到snd_soc_instantiate_card函数,接下来是codec_dev的probe方法的调用,codec_dev是相对cpu_dev的软解码设备,这个probe方法后面分析,接下来把snd_soc_instantiate_card 分析完。函数的最后就是platform中probe方法的调用,最后是初始化一个延时等待队列。一切工作完成以后card->instantiated = 1;完成卡的instantial工作。

目光转向codec_dev的probe方法

struct snd_soc_codec_device soc_codec_dev_uda134x = {

.probe = uda134x_soc_probe,

.remove = uda134x_soc_remove,

.suspend = uda134x_soc_suspend,

.resume = uda134x_soc_resume,

};

代码位于linux/sound/soc/codecs/uda134x.c中

469 static int uda134x_soc_probe(struct platform_device *pdev)

470 {

471 struct snd_soc_device *socdev = platform_get_drvdata(pdev);

472 struct snd_soc_codec *codec;

473 struct uda134x_priv *uda134x;

474 void *codec_setup_data = socdev->codec_data;

475 int ret = -ENOMEM;

476 struct uda134x_platform_data *pd;

477

478 printk(KERN_INFO "UDA134X SoC Audio Codec\n");

479

480 if (!codec_setup_data) {

481 printk(KERN_ERR "UDA134X SoC codec: "

482 "missing L3 bitbang function\n");

483 return -ENODEV;

484 }

485

486 pd = codec_setup_data;

487 switch (pd->model) {

488 case UDA134X_UDA1340:

489 case UDA134X_UDA1341:

490 case UDA134X_UDA1344:

491 break;

492 default:

493 printk(KERN_ERR "UDA134X SoC codec: "

494 "unsupported model %d\n",

495 pd->model);

496 return -EINV AL;

497 }

498

499 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);

500 if (socdev->card->codec == NULL)

501 return ret;

502

503 codec = socdev->card->codec;

504

505 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);

506 if (uda134x == NULL)

507 goto priv_err;

508 codec->private_data = uda134x;

509

510 codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg),

511 GFP_KERNEL);

512 if (codec->reg_cache == NULL)

513 goto reg_err;

514

515 mutex_init(&codec->mutex);

516

517 codec->reg_cache_size = sizeof(uda134x_reg);

518 codec->reg_cache_step = 1;

519

520 codec->name = "UDA134X";

521 codec->owner = THIS_MODULE;

522 codec->dai = &uda134x_dai;

523 codec->num_dai = 1;

524 codec->read = uda134x_read_reg_cache;

525 codec->write = uda134x_write;

526 #ifdef POWER_OFF_ON_STANDBY

527 codec->set_bias_level = uda134x_set_bias_level;

528 #endif

529 INIT_LIST_HEAD(&codec->dapm_widgets);

530 INIT_LIST_HEAD(&codec->dapm_paths);

531

532 codec->control_data = codec_setup_data;

533

534 if (pd->power)

535 pd->power(1);

536

537 uda134x_reset(codec);

538

539 /* register pcms */

540 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);

541 if (ret < 0) {

542 printk(KERN_ERR "UDA134X: failed to register pcms\n");

543 goto pcm_err;

544 }

545

546 switch (pd->model) {

547 case UDA134X_UDA1340:

548 case UDA134X_UDA1344:

549 ret = snd_soc_add_controls(codec, uda1340_snd_controls,

550 ARRAY_SIZE(uda1340_snd_controls));

551 break;

552 case UDA134X_UDA1341:

553 ret = snd_soc_add_controls(codec, uda1341_snd_controls,

554 ARRAY_SIZE(uda1341_snd_controls));

555 break;

556 default:

557 printk(KERN_ERR "%s unkown codec type: %d",

558 __func__, pd->model);

559 return -EINV AL;

560 }

561

562 if (ret < 0) {

563 printk(KERN_ERR "UDA134X: failed to register controls\n");

564 goto pcm_err;

565 }

566

567 ret = snd_soc_init_card(socdev);

568 if (ret < 0) {

569 printk(KERN_ERR "UDA134X: failed to register card\n");

570 goto card_err;

571 }

572

573 return 0;

574

575 card_err:

576 snd_soc_free_pcms(socdev);

577 snd_soc_dapm_free(socdev);

578 pcm_err:

579 kfree(codec->reg_cache);

580 reg_err:

581 kfree(codec->private_data);

582 priv_err:

583 kfree(codec);

584 return ret;

585 }

在进入代码分析之前,首先关注一下函数的参数,这里的pdev实际上就是指向S3C24xx-uda134x.c中的&s3c24xx_uda134x_snd_device。当然471行socdev也就是指向static struct snd_soc_device s3c24xx_uda134x_snd_devdata = {

.card = &snd_soc_s3c24xx_uda134x,

.codec_dev = &soc_codec_dev_uda134x,

.codec_data = &s3c24xx_uda134x,

};

这里474行codec_setup_data也就是指向s3c24xx_uda134x,其实质是

static struct uda134x_platform_data s3c24xx_uda134x = {

.l3 = {

.setdat = setdat,

.setclk = setclk,

.setmode = setmode,

.data_hold = 1,

.data_setup = 1,

.clock_high = 1,

.mode_hold = 1,

.mode = 1,

.mode_setup = 1,

},

};

L3pin是uda134x控制数据接口,后面用到了再详细分析。

499-503行是为soc_codec分配空间。

510行kmemdup是kmalloc的一个变种,他不仅实现内存的分配,同时能为其赋值,这里uda134x_reg是内部寄存器缓存的情况,最终复制到reg_codec中。

524和525行是读写uda134x寄存器的方法,但是read只是对寄存器缓存变量的读取,具体的函数实现后面谈到的时候在详细分析。

537行uda134x_reset的过程如下:

146 static inline void uda134x_reset(struct snd_soc_codec *codec)

147 {

148 u8 reset_reg = uda134x_read_reg_cache(codec, UDA134X_STA TUS0);

149 uda134x_write(codec, UDA134X_STA TUS0, reset_reg | (1<<6));

150 msleep(1);

151 uda134x_write(codec, UDA134X_STA TUS0, reset_reg & ~(1<<6));

152 }

148行正是前面所说的codec->read。内容如下:

63 /*

64 * The codec has no support for reading its registers except for peak level...

65 */

66 static inline unsigned int uda134x_read_reg_cache(struct snd_soc_codec *codec,

67 unsigned int reg)

68 {

69 u8 *cache = codec->reg_cache;

70

71 if (reg >= UDA134X_REGS_NUM)

72 return -1;

73 return cache[reg];

74 }

从代码中我们可以看到,读数据的过程实际上就是从之前uda134x_reg变量中读取的数据,从注释上也不难看出,codec不支持内部寄存器数据的读取。

回到uda134x_reset中uda134x_write也正是前面codec->write提供的方法。在分析具体内容之前不妨从整体上观察一下函数所做的操作,reset首先置位状态寄存器0的第六位,然后延时一段时间后清零该位,完成复位过程。uda134x_write写硬件的过程如下:

93 static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,

94 unsigned int value)

95 {

96 int ret;

97 u8 addr;

98 u8 data = value;

99 struct uda134x_platform_data *pd = codec->control_data;

100

101 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);

102

103 if (reg >= UDA134X_REGS_NUM) {

104 printk(KERN_ERR "%s unkown register: reg: %u", 105 __func__, reg);

106 return -EINV AL;

107 }

108

109 uda134x_write_reg_cache(codec, reg, value);

110

111 switch (reg) {

112 case UDA134X_STA TUS0:

113 case UDA134X_STA TUS1:

114 addr = UDA134X_STA TUS_ADDR;

115 break;

116 case UDA134X_DA TA000:

117 case UDA134X_DA TA001:

118 case UDA134X_DA TA010:

119 addr = UDA134X_DATA0_ADDR;

120 break;

121 case UDA134X_DA TA1:

122 addr = UDA134X_DATA1_ADDR;

123 break;

124 default:

125 /* It's an extended address register */

126 addr = (reg | UDA134X_EXTADDR_PREFIX); 127

128 ret = l3_write(&pd->l3,

129 UDA134X_DATA0_ADDR, &addr, 1); 130 if (ret != 1)

131 return -EIO;

132

133 addr = UDA134X_DATA0_ADDR;

134 data = (value | UDA134X_EXTDATA_PREFIX);

135 break;

136 }

137

138 ret = l3_write(&pd->l3,

139 addr, &data, 1);

140 if (ret != 1)

141 return -EIO;

142

143 return 0;

144 }

109行是将改变值写入reg_cache也就是前面读函数缓存的变量。138行是L3引脚想uda134x写入数据的过程,内容如下:

67 int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len)

68 {

69 adap->setclk(1);

70 adap->setdat(1);

71 adap->setmode(1);

72 udelay(adap->mode);

73

74 adap->setmode(0);

75 udelay(adap->mode_setup);

76 sendbyte(adap, addr);

77 udelay(adap->mode_hold);

78

79 sendbytes(adap, data, len);

80

81 adap->setclk(1);

82 adap->setdat(1);

83 adap->setmode(0);

84

85 return len;

86 }

很明显这里是对GPIO口按位操作的过程,实际在硬件连接的过程中L3引脚包含clk、data 和mode引脚。struct l3_pins *adap的内容前面已经贴出来过,这里以setclk为例看看是如何接口的,实际就是对GPIO的操作。

static void setclk(int v)

{

gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0);

}

最终s3c24xx_uda134x_l3_pins关联到了

static struct s3c24xx_uda134x_platform_data s3c24xx_uda134x_data = {

.l3_clk = S3C2410_GPB(4),

.l3_data = S3C2410_GPB(3),

.l3_mode = S3C2410_GPB(2),

.model = UDA134X_UDA1341,

};

回到uda134x_probe函数中….

540行snd_soc_new_pcms是重头戏,注册了一个新的基于pcm的声卡。重新回到了soc_core.c 文件。

1422 int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)

1423 {

1424 struct snd_soc_card *card = socdev->card;

1425 struct snd_soc_codec *codec = card->codec;

1426 int ret, i;

1427

1428 mutex_lock(&codec->mutex);

Android源代码结构分析

目录 一、源代码结构 (2) 第一层次目录 (2) bionic目录 (3) bootloader目录 (5) build目录 (7) dalvik目录 (9) development目录 (9) external目录 (13) frameworks目录 (19) Hardware (20) Out (22) Kernel (22) packages目录 (22) prebuilt目录 (27) SDK (28) system目录 (28) Vendor (32)

一、源代码结构 第一层次目录 Google提供的Android包含了原始Android的目标机代码,主机编译工具、仿真环境,代码包经过解压缩后,第一级别的目录和文件如下所示: . |-- Makefile (全局的Makefile) |-- bionic (Bionic含义为仿生,这里面是一些基础的库的源代码) |-- bootloader (引导加载器),我们的是bootable, |-- build (build目录中的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具) |-- dalvik (JAVA虚拟机) |-- development (程序开发所需要的模板和工具) |-- external (目标机器使用的一些库) |-- frameworks (应用程序的框架层) |-- hardware (与硬件相关的库) |-- kernel (Linux2.6的源代码) |-- packages (Android的各种应用程序) |-- prebuilt (Android在各种平台下编译的预置脚本) |-- recovery (与目标的恢复功能相关) `-- system (Android的底层的一些库)

大连理工大学结构优化复习总结

结构优化设计-基于结构分析技术,在给定的设计空间实现满足使用要求且具有最佳性能或最低成本的工程结构设计的技术 优化设计的三要素:设计变量;约束条件;目标函数 凸域:基于n维空间的区域s里,如果取任意两点x1和x2,连接这两点的线段也属于s,该区域称凸域(=αx1+(1-α)x2 ) 凸函数:如果函数f(x)定义在n维空间的凸域s上,而且对s中的任意两点x1和x2和任意常数α,0.0<=α<=1.0,有f[αx1+(1- α)x2]<=αf(x1)+(1- α)f(x2),则f(x)称为s上的凸函数 严格凸函数:上式小于严格成立 凸规划:如果可行域是凸域,目标函数是凸函数,这样构成的数学规划问题为凸规划问题。 准则设计法:依靠工程经验;效率高;缺乏严格数学基础 最优准则法基于库塔克(K-T)条件:需构造迭代求解算法;通用性不强 数学规划方法:有严格的数学基础,有较好的通用性,计算效率要考虑。 结构优化问题的求解布骤 I. 建立优化模型。给定初始设计方案。 II. 结构分析(有限元) III.优化(收敛性)检验。满足则结束程序,否则继续IV IV. 灵敏度分析 V. 求解优化问题,修改结构模型,返回II。 优化求解的两大类方法:准则法;数学规划法 准则设计方法:用优化准则代替原来的优化问题 同步失效准则设计的评价: {优点:简单、方便,特别是独立约束个数n=m时;工程实用;适合于构件设计。 缺点:只能处理简单构件设计;缩小了设计空间,不能保证最优解;若n < m ,可能无解; 当n > m时,确定哪些破坏模式应同时发生比较困难。 改进:为了弥补等式约束代替不等式约束的缺陷,引入松弛因子ψi σi (X ) =ψiσip , 0 ≤ψi ≤1, i =1,2,......n 启发:用准则代替原来的优化问题,准则法的基本思想;如果将桁架的每根杆看作一种可能的破坏模式,桁架看作一个元件。可以得到满应力准则 满应力方法的缺点:完全无视重量会漏掉最轻设计;中间点一般是不可行设计,对工程实际不利。希望得到可行的中间设计点。 齿形法:采用射线步进行可行性调整,适用于桁架一类刚度与设计变量成正比的结构。 将所有设计变量同时乘以一个常数ξ:A n i=ξA i o} 线性函数都是凸函数,线性规划是凸规划。

党员队伍思想状况定期分析报告制度(参考)

党员队伍思想状况定期分析制度 为了解和掌握党员队伍思想状况,提高思想政治工作的针对性、实效性和主动性,进一步加强党员队伍思想政治建设,提高党员队伍素质,增强党支部凝聚力,为完成本部门中心工作和生产经营任务提供强有力的思想保证,制订本制度。 (一)工作内容。及时了解和掌握党员以下情况: 1.党员组织纪律观念和精神状态、理想信念和宗旨意识,世界观、人生观和价值观,以及社会公德、职业道德、家庭美德、个人品德建设等方面的情况。 2.党员学习贯彻党的理论和路线、方针、政策,以及中央、省委、国资委党委重要会议精神和公司党委重大决策的情况。 3.党员对热点、难点问题特别是重大社会性事件及其他重要情况的反映。 4.党员对贯彻落实中央、省委和国资委党委重大决策部署以及公司党委工作部署,推进各项重点工作的意见和建议。 5.党员在意识形态领域、维护社会稳定等方面的思想状态、

行动表现以及意见建议。 6.党员在思想、工作、学习、生活以及个人成长发展等方面存在的突出问题和合理诉求。 (二)工作步骤。 1.信息收集。坚持“真实、准确、可靠”的原则,利用QQ、微信等信息手段做好日常收集,采取召开座谈调研、开展谈心谈话、发放调查问卷等形式定期收集。信息收集过程中发现的重大问题要及时向党组织报告。 2.信息分析。定期分析(每季一次)党员思想状况,甄别、筛选收集、汇总信息,全面分析党员思想状况,针对存在问题,研究工作措施,制定改进方案。对热点、重点问题和集团公司党委布置的专项工作,应随时专题分析研究。 3.报告反馈。党员思想动态分析报告及时报送集团公司党委,重要情况随时报告。对带有倾向性、苗头性的问题和突发事件,按照有关要求报告并及时处理;对党员普遍关注的热点问题,以适当方式予以反馈。对个别党员的思想问题,及时做好教育引导工作,防止引发其他问题。

数据结构实验报告

数据结构实验报告 一.题目要求 1)编程实现二叉排序树,包括生成、插入,删除; 2)对二叉排序树进行先根、中根、和后根非递归遍历; 3)每次对树的修改操作和遍历操作的显示结果都需要在屏幕上用树的形状表示出来。 4)分别用二叉排序树和数组去存储一个班(50人以上)的成员信息(至少包括学号、姓名、成绩3项),对比查找效率,并说明在什么情况下二叉排序树效率高,为什么? 二.解决方案 对于前三个题目要求,我们用一个程序实现代码如下 #include #include #include #include "Stack.h"//栈的头文件,没有用上 typedefintElemType; //数据类型 typedefint Status; //返回值类型 //定义二叉树结构 typedefstructBiTNode{ ElemType data; //数据域 structBiTNode *lChild, *rChild;//左右子树域 }BiTNode, *BiTree; intInsertBST(BiTree&T,int key){//插入二叉树函数 if(T==NULL) { T = (BiTree)malloc(sizeof(BiTNode)); T->data=key; T->lChild=T->rChild=NULL; return 1; } else if(keydata){ InsertBST(T->lChild,key); } else if(key>T->data){ InsertBST(T->rChild,key); } else return 0; } BiTreeCreateBST(int a[],int n){//创建二叉树函数 BiTreebst=NULL; inti=0; while(i

西安交大结构优化设计实验报告

结构优化设计实验报告 1.实验背景 结构优化能在保证安全使用的前提下保证工程结构减重,提高工程的经济效益,这也是课程练习的有效补充。 2.实验课题 问题1:考察最速下降法、拟牛顿法(DFP,BFGS)、单纯形法的性能,使用matlab中的fminunc 和fminsearch 函数。 ●目标函数1: 目标函数,多元二次函数 其中,,,, 初值 ●目标函数2 1.3 结果分析:从上述结果可以看出牛顿法具有较好的稳定性,最速下降法和单纯形法在求解超越函数时稳定性不佳,最速下降法迭代次数最少,单纯形法

迭代次数最多。 问题2:使用matlab中的linprog和quadprog函数验证作业的正确性。 用单纯形法求解线性规划问题的最优解 ●目标函数1 6 , 运行结果: 单纯形法的解析解 用两相法求解线性规划问题的最优解 ●目标函数2 , 运行结果: 单纯形法的解析解 求解二次规划问题的最优解 ●目标函数2 , , 运行结果:

问题3:用Matlab命令函数fmincon求解非线性约束规划问题 ●目标函数1 运行结果: 迭代次数:8 ●目标函数2 运行结果: 迭代次数:16 问题4:用Matlab命令函数fmincon求解人字形钢管架优化问题。已知:2F = 600kN,2B = 6 m,T=5 mm,钢管材料E = 210 GPa,密度=, 许用应力[ ]=160MPa,根据工艺要求2m ≤ h≤6m ,20mm ≤ D≤300mm 。求h , D 使总重量W为最小。

求 目标函数1 运行结果:

迭代次数:8 问题5:修改满应力程序opt4_1.m 和齿形法程序opt4_2.m ,自行设计一个超静定桁架结构,并对其进行优化。要求: (1)设计变量数目不小于2; (2)给出应力的解析表达式; (3)建立以重量最小为目标函数、应力为约束的优化模型。 分别用满应立法和齿轮法求解图2超静定结构,已知材料完全相同, , , 2000,1500==σσ , 满应力法和齿轮法运行结果:

党员队伍状况分析报告

醴泉街道党员队伍状况 分析报告 在前期摸底排查和整顿软弱涣散基层党组织工作的基础上,我街道对所管理党员的基本信息进一步进行认真核实,经与本人档案、户籍等有关资料进行比对、印证后,对全街道党员队伍有了一个大致的情况分析,现将调研掌握的党员队伍情况汇报如下:一、基层党组织党员情况基本情况 我街道共有党组织234个,包括党委11个、党总支10个、党支部213个。街道现有党员5073名,其中正式党员5001名,预备党员72名。2012年发展党员62名,2013年发展党员33名,2014年发展党员39名。共有党员5073名,其中农村生产一线党员 2126名,外出务工(个体)540名,企业党员1737 名,机关教育部门党员468 名,离退休人员党员202名。其中女党员1005人;研究生学历党员有20名,男性9名,女性11名;本专科学历党员1028名,男性党员700名,女性党员328名;中专及以下学历有4024名,男性3358名,女性666名。;流动党员42人,年老体弱不能参加正常组织活动党员116人,无法查找73人。二、党员队伍中存在的主要问题及原因分析 从调查摸底的情况来看,我街道在党组织自身建设和党员队伍建设上还存在一些问题,主要表现在: 1、农村部分党组织和党员的创造力、凝聚力和战斗力不强。一是党支部经费严重不足,党组织活动开展少,从而削弱了基层党组织的创造力、凝聚力和战斗力,党员的模范带头作用发挥不够的问题也比较突出。二是党员年龄老化,联系群众作用得不到很好地体现。三是能力偏弱,无力起带头作用。四是少部分党员党性观念淡漠,思想退化。

2、党员流动性大,对他们实行有效的教育管理难。流动党员是新形势下党员队伍中出现的一个特殊群体,对其的教育管理是新时期党建工作面临的一个新问题,集中表现为党组织教育管理上的“五难”和流动党员自身面临的“五个矛盾”。“五难”是:去向难掌握、管理难落实、教育难适应、活动难开展、设臵难健全。“五个矛盾”是:找组织与找工作的矛盾、党员找组织与组织找党员的矛盾、党员的权利与义务的矛盾、管理与服务的矛盾、先进性与新环境的矛盾。究其原因:一是由于流动性大,不好管;二是认识不清,不想管;三是模式老化,不会管;四是流动党员思想复杂,不服管。 3、企业党支部开展工作和企业党员的管理存在难度。有的党员生活困难,疲于应付生活的压力,参加组织生活的热情不高;有的党员因工作性质的原因,经常外出,行踪不定;非公有制经济组织中有一部分党员不愿意暴露党员身份,这些都给党员的管理增加了难度。 三、针对存在的主要问题提出相应对策 1、大力加强农村基层组织建设。一个地方的农村基层党组织战斗力强不强,工作搞得好与差,关键在班子,尤其是一把手。因此,农村基层组织建设要始终把选好配强支部一班人,特别是选好党支部书记放在首位。坚持“三向培养”,要坚持素质标准,真正选“能人”来当家,选“强者”来执政,特别要从种养大户、复退军人、未就业的大中专毕业生、个体私营业主里的优秀分子中选拔能人进村级班子;要形成制度化的教育培训机制,不断提高村干部的思想政治素质、科技文化素质和驾驭农村工作、解决农村各种矛盾的能力,使村干部在思想、作风、能力上适应农村新形势、新任务的要求,不断提高党组织的影响力,增强党组织的凝聚力。积极探索推行针对性强、特色鲜明、能有效增强基层组织战斗堡垒作用和党员先锋模范作用的活动载体,不断赋于农

如何安装电脑声卡驱动

如何安装电脑声卡驱动 随着操作系统安装包的不断增多,例如vista,安装包已经达到了几G,系统附带的驱动包也变的更加全面。有时候,系统安装好后,很多硬件不用安装驱动就可以正常使用了。但是并不是所有的硬件都能免安装驱动,比如有时候安装完系统后,声卡没有被成功驱动,播放器放不出声音,下面笔者就来介绍下如何安装声卡。 右键点击―我的电脑‖----―属性‖---―硬件‖----―设备管理器‖,展开―声音、视频和游戏控制器‖,看前面有没有黄色的―?‖,有,说明缺声卡驱动,没有,说明该声卡驱动不能正常使用,右击声卡,选―卸载‖将其删除,重新安装驱动。如果有声卡驱动盘,那就很简单了。将声卡的驱动光盘放入光驱,右击―声音、视频和游戏控制器‖下的?号选项,选―更新驱动程序‖,打开―硬件更新向导‖,选―是,仅这一次‖---―下一步‖---―自动安装软件‖--―下一步‖,系统即自动搜索并安装光盘中的声卡驱动程序,如果该光盘没有适合你用的声卡驱动,再换一张试试,直到完成。( 三联教程) 倘若没有声卡驱动盘,可以从网上下载相应的驱动程序。要下载相应的驱动程序,少不了要先确定声卡的型号。不知道声卡型号,看展开的―声音、视频和游戏控制器‖下的那一串字符和数字就是你的声卡型号,也可―开始‖—―运行‖—输入dxdiag, 打开―DirectX诊断工具‖—声音,从打开的界面中找。另外,如果不能查到,一般情况下,这招都不行的;可以用号称世界上最好的硬件检测工具EVEREST中文版。 下载声卡驱动的网站不少,你也可以在综合大型网站主页,把你的声卡型号输入到―搜索‖文本框中,按―搜索‖按钮,从打开的界面中,选你要下载驱动的网站。下载驱动软件要注意:一是品牌型号要对,二是在什么系统上便用,三是要看该驱动软件公布的时间,最新的未必适合使用,可多下载几个,挑着使。 下载的驱动软件一般有自动安装功能,打开后,点击即自动安装。不能自动安装的,解压后备用,要记下该软件在磁盘中的具体路径,如E:…………。右击―我的电脑‖----―属性‖---―硬件‖----―设备管理器‖,打开―声音、视频和游戏控制器‖,右击―声音、视频和游戏控制器‖ 下的?号声卡选项,选―更新驱动程序‖,打开―硬件更新向导‖,去掉―搜索可移动媒体‖前的勾,勾选―从列表或指定位置安装‖---―下一步‖,勾选―在搜索中包括这个位置‖,在下拉开列表框中填写要使用的声卡驱动文件夹的路径(E:…………---―下一步‖,系统即自动搜索并安装你指定位置中的声卡驱动程序。 安装完声卡驱动后,如果仍然没有声音,将声卡换一个插槽试试。此外还可以进我的电脑的硬件设备管理器–右击声卡—属性--资源—看有没有冲突,有进BIOS通过设置解决。 上述方法,相信对一个对驱动安装不大熟悉的朋友来说,也基本能解决声卡驱动问题了。

数据结构实验总结报告

数据结构实验总结报告 李博杰PB10000603 一、调试过程中遇到哪些问题? (1)在二叉树的调试中,从广义表生成二叉树的模块花了较多时间调试。 由于一开始设计的广义表的字符串表示没有思考清晰,处理只有一个孩子的节点时发生了混乱。调试之初不以为是设计的问题,从而在代码上花了不少时间调试。 目前的设计是: Tree = Identifier(Node,Node) Node = Identifier | () | Tree Identifier = ASCII Character 例子:a(b((),f),c(d,e)) 这样便消除了歧义,保证只有一个孩子的节点和叶节点的处理中不存在问题。 (2)Huffman树的调试花了较长时间。Huffman编码本身并不难处理,麻烦的是输入输出。 ①Huffman编码后的文件是按位存储的,因此需要位运算。 ②文件结尾要刷新缓冲区,这里容易引发边界错误。 在实际编程时,首先编写了屏幕输入输出(用0、1表示二进制位)的版本,然后再加入二进制文件的读写模块。主要调试时间在后者。 二、要让演示版压缩程序具有实用性,哪些地方有待改进? (1)压缩文件的最后一字节问题。 压缩文件的最后一字节不一定对齐到字节边界,因此可能有几个多余的0,而这些多余的0可能恰好构成一个Huffman编码。解码程序无法获知这个编码是否属于源文件的一部分。因此有的文件解压后末尾可能出现一个多余的字节。 解决方案: ①在压缩文件头部写入源文件的总长度(字节数)。需要四个字节来存储这个信息(假定文件长度不超过4GB)。 ②增加第257个字符(在一个字节的0~255之外)用于EOF。对于较长的文件,会造成较大的损耗。 ③在压缩文件头写入源文件的总长度%256的值,需要一个字节。由于最后一个字节存在或不存在会影响文件总长%256的值,因此可以根据这个值判断整个压缩文件的最后一字节末尾的0是否在源文件中存在。 (2)压缩程序的效率问题。 在编写压缩解压程序时 ①编写了屏幕输入输出的版本 ②将输入输出语句用位运算封装成一次一个字节的文件输入输出版本 ③为提高输入输出效率,减少系统调用次数,增加了8KB的输入输出缓存窗口 这样一来,每写一位二进制位,就要在内部进行两次函数调用。如果将这些代码合并起来,再针对位运算进行一些优化,显然不利于代码的可读性,但对程序的执行速度将有一定提高。

yaffs2文件系统制作

交叉编译器ARM-Linux-gcc4.1.2 开发板TX2440A Busybox-1.15.1.tar.bz2(在Linux中被称为瑞士军刀) mkyaffs2image工具 首先创建一个名字为root_2.6.31的文件夹,在其中创建如下文件夹 etc bin var dev home lib mnt proc root sbin sys tmp usr opt共14个文件夹 解压Busybox tar xjvf busybox 进入源目录,修改Makefile 第164行,CROSS_COMPILE=arm-linux- 第190行,ARCH=arm 执行#make men onfig进行配置 配置选项大部分都是保持默认的,只需要注意选择以下这几个选项,其他的选项都不用动:Busybox Setting---> Build Options---> [*]Build Busybox as a static binary(no shared libs) [*]Build with Large File Support(for accessing files>2GB) Installation Options--->

(./_install)Busybox installation prefix 进入这个选项,输入busybox的安装路径,如:../rootfs Busybox Library Tuning---> [*]vi-style line editing commands [*]Fancy shell prompts 要选择这个选项:“Fancy shell prompts”,否则挂载文件系统后,无法正常显示命令提示符:“[\u@\h\W]#” 配置完成以后 执行#make #make install 然后就会在上一级目录下生成rootfs文件夹,里面包含几个文件夹/bin/sbin/usr linuxrc 把这些文件全部复制到刚建好的root_2.6.31目录下, #cp–rf*../root_2.6.31 在dev目录下,创建两个设备节点: #mknod console c51 #mknod null c13 然后进入自己建立的etc目录 拷贝Busybox-1.15.2/examples/bootfloopy/etc/*到当前目录下。 #cp-r../../busybox-1.15.2/examples/bootfloopy/etc/*./ 包括文件:fstab init.d inittab profile

主厂房结构优化专题分析

编号:FA008CT-A-05 新都华润雪花啤酒分布式能源站工程 勘察设计投标文件 招标编号:XD2T201401 第二卷技术部分 第二册专题报告 主厂房结构优化专题报告 中国华电工程(集团)有限公司 二○一四年二月北京

总目次 第一卷商务部分 第二卷技术部分 第一册工程技术方案说明 第二册专题报告 第三册投标人需提交的其他文件和资料第三卷投标报价书

目次 1 前言........................................................................... 错误!未定义书签。 2 厂区工程地质条件.................................................... 错误!未定义书签。 2.1地形地貌.................................................................. 错误!未定义书签。 2.2工程地质条件.......................................................... 错误!未定义书签。 2.3水文地质条件.......................................................... 错误!未定义书签。 2.4场地类别、建筑场地类型...................................... 错误!未定义书签。 2.5地震参数.................................................................. 错误!未定义书签。 2.6地震液化情况.......................................................... 错误!未定义书签。 2.7场地稳定性评价...................................................... 错误!未定义书签。 2.8场地地基土的适宜性.............................................. 错误!未定义书签。 3 地基方案选择和评价................................................ 错误!未定义书签。 3.1地基土工程特性 .................................................... 错误!未定义书签。 3.2天然地基持力层的选择.......................................... 错误!未定义书签。 3.3基础型式的选择 .................................................... 错误!未定义书签。 3.4地基沉降 ................................................................ 错误!未定义书签。 4 其他建(构)筑物地基基础 .................................... 错误!未定义书签。 5 结论........................................................................... 错误!未定义书签。 6 存在问题及建议 ....................................................... 错误!未定义书签。

党支部党员队伍思想分析报告

要扎实抓好党员队伍建设这一基础工程,需要长期坚持不懈地提高党员素质。在新的发展时期,深化质监队伍党员教育管理工作,增强干部职工队伍学习实践创新能力,提高综合素质,是做好质监工作的根本。我们对支部内党员思想状况进行了调查研究,基本了解了支部内党员队伍思想现状,找准了需要解决的突出问题,并就存在的问题提出了对策和建议。现结合质监工作实践对加强党员教育工作汇报如下: 一、党员队伍基本情况 XX支部党员共计xx人。青年党员、大专以上文化程度的党员是我支部党员队伍的主体。 二、党员队伍中存在的主要问题及原因分析 总的来说,我支部能够带领支部党员正常开展组织活动,发挥支部的战斗堡垒作用;党员能在各自岗位上较好地发挥党员的先锋模范作用,体现党员的先进性。但从调查情况看,我支部组织建设和党员队伍建设上还存在一些问题,主要体现在: 1、党支部创造力、凝聚力和战斗力还不强。一是由于支部队伍年轻化,对党务知识和党组织建设等方面不够熟悉;二是党支部活动开展较少,主要是因为质监工作十分繁忙,没有太多的精力和时间来开展活动;三是支部工作开拓进取意识不强,一些工作流于形式,从而削弱了支部的创造力、凝聚力和战斗力。 2、学习氛围不够浓厚,党员教育形式单调。有些党员对政治、业

务学习不够认真,不够深入,存在粗枝大叶的现象。“三会一课”也只是单纯的组织党员读读报纸、学学文件,除此外很少组织党员开展一些丰富多彩的活动,激发不了党员学习理论的热情,产生了对是否参加组织生活无所谓的态度,影响了组织生活正常开展。 3、党员先进性认识不足。少数党员意识淡薄,责任感、使命感不强,把自已等同于一般群众,自律意识不强,缺乏发挥作用的勇气和动力,思想认识水平有待于进一步提高。有些党员没有认清当前竞争日益激烈、不进则退的形势,认为自己的工作比较稳定,缺乏竞争意识和责任感,没有了进取心,放松了对世界观、人生观、价值观的改造和党性煅炼。 三、解决问题的措施与方法 1、注重学习教育,努力提高思想政治素质。通过各种方式开展对党员党的十七大四中全会精神、科学发展观、党的先进性建设理论和党风廉政建设理论等内容的思想政治学习,对党员重点加强理想信念教育、廉政教育、公仆意识教育,全面提升其综合素质。 2、注重心理健康,努力做好思想教育引导。结合改革发展形势,进一步教育、引导党员干部以健康向上的思想增强归属感。 3、注重典型引路,努力通过党员队伍建设带动员工队伍建设。坚持以正面教育、自我教育为主,调动党员和员工的主观能动性,树立职工的价值意识,不断完善提高自己提高职工业务水平和自身素养。 4、注重活动的开展,提高党员队伍的凝聚力。党小组的战斗堡垒作用和党员的先锋模范作用,主要体现在现实活动中。既要围绕质监

2020健身行业现状及前景趋势

2020年健身行业现状及 前景趋势 2020年

目录 1.健身行业现状 (4) 1.1健身行业定义及产业链分析 (4) 1.2健身市场规模分析 (5) 1.3健身市场运营情况分析 (6) 2.健身行业存在的问题 (9) 2.1缺乏市场和行业标准、运作规范和职业资质准入 (9) 2.2专业化程度低 (9) 2.3市场短期和投机行为普遍 (9) 2.4管理水平较低 (9) 2.5供应链整合度低 (10) 3.健身行业前景趋势 (10) 3.1中国运动健身行业迎来新突破 (10) 3.2需求释放,健身群体规模整体保持增长,健身文化逐渐成为主流11 3.3互联网入局,突破时间、空间限制,带来全新健身体验 (11) 3.4健身行业经历洗牌阶段,建立新格局 (11) 3.5行业协同整合成为趋势 (11) 3.6生态化建设进一步开放 (12) 3.7细分化产品将会最具优势 (12) 3.8需求开拓 (13) 4.健身行业政策环境分析 (13)

4.1健身行业政策环境分析 (13) 4.2健身行业经济环境分析 (14) 4.3健身行业社会环境分析 (14) 4.4健身行业技术环境分析 (14) 5.健身行业竞争分析 (16) 5.1健身行业竞争分析 (16) 5.1.1对上游议价能力分析 (16) 5.1.2对下游议价能力分析 (16) 5.1.3潜在进入者分析 (17) 5.1.4替代品或替代服务分析 (17) 5.2中国健身行业品牌竞争格局分析 (17) 5.3中国健身行业竞争强度分析 (18) 6.健身产业投资分析 (18) 6.1中国健身技术投资趋势分析 (19) 6.2中国健身行业投资风险 (19) 6.3中国健身行业投资收益 (20)

linux-2.6.18移植

Linux-2.6.18移植 有了我们的交叉编译环境和我们先前学的内核基础知识,下面我们就开始我们的内核移植了,我们所用的是博创的 S3C2410 。 关于 linux-2.6.18.tar.bz2 的下载网站先前我们说过,我们要先到该官方网站上去下载一个全新的内核。 [root@Binnary ~ ]# tar –jxvf linux-2.6.18.tar.bz2 [root@Binnary ~ ]# make mrproper 如果你是新下载的内核,那这一步就不用了。但如果你用的是别人移植好的内核,那最好在编译内核之前先清除一下中间文件,因为你们用来编译内核的交叉编译工具可能不同。 第一步:修改Makefile文件 将 改为 第二步:修改分区设置信息 我们要先在BootLoader中查看相应的分区信息 vivi>help 然后修改内核源码中的分区信息。分区信息文件在 a rch/arm/mach-s3c2410/common-smdk.c 将其中的

改为如下内容:

第三步:内核通过 BootLoader把数据写入NAND Flash,而vivi的ECC效验算法和内核的不同,内核的效验码是由NAND Flash控制器产生的,所以在此必须禁用NAND Flash ECC。所以我们就要修改 drivers/mtd/nand/s3c2410.c 这个文件。将 中的 chip->ecc.mode = NAND_ECC_SOFT ,改为如下 chip->ecc.mode = NAND_ECC_NONE。

只此一处。 第四步:下面是devfs的问题,因为2.6.12内核以后取消了devfs的配置选项,缺少了它内核会找不到mtdblock设备。所以我们需要修改 fs/Kconfig 文件,或者是从2.6.12的fs/Kconfig中拷贝下面几项到2.6.18的fs/Kconfig中去,我们采用修改的方法来完成。 修改 fs/Kconfig支持devfs 。 在Pseudo filesystems 主菜单的最后添加我们所要的内容。 第五步:文件系统的支持 Yaffs 文件系统 YAFFS文件系统简介 YAFFS,Yet Another Flash File System,是一种类似于JFFS/JFFS2的专门为Flash设计 的嵌入式文件系统。与JFFS相比,它减少了一些功能,因此速度更快、占用内存更少。 YAFFS和JFFS都提供了写均衡,垃圾收集等底层操作。它们的不同之处在于: (1)、JFFS是一种日志文件系统,通过日志机制保证文件系统的稳定性。YAFFS仅仅 借鉴了日志系统的思想,不提供日志机能,所以稳定性不如JAFFS,但是资源占用少。 (2)、JFFS中使用多级链表管理需要回收的脏块,并且使用系统生成伪随机变量决定 要回收的块,通过这种方法能提供较好的写均衡,在YAFFS中是从头到尾对块搜索, 所以在垃圾收集上JFFS的速度慢,但是能延长NAND的寿命。 (3)、JFFS支持文件压缩,适合存储容量较小的系统;YAFFS不支持压缩,更适合存 储容量大的系统。 YAFFS还带有NAND芯片驱动,并为嵌入式系统提供了直接访问文件系统的API,用 户可以不使用Linux中的MTD和VFS,直接对文件进行操作。NAND Flash大多采用 MTD+YAFFS的模式。MTD( Memory Technology Devices,内存技术设备)是对Flash 操作的接口,提供了一系列的标准函数,将硬件驱动设计和系统程序设计分开。 Yaffs 文件系统内核没有集成,可以对其主页下载: https://www.doczj.com/doc/de360724.html,/cgi-bin/viewcvs.cgi/#dirlist

党员队伍状况分析_1

竭诚为您提供优质的服务,优质的文档,谢谢阅读/双击去除 党员队伍状况分析 高山镇党员队伍状况综合分析报告 根据市委组织部[20XX]29号《关于进一步保持共产党员先进性教育活动准备工作通知》精神,我镇于20XX年8月19日在四楼会议室召开了党员队伍状况专题研究会、对全镇党员队伍情况进行了调研,现将调研的情况报告如下: 一、党员基本情况。 我镇共有47个支部,党员总数1309人,其中,女114人;预备党员49人。35岁以下276人,60岁以上466人;1992年10月以前入党834人,92年以后入党475人;大专以上114人,高中288人,初中及以下907人;非公有制企业30人,在岗职工305人,农村生产一线有916人,离、退休(退职)人员40人。生活困难党员40人;入党积极分子160人。 二、党建工作的主要作法。 1、认真学习,坚定信念,不断加强思想建设。

(1)坚持政治学习制度,思想上与时俱进、吐故纳新。坚持每季度2个小时组织党员政治学习,保证时间,保证人数,保证学习效果,定期召开研讨学习体会经验交流会。本年度先后学习了十六大文献,新《党章》,国际国内重大时事,近期重点学习党的十六届四中全会精神。集中学习6次,统一布置内容自学10次,召开研讨交流会3次,镇党政领导下基层党建调研3次。 (2)坚持“三会一课”制度,坚定党员的共产主义信念。每个月召开一次党小组生活会,每个月召开一次党支部会议,每季度召开一次支部党员大会,交流思想,开展批评与自我批评,总结工作。 (3)“七·一”组织新党员开展了入党宣誓,并开展优秀党务工作者、优秀共产党员评选活动。 2、培养后备力量,不断加强组织建设。 (1)建立稳定的入党积极分子队伍。我镇入党积极分子队伍稳定在160人,每季度召开一次入党积极分子会议,组织他们学习党章,加强对党组织的了解,端正入党动机,明确奋斗目标,并安排专人培养,定期谈话,指导写思想汇报,按时认真填写入党积极分子考核表,接受党的教育。 (2)按期缴纳党费,增强党员组织观念。每半年都能按政策,按期足额上交党费,从而使每个党员都能意识到我是一名党员,生活、工作在党组织中,我的行动要为党组织争光添彩。 3、维护党的形象,不断加强作风建设。我镇党委重温毛泽东同志“两个务必”的教导,以“党兴我兴,党衰我亡”为己任,党委成员以

中国健身行业的现状以及新发展

中国健身行业的现状以及新发展 健身俱乐部落户海内不外短短几年,却发展得异常红火。 作为该行业核心支柱的健身教练在公家心目中究竟印象如何呢?近日,中国青年报社调查中央、智联招聘和新浪招聘联合进行的一项职业吸引力调查发现,30%的公家觉得“现在做健身教练这行的鱼龙混杂,高素质健身教练却未几”。调查中,28%的公家以为“随着健身热兴起,教练市场肯定需求火爆”。 据08年8月,劳动和社会保障部宣布的“北京市二季度职业排行榜”显示,健身、娱乐场所服务职员作为“新生气力”首次入榜,跻身北京市二季度最轻易就业的20个职业。 现在的健身教练培训机构如雨后春笋般的涌入健身事业大潮,培训项目也五花八门。由此可见健身行业的发展正以惊人的速度从我们身边崛起。而现如今我们需要的是具备健身教练专业培训体系和专业培训技能的培训机构。目的清楚,落到实处——“信誉是教育的本质,质量是教育的核心。”集团操课类着名的培训机构主要集中在北京、武汉、上海等几个城市。而从健身教练的收入水平上来看,排在前面的是深圳、广东、北京、上海等大中型的城市,在这几个城市从业的教练月薪过万是很正常的事情。所以,根据自己的需求,找对地方,才是成为专业操课教练的条件。 健身教练行业目前存在的问题: 1.公家以为健身教练是吃青春饭的 a)很多人以为教练职业是个青春饭,这种认识是不准确 的。能把动作做得好看、有力度好像是教练能立足于领操台

的基本条件,但跟着会员对健身熟悉的不断深化,教练的专业知识是否过硬会成为更重要的评判尺度。此外,经验和服务意识也是赢得顾客的枢纽。国外也有岁数很大的人仍旧在做健身教练。现在从事教练这个职业的人大多是年青人,但是跟着健身行业的发展,以后很可能会泛起四五十岁的资深教练,他们不仅具有很高的理论知识,同时还能够在一线对会员健身做出很全面正确的指导。 b)健身教练的基本素质:1丰硕的理论知识;2亲身的健 身体会;3为人师表的立场。三者缺一不可,而理论知识和健身体会若非长时间参与是很难获得的,为人师表的立场则是一个成功运动员转型做教练的意识形态,很多优秀运动员退役后做不了教练就是因为他平时不留意观察和总结的结果,很多优秀运动员也从来没想过转型做教练。所以可以看出:长时间的积累是一个真正优秀教练的铺路石。 2.健身教练三大来源 a)记者在采访中了解到,目前健身教练的来源主要有三部分组成,或者是健身俱乐部会员,由于成绩凸起,被升格为教练;或者是相关体育专业毕业生毕业后直接进入健身俱乐部;再有就是通过参加培训班,考到有关健身教练资格。 b)据了解,教练中的相当一部门是兼职。科班出身的有扎实的理论功底,但往往会显得缺少个性,而培训班出身的健身教练可能由于培训班的良莠不齐以及缺少同一的尺度而导致水准得不到保障。 c)某健身会所的工作职员说:“我们聘用的教练是需要证书的,什么证书无所谓,口试合格的就可以录用任教。”

电脑有声卡但没有声音

电脑有声卡但没有声音,请按下面的方法操作: 1、检查主机与音箱的连线有没有松动或断线,音箱电源有没有打开,音箱的音量大小旋钮有没有关到最小。 2、对于独立声卡,检查声卡与主板插槽接触是否良好,可重新拔插一次声卡。对于主板集成的声卡,检查在BIOS中是否禁用了。解决方法:启动电脑时进入BIOS 设置(一般按住Del键),展开“Integrated Peripherals(集成外围设备设置)”,在出现的窗口中找到声卡项(一般名称为AC97 Audio),将其设置为"Auto"或“Enabled",找到On Board AC97 Control,将其设置为“Enabled",然后存储退出,进入系统后在安装声卡的驱动程序。 3、打开“设备管理器”检查声卡安装驱动程序有没有问题。解决方法:在桌面上右击"我的电脑"→选择"属性"→弹出"系统属性"窗口→选择“硬件”页面→按“设备管理器(D)”按钮→弹出“设备管理器”窗口→检查"声音、视频和游戏控制器"或“多媒体音频控制器”前有没有“!”或“?”,如有说明声卡驱动程序损坏,请找到声卡的驱动盘重新安装驱动程序(如果声卡是主板集成的,那么驱动程序在主板的驱动光盘中)即可。声卡驱动程序正确安装后如果还是没有声音,检查下面两个方面: 1、在“设备管理器”里面禁用了声卡。解决方法:进入“设备管理器”,展开"声音、视频和游戏控制器"分支,找到声卡项(如果被禁用了,其前面的小喇叭上有一个“X”)并选中,然后按工具栏的“启用”按钮即可。 2、在声音属性里关闭了音量。解决方法:进入“控制面板”,双击“声音和音频设备”项,弹出“声音和音频设备属性”窗口,选择“音量”页面,把音量调节滑块调到合适的位置,并在“将音量调节图标放入任务栏(I)”前打上钩,确定并退出即可。 3,查看系统默认播放器的声音是否被你调到最低,默认播放器的声音设置可以控制整个系统声音如果以上都没有问题的话,你试试双击任务栏的那个声音图标,看看波形音响是不是0,如果是0的话,调一下就OK了。

数据结构实验报告及心得体会

2011~2012第一学期数据结构实验报告 班级:信管一班 学号:201051018 姓名:史孟晨

实验报告题目及要求 一、实验题目 设某班级有M(6)名学生,本学期共开设N(3)门课程,要求实现并修改如下程序(算法)。 1. 输入学生的学号、姓名和 N 门课程的成绩(输入提示和输出显示使用汉字系统), 输出实验结果。(15分) 2. 计算每个学生本学期 N 门课程的总分,输出总分和N门课程成绩排在前 3 名学 生的学号、姓名和成绩。 3. 按学生总分和 N 门课程成绩关键字升序排列名次,总分相同者同名次。 二、实验要求 1.修改算法。将奇偶排序算法升序改为降序。(15分) 2.用选择排序、冒泡排序、插入排序分别替换奇偶排序算法,并将升序算法修改为降序算法;。(45分)) 3.编译、链接以上算法,按要求写出实验报告(25)。 4. 修改后算法的所有语句必须加下划线,没做修改语句保持按原样不动。 5.用A4纸打印输出实验报告。 三、实验报告说明 实验数据可自定义,每种排序算法数据要求均不重复。 (1) 实验题目:《N门课程学生成绩名次排序算法实现》; (2) 实验目的:掌握各种排序算法的基本思想、实验方法和验证算法的准确性; (3) 实验要求:对算法进行上机编译、链接、运行; (4) 实验环境(Windows XP-sp3,Visual c++); (5) 实验算法(给出四种排序算法修改后的全部清单); (6) 实验结果(四种排序算法模拟运行后的实验结果); (7) 实验体会(文字说明本实验成功或不足之处)。

三、实验源程序(算法) Score.c #include "stdio.h" #include "string.h" #define M 6 #define N 3 struct student { char name[10]; int number; int score[N+1]; /*score[N]为总分,score[0]-score[2]为学科成绩*/ }stu[M]; void changesort(struct student a[],int n,int j) {int flag=1,i; struct student temp; while(flag) { flag=0; for(i=1;ia[i+1].score[j]) { temp=a[i]; a[i]=a[i+1]; a[i+1]=temp; flag=1; } for(i=0;ia[i+1].score[j]) { temp=a[i]; a[i]=a[i+1]; a[i+1]=temp; flag=1;

相关主题
文本预览
相关文档 最新文档