Configure samba server on Ubuntu

###Installation Update repository and install samba and samba services.

	$ sudo apt-get update
	$ sudo apt-get install samba smbfs

###Configuration Add a new samba user:

	Trusty@joggler:~$ sudo smbpasswd -a Trusty
	[sudo] password for Trusty: 
	New SMB password:
	Retype new SMB password:

Editing the /etc/samba/smb.conf:


	[samba]
	   comment = samba for ethernet users
	   path = /media/samba
	   valid users = Trusty
	   public = no
	   writable = yes
	   printable = no
	   create mask = 0765

	[homes]
	   comment = Home Directories
	   browseable = no

	security = user
	username map = /etc/samba/smbusers

Adding the mapping of the system user to samba user:

	Trusty@joggler:/media$ cat /etc/samba/smbusers 
	Trusty="Trusty"

Restarting the samba service and now you can login with your new username and password. ###Configure easy swat for samba, its description is listed as:
swat - Samba Web Administration Tool

	$ sudo apt-get install swat xinetd

edit the configuration files:

	Trusty@joggler:/etc/samba$ cat /etc/xinetd.d/swat 
	# description: SWAT is the Samba Web Admin Tool. Use swat \
	#              to configure your Samba server. To use SWAT, \
	#              connect to port 901 with your favorite web browser.
	service swat
	{
	        port    = 901
	        socket_type     = stream
	        wait    = no
	        user    = root
	        server  = /usr/sbin/swat
	        log_on_failure  += USERID
	        disable = no
	}

After restart xinetd, we can access http://YourIP:901 for configuration. ###Mount the samba partition We can add this line to the ~/.bashrc, then use mountsamba we could mount the samba disk to our own mounting point.

	alias mountsamba='sudo mount -t cifs //10.0.0.11/samba1/ -o user=Trusty,password=Trustywill,workgroup=WORKGROUP /media/samba'

On Windows it’s very convinient to mount the shared samba, but on Linux, only root could write to the samba disk , why?
###NFS Installation:

	$ sudo apt-get install nfs-kernel-server
	$ sudo apt-get install rpcbind

Configuration of the nfs server:

	Trusty@joggler:~$ cat /etc/exports 
	/home/Trusty 10.0.0.221(rw,sync,no_subtree_check) 10.0.0.11(rw,sync,no_subtree_check)
Restart the service of nfs:
	$ sudo service nfs-kernel-server restart
In client machine, Just add following lines to your /etc/fstab
	10.0.0.11:/home/Trusty   /media/nfs   nfs4   rsize=8192,wsize=8192,timeo=14,intr,_netdev	0 0

Restart and now in your own /media/nfs you will see the destination nfs directory.

GPIO Advanced in STM32

直接操作寄存器的好处,最主要的就是看中它的快。缺点在于比较晦涩,因为你需要了解到实现的底层。在官方库中,我们可以找到如下的定义:

//./Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/stm32f10x.h:
#define PERIPH_BASE           ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */
//./Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/stm32f10x.h:
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
//./Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/stm32f10x.h:
#define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)
//./Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/stm32f10x.h:
#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
// Definition of the GPIO Types
/** 
  * @brief General Purpose I/O
  */

typedef struct
{
  __IO uint32_t CRL;
  __IO uint32_t CRH;
  __IO uint32_t IDR;
  __IO uint32_t ODR;
  __IO uint32_t BSRR;
  __IO uint32_t BRR;
  __IO uint32_t LCKR;
} GPIO_TypeDef;

/**
 * IO definitions
 *
 * define access restrictions to peripheral registers
 */

#ifdef __cplusplus
  #define     __I     volatile                /*!< defines 'read only' permissions      */
#else
  #define     __I     volatile const          /*!< defines 'read only' permissions      */
#endif
#define     __O     volatile                  /*!< defines 'write only' permissions     */
#define     __IO    volatile                  /*!< defines 'read / write' permissions   */
;

