I have a program in AVR Studio V4 with the following code:
#include <avr/pgmspace.h>
void nlcd_Putc(unsigned char c)
{
unsigned char i;
if (c>127) c=c-64;
for (i = 0; i < 5; i++ )
{
nlcd_SendByte(DATA_LCD_MODE,pgm_read_byte(&(nlcd_Font[c-32][i])));
}
nlcd_SendByte(DATA_LCD_MODE,0x00);
}
So when i want to run this code in MiKroC for AVR i get the following error:
128 324 Undeclared identifier 'pgm_read_byte' in expression MyProject.c
Should I add the header avr/pgmspace.h To MiKroc For AVR, or what is the equivalent header to avr/pgmspace.h in Mikroc For AVR?
Thanks a lot.
by addinf this codes to header :
typedef signed char int8;
typedef unsigned char uint8;
typedef signed int int16;
typedef unsigned int uint16;
typedef signed long int int32;
typedef unsigned long int uint32;
//-----------------------
#define PGM_P char flash *
#define PROGMEM flash
#define const flash
#define PSTR(x) x
#define EEMEM eeprom
#define pgm_read_byte(x) (*((uint8 flash *)(x)))
#define pgm_read_word(x) (*((uint16 flash *)(x)))
#define pgm_read_float(x) (*((uint32 flash *)(x)))
#define pgm_read_byte_near(x) (*((uint8 flash *)(x)))
Related
I'm completely new to netlink & co. and I am trying to establisch a connection from user space to the w1-kernel module of a raspberry pi.
Unfortunately the documentation i found is spotty and contradictory.
Here some of the things not clear to me:
basic communication is:
generate a socket: socket()
int s = socket(AF_NETLINK,SOCK_DGRAM, NETLINK_CONNECTOR);
bind it to a local name: bind()
int b = bind(s,(sockaddr*)&sa,sizeof(sa));
with
sa.nl_family=AF_NETLINK;
sa.nl_pid=getpid();//0?
sa.nl_groups=0; //23? -1?
create the message
send it: send()? sendmsg()?
wait for answer: poll()
read answer: recv()
+In examples i found (w1d.c and ucon.c) they use the send() command (not sendmsg) without a connect(), even though the man pages of send say that wouldnt work.
+I am not clear about the structure of the message:
send can send any buffer (char*)
netlink expects a struct nlmsghdr header;
connector expects a struct cn_msg header.
w1_netlink expects a w1_netlink_msg header and w1_netlink_cmd data.
Do i need all headers in a row? Ther are 2 sequence / message number variables, one in nlmsghdr and on in cn_msg???
The test program i wrote is not producing the result i expect: every thing works withour producing an error but i am getting no answer :-(
#include <iostream>
#include <linux/netlink.h>
#include <sys/types.h>
#include <sys/socket.h>
#include<sys/poll.h>
#include <unistd.h>
#include<cstring>
#include "w1_netlink.h"
__u32 nl_seq;
static int netlink_send(int s, struct cn_msg *msg) //copy from (ucon.c)
{
struct nlmsghdr *nlh;
unsigned int size;
int err;
char buf[128];
struct cn_msg *m;
size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);
nlh = (struct nlmsghdr *)buf;
nlh->nlmsg_seq = nl_seq++;
nlh->nlmsg_pid = getpid();
nlh->nlmsg_type = NLMSG_DONE;
nlh->nlmsg_len = size;
nlh->nlmsg_flags = 0;
m = (cn_msg*) NLMSG_DATA(nlh);
memcpy(m, msg, sizeof(*m) + msg->len);
err = send(s, nlh, size, 0);
return err;
}
int main(int argc, char *argv[])
{
nl_seq=0;
int s = socket(AF_NETLINK,SOCK_DGRAM, NETLINK_CONNECTOR);
if(s==-1) {std::cout<<"no socket"; return s;};
std::cout<<"socket "<<s;
sockaddr_nl sa;
sa.nl_family=AF_NETLINK;
sa.nl_pid=0;//getpid();
sa.nl_groups=0;
int b = bind(s,(sockaddr*)&sa,sizeof(sa));
if(b==-1){std::cout<<"bind error";return b;}; //prints 3
std::cout<<"bind "<<b; //prints 0
int si=sizeof(struct cn_msg)+sizeof(struct w1_netlink_msg)+sizeof(w1_netlink_cmd);
char * buf;
buf=(char *)malloc(1024);
memset(buf,0,1024);
cn_msg *cnh = (cn_msg*)buf;
w1_netlink_msg* wnh=(w1_netlink_msg*)&cnh->data;
w1_netlink_cmd* wcmd = (w1_netlink_cmd*)&wnh->data;
cnh->id.idx=CN_W1_IDX;
cnh->id.val=CN_W1_VAL;
cnh->seq=nl_seq;
cnh->flags=0;
wnh->type=W1_LIST_MASTERS;
wnh->len=0;
cnh->len=sizeof(struct w1_netlink_msg)+sizeof(w1_netlink_cmd);
int len=netlink_send(s,cnh);
std::cout<<"send "<<len<<" "<<(int)wnh->status; //prints 52 0
pollfd pfd;
pfd.fd=s;
pfd.events=POLLIN;
pfd.revents=0;
int p=0;
while(p<1) {
p=poll(&pfd,1,1000);
std::cout<<"poll "<<p<<pfd.revents; //prints 0 0 in infinite loop
std::cout.flush();
};
memset(wcmd,0,128);
len=recv(s,buf,255,0);
std::cout<<"recv "<<len;
close(s);
return 0;
}
Result is socket 3 bind 0 send 52 0 poll 00 poll 00 ...
Thanks
trying to figure out the linux capabilities interface, i came across with an unexpected issue (for me at least). When seting the capabilities of a process with the capset syscall the kernel rejects a change of userid with the setuid syscall. Does anybody know why setuid fails?
This is code i wrote to test this behavior:
#undef _POSIX_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/capability.h>
#include <sys/capability.h>
#include <string.h>
int main(int argc, char** argv){
struct __user_cap_header_struct cap_header;
struct __user_cap_data_struct cap_data;
int cap_res;
FILE *file;
int sockfd;
cap_header.pid = getpid();
cap_header.version = _LINUX_CAPABILITY_VERSION_1;
__u32 cap_mask = 0;
cap_mask |= (1 << CAP_DAC_OVERRIDE);
cap_mask |= (1 << CAP_SETUID);
printf("You selected mask: %x\n", cap_mask);
cap_data.effective = cap_mask;
cap_data.permitted = cap_mask;
cap_data.inheritable = cap_mask;
cap_res = capset(&cap_header, &cap_data);
if(cap_res < 0){
printf("Trying to apply mask: FAIL\n", cap_mask);
} else {
printf("Capability set correctly\n");
}
int uid = atol(argv[1]);
int setuid_res = setuid(uid);
if (setuid_res == -1){
printf("7w7\n");
} else {
printf("UID set correctly\n");
}
}
compiled with:
$ gcc -g test1.c -o test1
Output is (for user id: 1000)
$ # ./test1 1000
You selected mask: 2
Capability set correctly
7w7
I think you might be missing a couple of steps in your question:
How do you give the binary some privilege?
It looks like you are trying to use cap_dac_override to achieve what cap_setuid is intended for.
Rewriting the program as follows:
#undef _POSIX_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/capability.h>
#include <sys/capability.h>
#include <string.h>
int main(int argc, char** argv){
struct __user_cap_header_struct cap_header;
struct __user_cap_data_struct cap_data;
int cap_res;
// need to start from known data. C does not guarantee these are
// zero filled by default. You could declare them static to get
// that.
memset(&cap_header, 0, sizeof(cap_header));
memset(&cap_data, 0, sizeof(cap_data));
cap_header.pid = getpid();
cap_header.version = _LINUX_CAPABILITY_VERSION_1;
__u32 cap_mask = 0;
cap_mask |= (1 << CAP_SETUID);
printf("You selected mask: %x\n", cap_mask);
cap_data.effective = cap_mask;
cap_data.permitted = cap_mask;
// not needed: cap_data.inheritable = cap_mask;
cap_res = capset(&cap_header, &cap_data);
if(cap_res < 0){
printf("Trying to apply mask: FAIL\n", cap_mask);
exit(1);
} else {
printf("Capability set correctly\n");
}
if (argc != 2) {
printf("usage: %s <uid>\n", argv[0]);
exit(1);
}
int uid = atol(argv[1]);
int setuid_res = setuid(uid);
if (setuid_res == -1){
printf("7w7\n");
} else {
printf("UID set correctly to %d\n", uid);
}
}
You can run the program like this:
$ sudo ./test1 1000
You selected mask: 80
Capability set correctly
UID set correctly to 1000
Or, using a file capability:
$ sudo setcap cap_setuid=p ./test1
$ ./test1 1000
You selected mask: 80
Capability set correctly
UID set correctly to 1000
This will work if you want to use the first 32 capabilities. However, there are ~40 of them under Linux at present, so I'd suggest you look into using the libcap API instead which figures out all of the kernel ABI details for you.
I am sending AT command to get IMEI no.
char CGSN[] = "AT+CGSN\r\n";
// in while loop
HAL_UART_Transmit(&huart2,(uint8_t *)CGSN, sizeof(CGSN),100);
HAL_Delay(1000);
HAL_UART_Receive_IT(&huart2,(uint8_t *)&ch,1);
// Callback
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART2){
if(buf[i]!=13){
buf[i]=ch;
i++;
}
}
HAL_UART_Receive_IT(&huart2,(uint8_t *)&ch,1);
buf[i]=0;
}
the response stored in buffer is - \r\n9876543212345\r\n\r\nOK\r\n
What is best way to receive response and filter out n"9876543212345" & "OK" and store separately in a array to further process
Thanks
You can use sscanf for this purpose. Below is the quick implementation of the scenario in C.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(void) {
unsigned long a;
char array[10];
char string[] = "\r\n9876543212345\r\n\r\nOK\r\n";
sscanf(string , "\r\n%ld\r\n\r\n%s\r\n", &a, array);
printf("%ld %s\n", a, array);
return 0;
}
Problem is simple! Your buf[] dont include '\r' (in decimal 13).
Correct value buf[] is "AT+CGSN\n9876543212345\n\nOK\n\0".
Trying to use perl API functions in C program. Couldn't find the function to do regular expression match. Wish there is a function like regexmatch in the following program.
#include <EXTERN.h> /* from the Perl distribution */
#include <perl.h> /* from the Perl distribution */
#include <sys/time.h>
typedef unsigned long ulong;
static PerlInterpreter *my_perl; /*** The Perl interpreter ***/
int main(int argc, char **argv, char **env) {
int numOfArgs = 0;
PERL_SYS_INIT3(&numOfArgs, NULL, NULL);
my_perl = perl_alloc();
perl_construct(my_perl);
SV* str = newSVpv(argv[1], strlen(argv[1]));
if (regexmatch(str, "/hi (\S+)/")) {
printf("found a match\n");
}
return 0;
}
I know it's possible to use pcre library, just wonder if it's possible to get it from perl library here (libperl.so.5.14.2 on ubuntu 12.04)
Thanks!
UPDATE 1:
Did some google search and got the following simple program compiling. But when I ran the program as ./a.out ping pin, it gave "Segmentation fault" in the "pregcomp" function. Not sure why.
#include <EXTERN.h> /* from the Perl distribution */
#include <perl.h> /* from the Perl distribution */
#include <sys/time.h>
#include <embed.h>
typedef unsigned long ulong;
static PerlInterpreter *my_perl; /*** The Perl interpreter ***/
struct REGEXP * const engine;
int main(int argc, char **argv, char **env) {
int numOfArgs = 0;
PERL_SYS_INIT3(&numOfArgs, NULL, NULL);
my_perl = perl_alloc();
perl_construct(my_perl);
SV* reStr = newSVpv(argv[2], strlen(argv[2]));
printf("compiling regexp\n");
REGEXP * const compiled_regex = pregcomp(reStr, 0);
printf("execing regexp\n");
int len = strlen(argv[1]);
pregexec(compiled_regex, argv[1], argv[1] + len, argv[1], 5, NULL, 0);
return 0;
}
Don't mess with Perl's private internals. Call a Perl sub that uses the match operator.
Say you previously compiled the following in your interpreter (using eval_pv),
sub regex_match { $_[0] =~ $_[1] }
Then you can call
static bool regex_match_sv(SV* str, SV* re) {
dSP;
bool matched;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(str);
XPUSHs(re);
PUTBACK;
call_pv("regex_match", G_SCALAR);
SPAGAIN;
matched = SvTRUE(POPs);
PUTBACK;
FREETMPS;
LEAVE;
return matched;
}
i just started the project which requiers to connect ADXL345 to my Atmega16. I want to put device id on screen and read axis. So far i cant communicate with ADXL345. ON LCD only appears 0 I would be gratefull for any help.
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include "hd44780.h"
#define F_CPU 1000000UL
/*-----------------------Rejestry ADXL345---------------------*/
char POWER_CTL = 0x2D; //Power Control Register 0x08 measurement
char DATA_FORMAT = 0x31;
char BW_RATE = 0X2C;
char FIFO = 0x38; //fifo ctl
char DATAX0 = 0x32; //X-Axis Data 0
char DATAX1 = 0x33; //X-Axis Data 1
char DATAY0 = 0x34; //Y-Axis Data 0
char DATAY1 = 0x35; //Y-Axis Data 1
char DATAZ0 = 0x36; //Z-Axis Data 0
char DATAZ1 = 0x37; //Z-Axis Data 1
char DEVICEID = 0x00;
#define Read_Byte_SPI( addr ) ADXL_write( 0x80 | addr , 0xFF );
/*------------------PORTY SPI---------------*/
#define SPI_CS PB4
#define DDR_SPI DDRB
#define DD_MOSI PB5
#define DD_MIOS PB6
#define DD_SCK PB7
/*vcc<->vs*/
//--------------------------------------Funkcje-------------------
unsigned int init_port(void) //ports 4 lcd
{DDRD =0x00; PORTD =0x07 ; }
/*function 4 lcd*/
static void lcd( int a){ LCD_LOCATE(2,0); char buff[2]; char tab[2]; /*itoa(a,buff,10);*/ sprintf(a, %d", buff); lcd_puts(buff);
}
/**
* This writes to a register with the data passed to the address passed
* #param unsigned char cReg - the address of the register you wish to write to
* #param unsigned char cData - the data you wish to write to the register
*/
unsigned char ADXL_write(unsigned char cReg, unsigned char cData){
set_spics();
/* Start transmission send register */
SPDR = cReg;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)))
{ /* NOOP */ }
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)))
{ /* NOOP */ }
clear_spics();
return SPDR;
}
uint8_t ADXL_read(unsigned char addr) { // read ADXL345 - 128+ addrs, back 8 bits - found this in another topic
int8_t ans;
set_spics();
SPDR = 0x08 | addr;
loop_until_bit_is_set(SPSR, SPIF);
SPDR = 0xFF;
loop_until_bit_is_set(SPSR, SPIF);
ans = SPDR;
clear_spics();
return(ans);}
//inicjalizacjia SPI
void Init_SPI(){
// make the MOSI, SCK, and SS pins outputs
DDRB |= ( 1 << DD_MOSI ) | ( 1 << DD_SCK ) | ( 1 << SPI_CS );
DDRB &= ~( 1 << DD_MIOS );
/* Enable SPI, Master, set clock rate fck/128 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);
}
//Control SS=CHIP SELECT ADXL345
void clear_spics(){
PORTB |= _BV(SPI_CS); // high
_delay_ms(30);}
void set_spics(){
PORTB &=~ _BV(SPI_CS); // low
_delay_ms(30);}
void ADXL_init(void){
//init ADXL
ADXL_write(DATA_FORMAT,0x08); //pełna rozdzielczość DATASHEET STRONA 26 4SPI
ADXL_write(BW_RATE, 0x0A) ; //100hz
ADXL_write(POWER_CTL,0x08);
ADXL_write(FIFO, 0); //FIFO Wylacozny
}
/*------------------------główna petla---------------------------*/
int main(void)
{
/* tab for strings */
char str1[] = "Czujnik ADXL 345";
/* init lcd*/
lcd_init();
/* LCD UP */
LCD_DISPLAY(LCDDISPLAY);
LCD_CLEAR;
LCD_LOCATE(1,1);
lcd_puts(str1);
init_port();/*port init*/
Init_SPI();//SPIUP
_delay_ms(50);
ADXL_init(); //ADXL345 config
_delay_ms(50);
while(1)
{
int8_t k;
k=Read_Byte_SPI( DEVICEID );
lcd(k);
_delay_ms(5000);
k=ADXL_read(DATAX0);
lcd(k);
_delay_ms(5000);
}
`>