从上面就可以基本看出GPIO的相关知识。在GPIO的使用中我们需要注意7个寄存器:
CRL, CRH, IDR, ODR, BSRR, BRR, LCKR.
使用起来很简单,直接调用相应的寄存器操作就好:
GPIOA->CRL=0x00;
寄存器的定义在手册中有详细的介绍。简单的说,CRL和CRH被称之为Configuration Register, 配置寄存器,而IDR和ODR则是数据寄存器,一个是INPUT一个是OUTPUT。 置位/复位寄存器BSRR,还有一个16位的复位寄存器BRR, 还有一个32位的锁定寄存器LCKR,设置好对应的寄存器则可执行相应的操作。

输入和输出操作可以直接操作寄存器,例如点亮和熄灭LED都是可以直接用操作寄存器来完成。而对键盘的操作,则是读入值。

	#define GET_LEFT()	(!(GPIOD->IDR&GPIO_Pin_3)) 

能使用库函数的场合,除非对IO要求非常高,否则不建议直接操作寄存器。因为出错误的概率会远远增大。

STM32 and 25F080

SST25F080,高达 1M 字节的串行 FLASH 存储器,此芯片为-50 版,即 SPI 速度可达到 50M,利用 STM32 的最高速 SPI 接口(36M),读写速度绝对不比并行 FLASH 慢.
连线图如下:

25f080.jpg

RTC on STM32

RTC(Real Time Clock) 在STM32中可以理解为内置的一个部件,和传说中的DS1302是有差别的。尽管官方发布的程序可以将RTC搞成一个万年历。
###配置RTC RTC需要顺带使用后备寄存器, 因为RTC是一个简单的秒中断定时器,关于年日月分秒的信息需要在掉电保存时依然放在某个地方,这个地方就是STM32的后备寄存器。配置好以后,尽管系统关电,依靠板子上的后备电池,依然可以保存32768的晶振和后备寄存器的数据。
配置RTC的方法:

	#include "stm32f10x_bkp.h"
	#include "stm32f10x_pwr.h"
	#include "stm32f10x_rtc.h"
	//使能一些外设
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
		PWR_BackupAccessCmd(ENABLE);

###判断RTC是否被配置过 下面的函数被用于判断RTC是否被配置过:

/**************************************************************
** 函数名:TestRtc
** 功能:测试RTC用
** 注意事项:用于显示RTC是否已经设置过.
***************************************************************/
void TestRtc(void)
{
	if(RTC_Blank)
	{
		USART1_Puts("The Time is not set\r\n");
	}
	else
	{
		USART1_Puts("Time Setted.\r\n");
	}
}

这个函数判断RTC_Blank全局变量的值,而全局变量的值则在配置RTC的时候被设定。

void RTC_Configuration(void)
{
  //......
	if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
		{
	//......
			RTC_Blank=1;	//这个标志代表RTC是没有预设的(或者说是没有上纽扣电池)
	
		}

如果RTC后备寄存器的值为设定为0xA5A5,则代表RTC已经被设置过。否则,我们认为它处于未被设置过的状态。
###使用RTC的秒中断 在NVIC中,需要有下列的定义,以标识RTC的秒中断。

	/* RTC */
	NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

对应的中断响应例程则定义在stm32f10x_it.c中:

/*******************************************************************************
* Function Name  : RTC_IRQHandler    RTC中断
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
extern volatile bool Sec;	//1S标志
void RTC_IRQHandler(void)
{
	if(RTC_GetITStatus(RTC_IT_SEC) != RESET) //RTC发生了秒中断(也有可能是溢出或者闹钟中断)
	{
		RTC_ClearITPendingBit(RTC_IT_SEC);
		Sec=TRUE;
		
		//以免RTC计数溢出,这里限制了RTC计数值的大小.0x0001517f实际就是一天的秒数
		if(RTC_GetCounter() >= 0x0001517f)	
		{
			RTC_SetCounter(0x0);
		}
	}
}

而在main.c中,则根据Sec的值来闪烁LED1灯。

	for(;;)
	{
		if(Sec == 1)
		{
			Sec = 0;
			GPIOA->ODR^=GPIO_Pin_8;
		}
	}

Test:

	for(;;)
	{
		if(Sec == 1)
		{
			Sec = 0;
			GPIOA->ODR^=GPIO_Pin_8;
		}
	}

STM32中的Systick

Cortx-M3特有的SysTick可以很方便的实现定时。系统始终的频率和开启系统时钟中断主要在RCC.c里进行设置:

	//SYSTICK分频--1ms的系统时钟中断
	if (SysTick_Config(SystemCoreClock / 1000))
  	{
  	  	/* Capture error */
    	while (1);
  	}
// The definition of the SysTick_Config:

/**
 * @brief  Initialize and start the SysTick counter and its interrupt.
 *
 * @param   ticks   number of ticks between two interrupts
 * @return  1 = failed, 0 = successful
 *
 * Initialise the system tick timer and its interrupt and start the
 * system tick timer / counter in free running mode to generate 
 * periodical interrupts.
 */

/*
  *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
  *                                  by the user application to setup the SysTick 
  *                                  timer or configure other parameters.
*/

  系统时钟SYSCLK,它是供STM32中绝大部分部件工作的时钟源。系统时钟可选择为PLL输出、HSI或者HSE。系统时钟最大频率为72MHz,它通过AHB分频器分频后送给各模块使用,AHB分频器可选择1、2、4、8、16、64、128、256、512分频。其中AHB分频器输出的时钟送给5大模块使用:
  ①、送给AHB总线、内核、内存和DMA使用的HCLK时钟。
  ②、通过8分频后送给Cortex的系统定时器时钟。
  ③、直接送给Cortex的空闲运行时钟FCLK。
  ④、送给APB1分频器。APB1分频器可选择1、2、4、8、16分频,其输出一路供APB1外设使用(PCLK1,最大频率36MHz),另一路送给定时器(Timer)2、3、4倍频器使用。该倍频器可选择1或者2倍频,时钟输出供定时器2、3、4使用。
  ⑤、送给APB2分频器。APB2分频器可选择1、2、4、8、16分频,其输出一路供APB2外设使用(PCLK2,最大频率72MHz),另一路送给定时器(Timer)1倍频器使用。该倍频器可选择1或者2倍频,时钟输出供定时器1使用。另外,APB2分频器还有一路输出供分频器使用,分频后送给ADC模块使用。ADC分频器可选择为2、4、6、8分频。
Cortex-M3允许为SysTick提供2个时钟源以供选择,第一个是内核的“自由运行时钟”FCLK,“自由”表现在它不是来自系统时钟HCLK,因此在系统时钟停止时,FCLK也能继续运行。第2个是一个外部的参考时钟,但是使用外部时钟时,因为它在内部是通过FCLK来采样的,因此其周期必须至少是FCLK的两倍(采样定理)。

/*******************************************************************************
* Function Name  : SysTickHandler
* Description    :系统时钟,一般调教到1MS中断一次
*******************************************************************************/

void SysTick_Handler(void)
{
	if(Timer1)
		Timer1--;
}

Timer1 为全局变量,我们将设置这个全局变量,以决定其定时期限。

/********************************************
**函数名:SysTickDelay
**功能:使用系统时钟的硬延迟
**注意事项:一般地,不要在中断中调用本函数,否则会存在重入问题.另外如果屏蔽了全局中断,则不要使用此函数
********************************************/
volatile u16 Timer1;
void SysTickDelay(u16 dly_ms)
{
	Timer1=dly_ms;
	while(Timer1);
}

而设置这个全局变量则是在main.c的loop函数中设置的。

	for(;;)
	{
		SysTickDelay(500);
		GPIOA->ODR^=GPIO_Pin_8;
	}

如果把500改成其它的值,则很方便可以实现不同大小的定时器。